diff --git a/Jenkinsfile b/Jenkinsfile index 49c5635774..5f960ab4b5 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -19,7 +19,7 @@ properties([[$class: 'jenkins.model.BuildDiscarderProperty', strategy: [$class: artifactNumToKeepStr: '20']]]) // see https://github.com/jenkins-infra/documentation/blob/master/ci.adoc for information on what node types are available -def buildTypes = ['Linux'] // TODO add 'Windows' +def buildTypes = ['Linux', 'Windows'] def builds = [:] for(i = 0; i < buildTypes.size(); i++) { diff --git a/core/src/main/java/hudson/scheduler/CronTab.java b/core/src/main/java/hudson/scheduler/CronTab.java index d289dc32ef..81fa5075c9 100644 --- a/core/src/main/java/hudson/scheduler/CronTab.java +++ b/core/src/main/java/hudson/scheduler/CronTab.java @@ -326,10 +326,19 @@ public final class CronTab { * See {@link #ceil(long)}. * * This method modifies the given calendar and returns the same object. + * + * @throws RareOrImpossibleDateException if the date isn't hit in the 2 years after it indicates an impossible + * (e.g. Jun 31) date, or at least a date too rare to be useful. This addresses JENKINS-41864 and was added in TODO */ public Calendar ceil(Calendar cal) { + Calendar twoYearsFuture = (Calendar) cal.clone(); + twoYearsFuture.add(Calendar.YEAR, 2); OUTER: while (true) { + if (cal.compareTo(twoYearsFuture) > 0) { + // we went too far into the future + throw new RareOrImpossibleDateException(); + } for (CalendarField f : CalendarField.ADJUST_ORDER) { int cur = f.valueOf(cal); int next = f.ceil(this,cur); @@ -378,10 +387,20 @@ public final class CronTab { * See {@link #floor(long)} * * This method modifies the given calendar and returns the same object. + * + * @throws RareOrImpossibleDateException if the date isn't hit in the 2 years before it indicates an impossible + * (e.g. Jun 31) date, or at least a date too rare to be useful. This addresses JENKINS-41864 and was added in TODO */ public Calendar floor(Calendar cal) { + Calendar twoYearsAgo = (Calendar) cal.clone(); + twoYearsAgo.add(Calendar.YEAR, -2); + OUTER: while (true) { + if (cal.compareTo(twoYearsAgo) < 0) { + // we went too far into the past + throw new RareOrImpossibleDateException(); + } for (CalendarField f : CalendarField.ADJUST_ORDER) { int cur = f.valueOf(cal); int next = f.floor(this,cur); diff --git a/core/src/main/java/hudson/scheduler/RareOrImpossibleDateException.java b/core/src/main/java/hudson/scheduler/RareOrImpossibleDateException.java new file mode 100644 index 0000000000..7bd9d2562f --- /dev/null +++ b/core/src/main/java/hudson/scheduler/RareOrImpossibleDateException.java @@ -0,0 +1,53 @@ +/* + * The MIT License + * + * Copyright (c) 2017 CloudBees, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package hudson.scheduler; + +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; + +import java.util.Calendar; + +/** + * This exception is thrown when trying to determine the previous or next occurrence of a given date determines + * that it's not happened, or going to happen, within some time period (e.g. within the next year). + * + *

This can typically have a few different reasons:

+ * + * + * + * @see CronTab#floor(Calendar) + * @see CronTab#ceil(Calendar) + * @since TODO + */ +@Restricted(NoExternalUse.class) +public class RareOrImpossibleDateException extends RuntimeException { +} diff --git a/core/src/main/java/hudson/triggers/TimerTrigger.java b/core/src/main/java/hudson/triggers/TimerTrigger.java index 4380c0797c..da844fa6b6 100644 --- a/core/src/main/java/hudson/triggers/TimerTrigger.java +++ b/core/src/main/java/hudson/triggers/TimerTrigger.java @@ -32,6 +32,7 @@ import hudson.model.Cause; import hudson.model.Item; import hudson.scheduler.CronTabList; import hudson.scheduler.Hash; +import hudson.scheduler.RareOrImpossibleDateException; import hudson.util.FormValidation; import java.text.DateFormat; import java.util.ArrayList; @@ -104,13 +105,17 @@ public class TimerTrigger extends Trigger { } private void updateValidationsForNextRun(Collection validations, CronTabList ctl) { - Calendar prev = ctl.previous(); - Calendar next = ctl.next(); - if (prev != null && next != null) { - DateFormat fmt = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL); - validations.add(FormValidation.ok(Messages.TimerTrigger_would_last_have_run_at_would_next_run_at(fmt.format(prev.getTime()), fmt.format(next.getTime())))); - } else { - validations.add(FormValidation.warning(Messages.TimerTrigger_no_schedules_so_will_never_run())); + try { + Calendar prev = ctl.previous(); + Calendar next = ctl.next(); + if (prev != null && next != null) { + DateFormat fmt = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL); + validations.add(FormValidation.ok(Messages.TimerTrigger_would_last_have_run_at_would_next_run_at(fmt.format(prev.getTime()), fmt.format(next.getTime())))); + } else { + validations.add(FormValidation.warning(Messages.TimerTrigger_no_schedules_so_will_never_run())); + } + } catch (RareOrImpossibleDateException ex) { + validations.add(FormValidation.warning(Messages.TimerTrigger_the_specified_cron_tab_is_rare_or_impossible())); } } } diff --git a/core/src/main/resources/hudson/triggers/Messages.properties b/core/src/main/resources/hudson/triggers/Messages.properties index 7efa24a94f..3b6e1a4253 100644 --- a/core/src/main/resources/hudson/triggers/Messages.properties +++ b/core/src/main/resources/hudson/triggers/Messages.properties @@ -31,5 +31,7 @@ TimerTrigger.MissingWhitespace=You appear to be missing whitespace between * and TimerTrigger.no_schedules_so_will_never_run=No schedules so will never run TimerTrigger.TimerTriggerCause.ShortDescription=Started by timer TimerTrigger.would_last_have_run_at_would_next_run_at=Would last have run at {0}; would next run at {1}. +TimerTrigger.the_specified_cron_tab_is_rare_or_impossible=This schedule will match dates only rarely (e.g. February 29) or \ + never (e.g. June 31), so this job may be triggered very rarely, if at all. Trigger.init=Initializing timer for triggers SCMTrigger.AdministrativeMonitorImpl.DisplayName=Too Many SCM Polling Threads diff --git a/core/src/test/groovy/hudson/util/SecretRewriterTest.groovy b/core/src/test/groovy/hudson/util/SecretRewriterTest.groovy index b748703ac1..a429bef54e 100644 --- a/core/src/test/groovy/hudson/util/SecretRewriterTest.groovy +++ b/core/src/test/groovy/hudson/util/SecretRewriterTest.groovy @@ -2,6 +2,7 @@ package hudson.util import com.trilead.ssh2.crypto.Base64 import hudson.FilePath +import hudson.Functions import jenkins.security.ConfidentialStoreRule import org.junit.Rule import org.junit.Test @@ -9,6 +10,8 @@ import org.junit.rules.TemporaryFolder import javax.crypto.Cipher +import static org.junit.Assume.assumeFalse + /** * * @@ -77,6 +80,7 @@ class SecretRewriterTest { */ @Test void recursionDetection() { + assumeFalse("Symlinks don't work on Windows very well", Functions.isWindows()) def sw = new SecretRewriter(); def st = StreamTaskListener.fromStdout() diff --git a/core/src/test/java/jenkins/model/RunIdMigratorTest.java b/core/src/test/java/jenkins/model/RunIdMigratorTest.java index f51d0299b8..71a3e47832 100644 --- a/core/src/test/java/jenkins/model/RunIdMigratorTest.java +++ b/core/src/test/java/jenkins/model/RunIdMigratorTest.java @@ -24,6 +24,7 @@ package jenkins.model; +import hudson.Functions; import hudson.Util; import hudson.util.StreamTaskListener; import java.io.File; @@ -38,6 +39,8 @@ import java.util.logging.Level; import org.apache.commons.io.FileUtils; import org.junit.Test; import static org.junit.Assert.*; +import static org.junit.Assume.assumeFalse; + import org.junit.Before; import org.junit.BeforeClass; import org.junit.Rule; @@ -79,6 +82,7 @@ public class RunIdMigratorTest { } @Test public void legacy() throws Exception { + assumeFalse("Symlinks don't work well on Windows", Functions.isWindows()); write("2014-01-02_03-04-05/build.xml", "\n\n ok\n 99\n ok\n"); link("99", "2014-01-02_03-04-05"); link("lastFailedBuild", "-1"); @@ -97,6 +101,7 @@ public class RunIdMigratorTest { } @Test public void reRunMigration() throws Exception { + assumeFalse("Symlinks don't work well on Windows", Functions.isWindows()); write("2014-01-02_03-04-04/build.xml", "\n 98\n"); link("98", "2014-01-02_03-04-04"); write("99/build.xml", "\n\n ok\n 1388649845000\n ok\n"); @@ -108,6 +113,7 @@ public class RunIdMigratorTest { } @Test public void reverseImmediately() throws Exception { + assumeFalse("Symlinks don't work well on Windows", Functions.isWindows()); File root = dir; dir = new File(dir, "jobs/somefolder/jobs/someproject/promotions/OK/builds"); write("99/build.xml", "\n\n ok\n 2014-01-02_03-04-05\n 1388649845000\n ok\n"); @@ -120,6 +126,7 @@ public class RunIdMigratorTest { } @Test public void reverseAfterNewBuilds() throws Exception { + assumeFalse("Symlinks don't work well on Windows", Functions.isWindows()); File root = dir; dir = new File(dir, "jobs/someproject/modules/test$test/builds"); write("1/build.xml", "\n\n ok\n 1388649845000\n ok\n"); @@ -130,6 +137,7 @@ public class RunIdMigratorTest { } @Test public void reverseMatrixAfterNewBuilds() throws Exception { + assumeFalse("Symlinks don't work well on Windows", Functions.isWindows()); File root = dir; dir = new File(dir, "jobs/someproject/Environment=prod/builds"); write("1/build.xml", "\n\n ok\n 1388649845000\n ok\n"); @@ -140,6 +148,7 @@ public class RunIdMigratorTest { } @Test public void reverseMavenAfterNewBuilds() throws Exception { + assumeFalse("Symlinks don't work well on Windows", Functions.isWindows()); File root = dir; dir = new File(dir, "jobs/someproject/test$test/builds"); write("1/build.xml", "\n\n ok\n 1388649845000\n ok\n"); diff --git a/core/src/test/java/jenkins/util/VirtualFileTest.java b/core/src/test/java/jenkins/util/VirtualFileTest.java index 46bfecd8d6..c45f45109c 100644 --- a/core/src/test/java/jenkins/util/VirtualFileTest.java +++ b/core/src/test/java/jenkins/util/VirtualFileTest.java @@ -24,6 +24,7 @@ package jenkins.util; +import hudson.Functions; import hudson.Util; import hudson.model.TaskListener; import java.io.File; @@ -32,6 +33,8 @@ import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import org.junit.Test; import static org.junit.Assert.*; +import static org.junit.Assume.assumeFalse; + import org.junit.Rule; import org.junit.rules.TemporaryFolder; import org.jvnet.hudson.test.Issue; @@ -42,6 +45,7 @@ public class VirtualFileTest { @Issue("SECURITY-162") @Test public void outsideSymlinks() throws Exception { + assumeFalse("Symlinks don't work well on Windows", Functions.isWindows()); File ws = tmp.newFolder("ws"); FileUtils.write(new File(ws, "safe"), "safe"); Util.createSymlink(ws, "safe", "supported", TaskListener.NULL); diff --git a/test/src/test/groovy/hudson/cli/SetBuildParameterCommandTest.groovy b/test/src/test/groovy/hudson/cli/SetBuildParameterCommandTest.groovy index 24d44d4624..b082cd03e5 100644 --- a/test/src/test/groovy/hudson/cli/SetBuildParameterCommandTest.groovy +++ b/test/src/test/groovy/hudson/cli/SetBuildParameterCommandTest.groovy @@ -1,5 +1,6 @@ package hudson.cli +import hudson.Functions import hudson.Launcher import hudson.model.AbstractBuild import hudson.model.BuildListener @@ -8,6 +9,8 @@ import hudson.model.ParametersDefinitionProperty import hudson.model.ParameterDefinition import hudson.model.Result import hudson.model.StringParameterDefinition +import hudson.tasks.BatchFile +import hudson.tasks.Builder import hudson.tasks.Shell import jenkins.model.JenkinsLocationConfiguration import org.junit.Assert @@ -39,9 +42,9 @@ public class SetBuildParameterCommandTest { }); List pd = [new StringParameterDefinition("a", ""), new StringParameterDefinition("b", "")]; p.addProperty(new ParametersDefinitionProperty(pd)) - p.buildersList.add(new Shell("java -jar cli.jar set-build-parameter a b")) - p.buildersList.add(new Shell("java -jar cli.jar set-build-parameter a x")) - p.buildersList.add(new Shell("java -jar cli.jar set-build-parameter b y")) + p.buildersList.add(createScriptBuilder("java -jar cli.jar set-build-parameter a b")) + p.buildersList.add(createScriptBuilder("java -jar cli.jar set-build-parameter a x")) + p.buildersList.add(createScriptBuilder("java -jar cli.jar set-build-parameter b y")) def r = [:]; @@ -50,10 +53,24 @@ public class SetBuildParameterCommandTest { assert r.equals(["a":"x", "b":"y"]); - p.buildersList.add(new Shell("BUILD_NUMBER=1 java -jar cli.jar set-build-parameter a b")); + if (Functions.isWindows()) { + p.buildersList.add(new BatchFile("set BUILD_NUMBER=1\r\njava -jar cli.jar set-build-parameter a b")) + } else { + p.buildersList.add(new Shell("BUILD_NUMBER=1 java -jar cli.jar set-build-parameter a b")) + } def b2 = j.assertBuildStatus(Result.FAILURE, p.scheduleBuild2(0).get()); r = [:]; b.getAction(ParametersAction.class).parameters.each { v -> r[v.name]=v.value } assert r.equals(["a":"x", "b":"y"]); } + + //TODO: determine if this should be pulled out into JenkinsRule or something + /** + * Create a script based builder (either Shell or BatchFile) depending on platform + * @param script the contents of the script to run + * @return A Builder instance of either Shell or BatchFile + */ + private Builder createScriptBuilder(String script) { + return Functions.isWindows() ? new BatchFile(script) : new Shell(script); + } } diff --git a/test/src/test/groovy/hudson/model/AbstractProjectTest.groovy b/test/src/test/groovy/hudson/model/AbstractProjectTest.groovy index 8c50f37f92..55294aa0c5 100644 --- a/test/src/test/groovy/hudson/model/AbstractProjectTest.groovy +++ b/test/src/test/groovy/hudson/model/AbstractProjectTest.groovy @@ -27,6 +27,7 @@ import com.gargoylesoftware.htmlunit.ElementNotFoundException import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException; import com.gargoylesoftware.htmlunit.HttpMethod import com.gargoylesoftware.htmlunit.WebRequest; +import hudson.tasks.BatchFile; import hudson.tasks.BuildStepMonitor; import hudson.tasks.Recorder; import com.gargoylesoftware.htmlunit.html.HtmlPage @@ -48,9 +49,10 @@ import hudson.triggers.TriggerDescriptor; import hudson.util.StreamTaskListener; import hudson.util.OneShotEvent import jenkins.model.Jenkins -import org.junit.Assert; -import org.jvnet.hudson.test.HudsonTestCase -import org.jvnet.hudson.test.Issue; +import org.junit.Rule +import org.junit.Test; +import org.jvnet.hudson.test.Issue +import org.jvnet.hudson.test.JenkinsRule; import org.jvnet.hudson.test.TestExtension; import org.jvnet.hudson.test.recipes.PresetData; import org.jvnet.hudson.test.recipes.PresetData.DataSet @@ -59,15 +61,22 @@ import org.junit.Assume; import org.jvnet.hudson.test.MockFolder import org.kohsuke.args4j.CmdLineException +import static org.junit.Assert.fail +import static org.junit.Assert.assertEquals; + /** * @author Kohsuke Kawaguchi */ -public class AbstractProjectTest extends HudsonTestCase { +public class AbstractProjectTest { + + @Rule public JenkinsRule j = new JenkinsRule(); + + @Test public void testConfigRoundtrip() { - def project = createFreeStyleProject(); - def l = jenkins.getLabel("foo && bar"); + def project = j.createFreeStyleProject(); + def l = j.jenkins.getLabel("foo && bar"); project.assignedLabel = l; - configRoundtrip((Item) project); + j.configRoundtrip((Item) project); assert l == project.getAssignedLabel(); } @@ -75,9 +84,10 @@ public class AbstractProjectTest extends HudsonTestCase { /** * Tests the workspace deletion. */ + @Test public void testWipeWorkspace() { - def project = createFreeStyleProject(); - project.buildersList.add(new Shell("echo hello")); + def project = j.createFreeStyleProject(); + project.buildersList.add(Functions.isWindows() ? new BatchFile("echo hello") : new Shell("echo hello")); def b = project.scheduleBuild2(0).get(); @@ -91,17 +101,18 @@ public class AbstractProjectTest extends HudsonTestCase { /** * Makes sure that the workspace deletion is protected. */ + @Test @PresetData(DataSet.NO_ANONYMOUS_READACCESS) public void testWipeWorkspaceProtected() { - def project = createFreeStyleProject(); - project.getBuildersList().add(new Shell("echo hello")); + def project = j.createFreeStyleProject(); + project.getBuildersList().add(Functions.isWindows() ? new BatchFile("echo hello") : new Shell("echo hello")); def b = project.scheduleBuild2(0).get(); assert b.getWorkspace().exists(): "Workspace should exist by now"; // make sure that the action link is protected - com.gargoylesoftware.htmlunit.WebClient wc = createWebClient(); + com.gargoylesoftware.htmlunit.WebClient wc = j.createWebClient(); try { wc.getPage(new WebRequest(new URL(wc.getContextPath() + project.getUrl() + "doWipeOutWorkspace"), HttpMethod.POST)); fail("Expected HTTP status code 403") @@ -114,16 +125,17 @@ public class AbstractProjectTest extends HudsonTestCase { * Makes sure that the workspace deletion link is not provided * when the user doesn't have an access. */ + @Test @PresetData(DataSet.ANONYMOUS_READONLY) public void testWipeWorkspaceProtected2() { - ((GlobalMatrixAuthorizationStrategy) jenkins.getAuthorizationStrategy()).add(AbstractProject.WORKSPACE,"anonymous"); + ((GlobalMatrixAuthorizationStrategy) j.jenkins.getAuthorizationStrategy()).add(AbstractProject.WORKSPACE,"anonymous"); // make sure that the deletion is protected in the same way testWipeWorkspaceProtected(); // there shouldn't be any "wipe out workspace" link for anonymous user - def webClient = createWebClient(); - HtmlPage page = webClient.getPage(jenkins.getItem("test0")); + def webClient = j.createWebClient(); + HtmlPage page = webClient.getPage(j.jenkins.getItem("test0")); page = (HtmlPage)page.getAnchorByText("Workspace").click(); try { @@ -138,11 +150,12 @@ public class AbstractProjectTest extends HudsonTestCase { /** * Tests the <optionalBlock @field> round trip behavior by using {@link AbstractProject#concurrentBuild} */ + @Test public void testOptionalBlockDataBindingRoundtrip() { - def p = createFreeStyleProject(); + def p = j.createFreeStyleProject(); [true,false].each { b -> p.concurrentBuild = b; - submit(createWebClient().getPage(p,"configure").getFormByName("config")); + j.submit(j.createWebClient().getPage(p,"configure").getFormByName("config")); assert b==p.isConcurrentBuild(); } } @@ -150,20 +163,21 @@ public class AbstractProjectTest extends HudsonTestCase { /** * Tests round trip configuration of the blockBuildWhenUpstreamBuilding field */ + @Test @Issue("JENKINS-4423") public void testConfiguringBlockBuildWhenUpstreamBuildingRoundtrip() { - def p = createFreeStyleProject(); + def p = j.createFreeStyleProject(); p.blockBuildWhenUpstreamBuilding = false; - def form = createWebClient().getPage(p, "configure").getFormByName("config"); + def form = j.createWebClient().getPage(p, "configure").getFormByName("config"); def input = form.getInputByName("blockBuildWhenUpstreamBuilding"); assert !input.isChecked(): "blockBuildWhenUpstreamBuilding check box is checked."; input.setChecked(true); - submit(form); + j.submit(form); assert p.blockBuildWhenUpstreamBuilding: "blockBuildWhenUpstreamBuilding was not updated from configuration form"; - form = createWebClient().getPage(p, "configure").getFormByName("config"); + form = j.createWebClient().getPage(p, "configure").getFormByName("config"); input = form.getInputByName("blockBuildWhenUpstreamBuilding"); assert input.isChecked(): "blockBuildWhenUpstreamBuilding check box is not checked."; } @@ -172,12 +186,13 @@ public class AbstractProjectTest extends HudsonTestCase { * Unless the concurrent build option is enabled, polling and build should be mutually exclusive * to avoid allocating unnecessary workspaces. */ + @Test @Issue("JENKINS-4202") public void testPollingAndBuildExclusion() { final OneShotEvent sync = new OneShotEvent(); - final FreeStyleProject p = createFreeStyleProject(); - def b1 = buildAndAssertSuccess(p); + final FreeStyleProject p = j.createFreeStyleProject(); + def b1 = j.buildAndAssertSuccess(p); p.scm = new NullSCM() { @Override @@ -217,7 +232,7 @@ public class AbstractProjectTest extends HudsonTestCase { // release the polling sync.signal(); - def b2 = assertBuildStatusSuccess(f); + def b2 = j.assertBuildStatusSuccess(f); // they should have used the same workspace. assert b1.workspace == b2.workspace; @@ -226,11 +241,12 @@ public class AbstractProjectTest extends HudsonTestCase { } } + @Test @Issue("JENKINS-1986") public void testBuildSymlinks() { Assume.assumeFalse("If we're on Windows, don't bother doing this", Functions.isWindows()); - def job = createFreeStyleProject(); + def job = j.createFreeStyleProject(); job.buildersList.add(new Shell("echo \"Build #\$BUILD_NUMBER\"\n")); def build = job.scheduleBuild2(0, new Cause.UserCause()).get(); File lastSuccessful = new File(job.rootDir, "lastSuccessful"), @@ -260,12 +276,13 @@ public class AbstractProjectTest extends HudsonTestCase { assert s.contains("Build #" + buildNumber + "\n") : "link should point to build #$buildNumber, but link was: ${Util.resolveSymlink(file, TaskListener.NULL)}\nand log was:\n$s"; } + @Test @Issue("JENKINS-2543") public void testSymlinkForPostBuildFailure() { Assume.assumeFalse("If we're on Windows, don't bother doing this", Functions.isWindows()); // Links should be updated after post-build actions when final build result is known - def job = createFreeStyleProject(); + def job = j.createFreeStyleProject(); job.buildersList.add(new Shell("echo \"Build #\$BUILD_NUMBER\"\n")); def build = job.scheduleBuild2(0, new Cause.UserCause()).get(); assert Result.SUCCESS == build.result; @@ -284,25 +301,27 @@ public class AbstractProjectTest extends HudsonTestCase { } /* TODO too slow, seems capable of causing testWorkspaceLock to time out: + @Test @Issue("JENKINS-15156") public void testGetBuildAfterGC() { - FreeStyleProject job = createFreeStyleProject(); + FreeStyleProject job = j.createFreeStyleProject(); job.scheduleBuild2(0, new Cause.UserIdCause()).get(); - jenkins.queue.clearLeftItems(); + j.jenkins.queue.clearLeftItems(); MemoryAssert.assertGC(new WeakReference(job.getLastBuild())); assert job.lastBuild != null; } */ + @Test @Issue("JENKINS-17137") public void testExternalBuildDirectorySymlinks() { - // TODO when using JUnit 4 add: Assume.assumeFalse(Functions.isWindows()); // symlinks may not be available - def form = createWebClient().goTo("configure").getFormByName("config"); - def builds = createTmpDir(); + Assume.assumeFalse(Functions.isWindows()); // symlinks may not be available + def form = j.createWebClient().goTo("configure").getFormByName("config"); + def builds = j.createTmpDir(); form.getInputByName("_.rawBuildsDir").valueAttribute = builds.toString() + "/\${ITEM_FULL_NAME}"; - submit(form); - assert builds.toString() + "/\${ITEM_FULL_NAME}" == jenkins.getRawBuildsDir(); - def p = jenkins.createProject(MockFolder.class, "d").createProject(FreeStyleProject.class, "p"); + j.submit(form); + assert builds.toString() + "/\${ITEM_FULL_NAME}" == j.jenkins.getRawBuildsDir(); + def p = j.jenkins.createProject(MockFolder.class, "d").createProject(FreeStyleProject.class, "p"); def b1 = p.scheduleBuild2(0).get(); def link = new File(p.rootDir, "lastStable"); assert link.exists(); @@ -325,14 +344,15 @@ public class AbstractProjectTest extends HudsonTestCase { } } + @Test @Issue("JENKINS-17138") public void testExternalBuildDirectoryRenameDelete() { - def form = createWebClient().goTo("configure").getFormByName("config"); - def builds = createTmpDir(); + def form = j.createWebClient().goTo("configure").getFormByName("config"); + def builds = j.createTmpDir(); form.getInputByName("_.rawBuildsDir").setValueAttribute(builds.toString() + "/\${ITEM_FULL_NAME}"); - submit(form); - assert builds.toString() + "/\${ITEM_FULL_NAME}" == jenkins.rawBuildsDir; - def p = jenkins.createProject(MockFolder.class, "d").createProject(FreeStyleProject.class, "prj"); + j.submit(form); + assert builds.toString() + "/\${ITEM_FULL_NAME}" == j.jenkins.rawBuildsDir; + def p = j.jenkins.createProject(MockFolder.class, "d").createProject(FreeStyleProject.class, "prj"); def b = p.scheduleBuild2(0).get(); def oldBuildDir = new File(builds, "d/prj"); assert new File(oldBuildDir, b.id) == b.rootDir; @@ -345,30 +365,32 @@ public class AbstractProjectTest extends HudsonTestCase { assert !b.rootDir.isDirectory(); } + @Test @Issue("JENKINS-18678") public void testRenameJobLostBuilds() throws Exception { - def p = createFreeStyleProject("initial"); - assertBuildStatusSuccess(p.scheduleBuild2(0)); + def p = j.createFreeStyleProject("initial"); + j.assertBuildStatusSuccess(p.scheduleBuild2(0)); assertEquals(1, p.getBuilds().size()); p.renameTo("edited"); p._getRuns().purgeCache(); assertEquals(1, p.getBuilds().size()); - def d = jenkins.createProject(MockFolder.class, "d"); + def d = j.jenkins.createProject(MockFolder.class, "d"); Items.move(p, d); - assertEquals(p, jenkins.getItemByFullName("d/edited")); + assertEquals(p, j.jenkins.getItemByFullName("d/edited")); p._getRuns().purgeCache(); assertEquals(1, p.getBuilds().size()); d.renameTo("d2"); - p = jenkins.getItemByFullName("d2/edited"); + p = j.jenkins.getItemByFullName("d2/edited"); p._getRuns().purgeCache(); assertEquals(1, p.getBuilds().size()); } + @Test @Issue("JENKINS-17575") public void testDeleteRedirect() { - createFreeStyleProject("j1"); + j.createFreeStyleProject("j1"); assert "" == deleteRedirectTarget("job/j1"); - createFreeStyleProject("j2"); + j.createFreeStyleProject("j2"); Jenkins.getInstance().addView(new AllView("v1")); assert "view/v1/" == deleteRedirectTarget("view/v1/job/j2"); MockFolder d = Jenkins.getInstance().createProject(MockFolder.class, "d"); @@ -381,19 +403,20 @@ public class AbstractProjectTest extends HudsonTestCase { } private String deleteRedirectTarget(String job) { - def wc = createWebClient(); + def wc = j.createWebClient(); String base = wc.getContextPath(); String loc = wc.getPage(wc.addCrumb(new WebRequest(new URL(base + job + "/doDelete"), HttpMethod.POST))).getUrl().toString(); assert loc.startsWith(base): loc; return loc.substring(base.length()); } + @Test @Issue("JENKINS-18407") public void testQueueSuccessBehavior() { // prevent any builds to test the behaviour - jenkins.numExecutors = 0; + j.jenkins.numExecutors = 0; - def p = createFreeStyleProject() + def p = j.createFreeStyleProject() def f = p.scheduleBuild2(0) assert f!=null; def g = p.scheduleBuild2(0) @@ -406,26 +429,27 @@ public class AbstractProjectTest extends HudsonTestCase { /** * Do the same as {@link #testQueueSuccessBehavior()} but over HTTP */ + @Test @Issue("JENKINS-18407") public void testQueueSuccessBehaviorOverHTTP() { // prevent any builds to test the behaviour - jenkins.numExecutors = 0; + j.jenkins.numExecutors = 0; - def p = createFreeStyleProject() - def wc = createWebClient(); + def p = j.createFreeStyleProject() + def wc = j.createWebClient(); - def rsp = wc.getPage("${getURL()}${p.url}build").webResponse + def rsp = wc.getPage("${j.getURL()}${p.url}build").webResponse assert rsp.statusCode==201; assert rsp.getResponseHeaderValue("Location")!=null; - def rsp2 = wc.getPage("${getURL()}${p.url}build").webResponse + def rsp2 = wc.getPage("${j.getURL()}${p.url}build").webResponse assert rsp2.statusCode==201; assert rsp.getResponseHeaderValue("Location")==rsp2.getResponseHeaderValue("Location") p.makeDisabled(true) try { - wc.getPage("${getURL()}${p.url}build") + wc.getPage("${j.getURL()}${p.url}build") fail(); } catch (FailingHttpStatusCodeException e) { // request should fail @@ -436,51 +460,56 @@ public class AbstractProjectTest extends HudsonTestCase { * We used to store {@link AbstractProject#triggers} as {@link Vector}, so make sure * we can still read back the configuration from that. */ + @Test public void testVectorTriggers() { - AbstractProject j = jenkins.createProjectFromXML("foo", getClass().getResourceAsStream("AbstractProjectTest/vectorTriggers.xml")) - assert j.triggers().size()==1 - def t = j.triggers()[0] + AbstractProject p = j.jenkins.createProjectFromXML("foo", getClass().getResourceAsStream("AbstractProjectTest/vectorTriggers.xml")) + assert p.triggers().size()==1 + def t = p.triggers()[0] assert t.class==SCMTrigger.class; assert t.spec=="*/10 * * * *" } + @Test @Issue("JENKINS-18813") public void testRemoveTrigger() { - AbstractProject j = jenkins.createProjectFromXML("foo", getClass().getResourceAsStream("AbstractProjectTest/vectorTriggers.xml")) + AbstractProject p = j.jenkins.createProjectFromXML("foo", getClass().getResourceAsStream("AbstractProjectTest/vectorTriggers.xml")) - TriggerDescriptor SCM_TRIGGER_DESCRIPTOR = Hudson.instance.getDescriptorOrDie(SCMTrigger.class) - j.removeTrigger(SCM_TRIGGER_DESCRIPTOR); - assert j.triggers().size()==0 + TriggerDescriptor SCM_TRIGGER_DESCRIPTOR = j.jenkins.getDescriptorOrDie(SCMTrigger.class) + p.removeTrigger(SCM_TRIGGER_DESCRIPTOR); + assert p.triggers().size()==0 } + @Test @Issue("JENKINS-18813") public void testAddTriggerSameType() { - AbstractProject j = jenkins.createProjectFromXML("foo", getClass().getResourceAsStream("AbstractProjectTest/vectorTriggers.xml")) + AbstractProject p = j.jenkins.createProjectFromXML("foo", getClass().getResourceAsStream("AbstractProjectTest/vectorTriggers.xml")) def newTrigger = new SCMTrigger("H/5 * * * *") - j.addTrigger(newTrigger); + p.addTrigger(newTrigger); - assert j.triggers().size()==1 - def t = j.triggers()[0] + assert p.triggers().size()==1 + def t = p.triggers()[0] assert t.class==SCMTrigger.class; assert t.spec=="H/5 * * * *" } + @Test @Issue("JENKINS-18813") public void testAddTriggerDifferentType() { - AbstractProject j = jenkins.createProjectFromXML("foo", getClass().getResourceAsStream("AbstractProjectTest/vectorTriggers.xml")) + AbstractProject p = j.jenkins.createProjectFromXML("foo", getClass().getResourceAsStream("AbstractProjectTest/vectorTriggers.xml")) def newTrigger = new TimerTrigger("20 * * * *") - j.addTrigger(newTrigger); + p.addTrigger(newTrigger); - assert j.triggers().size()==2 - def t = j.triggers()[1] + assert p.triggers().size()==2 + def t = p.triggers()[1] assert t == newTrigger } + @Test @Issue("JENKINS-10615") public void testWorkspaceLock() { - def p = createFreeStyleProject() + def p = j.createFreeStyleProject() p.concurrentBuild = true; def e1 = new OneShotEvent(), e2=new OneShotEvent() def done = new OneShotEvent() @@ -522,9 +551,10 @@ public class AbstractProjectTest extends HudsonTestCase { /** * Trying to POST to config.xml by a different job type should fail. */ + @Test public void testConfigDotXmlSubmissionToDifferentType() { - jenkins.crumbIssuer = null - def p = createFreeStyleProject() + j.jenkins.crumbIssuer = null + def p = j.createFreeStyleProject() HttpURLConnection con = postConfigDotXml(p, "") @@ -542,7 +572,7 @@ public class AbstractProjectTest extends HudsonTestCase { } private HttpURLConnection postConfigDotXml(FreeStyleProject p, String xml) { - HttpURLConnection con = new URL(getURL(), "job/${p.name}/config.xml").openConnection() + HttpURLConnection con = new URL(j.getURL(), "job/${p.name}/config.xml").openConnection() con.requestMethod = "POST" con.setRequestProperty("Content-Type", "application/xml") con.doOutput = true @@ -552,13 +582,15 @@ public class AbstractProjectTest extends HudsonTestCase { return con } + @Test @Issue("JENKINS-27549") public void testLoadingWithNPEOnTriggerStart() { - AbstractProject project = jenkins.createProjectFromXML("foo", getClass().getResourceAsStream("AbstractProjectTest/npeTrigger.xml")) + AbstractProject project = j.jenkins.createProjectFromXML("foo", getClass().getResourceAsStream("AbstractProjectTest/npeTrigger.xml")) assert project.triggers().size() == 1 } + @Test @Issue("JENKINS-30742") public void testResolveForCLI() { try { @@ -568,7 +600,7 @@ public class AbstractProjectTest extends HudsonTestCase { assert e.getMessage().contentEquals("No such job \u2018never_created\u2019 exists."); } - AbstractProject project = jenkins.createProject(FreeStyleProject.class, "never_created"); + AbstractProject project = j.jenkins.createProject(FreeStyleProject.class, "never_created"); try { AbstractProject not_found = AbstractProject.resolveForCLI("never_created1"); fail("Exception should occur before!"); diff --git a/test/src/test/groovy/hudson/util/TextFileTest.groovy b/test/src/test/groovy/hudson/util/TextFileTest.groovy index 9347b488a9..0299132fc8 100644 --- a/test/src/test/groovy/hudson/util/TextFileTest.groovy +++ b/test/src/test/groovy/hudson/util/TextFileTest.groovy @@ -44,9 +44,9 @@ class TextFileTest { f.text = getClass().getResource("ascii.txt").text def t = new TextFile(f) - def tail35 = "la, vitae interdum quam rutrum id.\n" - assert t.fastTail(35).equals(tail35) - assert tail35.length()==35 + def tailStr = "la, vitae interdum quam rutrum id." + System.lineSeparator() + assert t.fastTail(tailStr.length()).equals(tailStr) + assert tailStr.length()==(34 + System.lineSeparator().length()) } @Test diff --git a/test/src/test/java/hudson/PluginManagerTest.java b/test/src/test/java/hudson/PluginManagerTest.java index f68cf85dcb..7a22d84971 100644 --- a/test/src/test/java/hudson/PluginManagerTest.java +++ b/test/src/test/java/hudson/PluginManagerTest.java @@ -50,6 +50,7 @@ import net.sf.json.JSONObject; import org.apache.commons.io.FileUtils; import org.apache.tools.ant.filters.StringInputStream; import static org.junit.Assert.*; +import static org.junit.Assume.assumeFalse; import org.junit.Rule; import org.junit.Test; @@ -213,6 +214,7 @@ public class PluginManagerTest { } @Test public void prevalidateConfig() throws Exception { + assumeFalse("TODO: Implement this test on Windows", Functions.isWindows()); PersistedList sites = r.jenkins.getUpdateCenter().getSites(); sites.clear(); URL url = PluginManagerTest.class.getResource("/plugins/tasks-update-center.json"); @@ -467,6 +469,7 @@ public class PluginManagerTest { } @Test public void uploadDependencyResolution() throws Exception { + assumeFalse("TODO: Implement this test for Windows", Functions.isWindows()); PersistedList sites = r.jenkins.getUpdateCenter().getSites(); sites.clear(); URL url = PluginManagerTest.class.getResource("/plugins/upload-test-update-center.json"); diff --git a/test/src/test/java/hudson/ProcStarterTest.java b/test/src/test/java/hudson/ProcStarterTest.java index d88f30f722..901aa7e012 100644 --- a/test/src/test/java/hudson/ProcStarterTest.java +++ b/test/src/test/java/hudson/ProcStarterTest.java @@ -103,7 +103,8 @@ public class ProcStarterTest { @Override public Environment setUp(AbstractBuild build, Launcher launcher, BuildListener listener) throws IOException, InterruptedException { - Launcher.ProcStarter starter = launcher.launch().cmds("echo", "Hello"); + String[] cmds = Functions.isWindows() ? new String[] { "cmd.exe", "/C", "echo", "Hello" } : new String[] { "echo", "Hello" }; + Launcher.ProcStarter starter = launcher.launch().cmds(cmds); starter.start(); starter.join(); return new Environment() { @@ -148,7 +149,9 @@ public class ProcStarterTest { @Override public boolean perform(AbstractBuild build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException { - Launcher.ProcStarter starter = launcher.launch().cmds("echo", "Hello").pwd(new File("/this/path/doesnt/exist")); + String[] cmds = Functions.isWindows() ? new String[] { "cmd.exe", "/C", "echo", "Hello" } : new String[] { "echo", "Hello" }; + String path = Functions.isWindows() ? "C:\\this\\path\\doesn't\\exist" : "/this/path/doesnt/exist"; + Launcher.ProcStarter starter = launcher.launch().cmds(cmds).pwd(new File(path)); starter.start(); starter.join(); return true; diff --git a/test/src/test/java/hudson/ProcTest.java b/test/src/test/java/hudson/ProcTest.java index c3eebe20a0..4f7133ccff 100644 --- a/test/src/test/java/hudson/ProcTest.java +++ b/test/src/test/java/hudson/ProcTest.java @@ -2,6 +2,7 @@ package hudson; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; +import static org.junit.Assume.assumeFalse; import hudson.Launcher.LocalLauncher; import hudson.Launcher.RemoteLauncher; @@ -37,6 +38,7 @@ public class ProcTest { */ @Test public void remoteProcOutputSync() throws Exception { + assumeFalse("TODO: Implement this test for Windows", Functions.isWindows()); VirtualChannel ch = createSlaveChannel(); // keep the pipe fairly busy @@ -96,11 +98,13 @@ public class ProcTest { @Test public void ioPumpingWithLocalLaunch() throws Exception { + assumeFalse("TODO: Implement this test for Windows", Functions.isWindows()); doIoPumpingTest(new LocalLauncher(new StreamTaskListener(System.out, Charset.defaultCharset()))); } @Test public void ioPumpingWithRemoteLaunch() throws Exception { + assumeFalse("TODO: Implement this test for Windows", Functions.isWindows()); doIoPumpingTest(new RemoteLauncher( new StreamTaskListener(System.out, Charset.defaultCharset()), createSlaveChannel(), true)); diff --git a/test/src/test/java/hudson/cli/AbstractBuildRangeCommand2Test.java b/test/src/test/java/hudson/cli/AbstractBuildRangeCommand2Test.java index d2643b2d13..bea2d8de8a 100644 --- a/test/src/test/java/hudson/cli/AbstractBuildRangeCommand2Test.java +++ b/test/src/test/java/hudson/cli/AbstractBuildRangeCommand2Test.java @@ -25,10 +25,12 @@ package hudson.cli; import hudson.Extension; +import hudson.Functions; import hudson.model.AbstractBuild; import hudson.model.FreeStyleProject; import hudson.model.Job; import hudson.model.labels.LabelAtom; +import hudson.tasks.BatchFile; import hudson.tasks.Shell; import jenkins.model.Jenkins; import org.junit.Before; @@ -88,7 +90,7 @@ public class AbstractBuildRangeCommand2Test { @Test public void dummyRangeShouldSuccessEvenTheBuildIsRunning() throws Exception { FreeStyleProject project = j.createFreeStyleProject("aProject"); - project.getBuildersList().add(new Shell("echo 1\nsleep 10s")); + project.getBuildersList().add(Functions.isWindows() ? new BatchFile("echo 1\r\nping -n 10 127.0.0.1 >nul") : new Shell("echo 1\nsleep 10s")); assertThat("Job wasn't scheduled properly", project.scheduleBuild(0), equalTo(true)); // Wait until classProject is started (at least 1s) @@ -106,7 +108,7 @@ public class AbstractBuildRangeCommand2Test { .authorizedTo(Jenkins.READ, Job.READ) .invokeWithArgs("aProject", "1"); assertThat(result, succeeded()); - assertThat(result.stdout(), containsString("Builds: 1\n")); + assertThat(result.stdout(), containsString("Builds: 1" + System.lineSeparator())); } @Test public void dummyRangeShouldSuccessEvenTheBuildIsStuckInTheQueue() throws Exception { @@ -124,7 +126,7 @@ public class AbstractBuildRangeCommand2Test { .authorizedTo(Jenkins.READ, Job.READ) .invokeWithArgs("aProject", "1"); assertThat(result, succeeded()); - assertThat(result.stdout(), containsString("Builds: \n")); + assertThat(result.stdout(), containsString("Builds: " + System.lineSeparator())); } } diff --git a/test/src/test/java/hudson/cli/AbstractBuildRangeCommandTest.java b/test/src/test/java/hudson/cli/AbstractBuildRangeCommandTest.java index 50a4cf85cf..cda886fc85 100644 --- a/test/src/test/java/hudson/cli/AbstractBuildRangeCommandTest.java +++ b/test/src/test/java/hudson/cli/AbstractBuildRangeCommandTest.java @@ -119,13 +119,13 @@ public class AbstractBuildRangeCommandTest { .authorizedTo(Jenkins.READ, Job.READ) .invokeWithArgs(PROJECT_NAME, String.valueOf(BUILDS+1)); assertThat(result, succeeded()); - assertThat(result.stdout(), containsString("Builds: \n")); + assertThat(result.stdout(), containsString("Builds: "+System.lineSeparator())); result = command .authorizedTo(Jenkins.READ, Job.READ) .invokeWithArgs(PROJECT_NAME, String.valueOf(deleted[0])); assertThat(result, succeeded()); - assertThat(result.stdout(), containsString("Builds: \n")); + assertThat(result.stdout(), containsString("Builds: "+System.lineSeparator())); } @Test public void dummyRangeNumberSingleShouldSuccess() throws Exception { @@ -134,28 +134,28 @@ public class AbstractBuildRangeCommandTest { .authorizedTo(Jenkins.READ, Job.READ) .invokeWithArgs(PROJECT_NAME, "1"); assertThat(result, succeeded()); - assertThat(result.stdout(), containsString("Builds: 1\n")); + assertThat(result.stdout(), containsString("Builds: 1"+System.lineSeparator())); // First with plus symbol '+' result = command .authorizedTo(Jenkins.READ, Job.READ) .invokeWithArgs(PROJECT_NAME, "+1"); assertThat(result, succeeded()); - assertThat(result.stdout(), containsString("Builds: 1\n")); + assertThat(result.stdout(), containsString("Builds: 1"+System.lineSeparator())); // In the middle result = command .authorizedTo(Jenkins.READ, Job.READ) .invokeWithArgs(PROJECT_NAME, "10"); assertThat(result, succeeded()); - assertThat(result.stdout(), containsString("Builds: 10\n")); + assertThat(result.stdout(), containsString("Builds: 10"+System.lineSeparator())); // In the middle with plus symbol '+' result = command .authorizedTo(Jenkins.READ, Job.READ) .invokeWithArgs(PROJECT_NAME, "+10"); assertThat(result, succeeded()); - assertThat(result.stdout(), containsString("Builds: 10\n")); + assertThat(result.stdout(), containsString("Builds: 10"+System.lineSeparator())); // Last result = command @@ -163,7 +163,7 @@ public class AbstractBuildRangeCommandTest { .invokeWithArgs(PROJECT_NAME, String.valueOf(BUILDS)); assertThat(result, succeeded()); assertThat(result.stdout(), - containsString(String.format("Builds: %s\n", String.valueOf(BUILDS)))); + containsString(String.format("Builds: %s"+System.lineSeparator(), String.valueOf(BUILDS)))); // Last with the plus symbol '+' result = command @@ -171,7 +171,7 @@ public class AbstractBuildRangeCommandTest { .invokeWithArgs(PROJECT_NAME, '+' + String.valueOf(BUILDS)); assertThat(result, succeeded()); assertThat(result.stdout(), - containsString(String.format("Builds: %s\n", String.valueOf(BUILDS)))); + containsString(String.format("Builds: %s"+System.lineSeparator(), String.valueOf(BUILDS)))); } @Test public void dummyRangeNumberSingleShouldSuccessIfBuildNumberIsZero() throws Exception { @@ -179,13 +179,13 @@ public class AbstractBuildRangeCommandTest { .authorizedTo(Jenkins.READ, Job.READ) .invokeWithArgs(PROJECT_NAME, "0"); assertThat(result, succeeded()); - assertThat(result.stdout(), containsString("Builds: \n")); + assertThat(result.stdout(), containsString("Builds: "+System.lineSeparator())); result = command .authorizedTo(Jenkins.READ, Job.READ) .invokeWithArgs(PROJECT_NAME, "+0"); assertThat(result, succeeded()); - assertThat(result.stdout(), containsString("Builds: \n")); + assertThat(result.stdout(), containsString("Builds: "+System.lineSeparator())); } @Test public void dummyRangeNumberSingleShouldFailIfBuildNumberIsNegative() throws Exception { @@ -227,7 +227,7 @@ public class AbstractBuildRangeCommandTest { .authorizedTo(Jenkins.READ, Job.READ) .invokeWithArgs(PROJECT_NAME, ""); assertThat(result, succeeded()); - assertThat(result.stdout(), containsString("Builds: \n")); + assertThat(result.stdout(), containsString("Builds: "+System.lineSeparator())); } @Test public void dummyRangeNumberSingleShouldFailIfBuildNumberIsSpace() throws Exception { @@ -244,7 +244,7 @@ public class AbstractBuildRangeCommandTest { .authorizedTo(Jenkins.READ, Job.READ) .invokeWithArgs(PROJECT_NAME, ","); assertThat(result, succeeded()); - assertThat(result.stdout(), containsString("Builds: \n")); + assertThat(result.stdout(), containsString("Builds: "+System.lineSeparator())); } @Test public void dummyRangeNumberSingleShouldFailIfBuildNumberIsHyphen() throws Exception { @@ -261,40 +261,40 @@ public class AbstractBuildRangeCommandTest { .authorizedTo(Jenkins.READ, Job.READ) .invokeWithArgs(PROJECT_NAME, "1,2"); assertThat(result, succeeded()); - assertThat(result.stdout(), containsString("Builds: 1,2\n")); + assertThat(result.stdout(), containsString("Builds: 1,2"+System.lineSeparator())); // With plus symbol '+' result = command .authorizedTo(Jenkins.READ, Job.READ) .invokeWithArgs(PROJECT_NAME, "1,+2,4"); assertThat(result, succeeded()); - assertThat(result.stdout(), containsString("Builds: 1,2,4\n")); + assertThat(result.stdout(), containsString("Builds: 1,2,4"+System.lineSeparator())); // Build specified twice result = command .authorizedTo(Jenkins.READ, Job.READ) .invokeWithArgs(PROJECT_NAME, "1,1"); assertThat(result, succeeded()); - assertThat(result.stdout(), containsString("Builds: 1,1\n")); + assertThat(result.stdout(), containsString("Builds: 1,1"+System.lineSeparator())); // Build with zero build number result = command .authorizedTo(Jenkins.READ, Job.READ) .invokeWithArgs(PROJECT_NAME, "0,1,2"); assertThat(result, succeeded()); - assertThat(result.stdout(), containsString("Builds: 1,2\n")); + assertThat(result.stdout(), containsString("Builds: 1,2"+System.lineSeparator())); result = command .authorizedTo(Jenkins.READ, Job.READ) .invokeWithArgs(PROJECT_NAME, "1,0,2"); assertThat(result, succeeded()); - assertThat(result.stdout(), containsString("Builds: 1,2\n")); + assertThat(result.stdout(), containsString("Builds: 1,2"+System.lineSeparator())); result = command .authorizedTo(Jenkins.READ, Job.READ) .invokeWithArgs(PROJECT_NAME, "1,2,0"); assertThat(result, succeeded()); - assertThat(result.stdout(), containsString("Builds: 1,2\n")); + assertThat(result.stdout(), containsString("Builds: 1,2"+System.lineSeparator())); } @Test public void dummyRangeNumberMultiShouldSuccessIfSomeBuildDoesNotExist() throws Exception { @@ -302,19 +302,19 @@ public class AbstractBuildRangeCommandTest { .authorizedTo(Jenkins.READ, Job.READ) .invokeWithArgs(PROJECT_NAME, "1,2,"+deleted[0]); assertThat(result, succeeded()); - assertThat(result.stdout(), containsString("Builds: 1,2\n")); + assertThat(result.stdout(), containsString("Builds: 1,2"+System.lineSeparator())); result = command .authorizedTo(Jenkins.READ, Job.READ) .invokeWithArgs(PROJECT_NAME, String.format("1,%d,%d", deleted[0], deleted[0]+1)); assertThat(result, succeeded()); - assertThat(result.stdout(), containsString(String.format("Builds: 1,%d\n", deleted[0]+1))); + assertThat(result.stdout(), containsString(String.format("Builds: 1,%d"+System.lineSeparator(), deleted[0]+1))); result = command .authorizedTo(Jenkins.READ, Job.READ) .invokeWithArgs(PROJECT_NAME, String.format("%d,%d,%d", deleted[0]-1, deleted[0], deleted[0]+1)); assertThat(result, succeeded()); - assertThat(result.stdout(), containsString(String.format("Builds: %d,%d\n", deleted[0]-1, deleted[0]+1))); + assertThat(result.stdout(), containsString(String.format("Builds: %d,%d"+System.lineSeparator(), deleted[0]-1, deleted[0]+1))); } @Test public void dummyRangeNumberMultiShouldFailIfBuildNumberIsNegative() throws Exception { @@ -504,25 +504,25 @@ public class AbstractBuildRangeCommandTest { .authorizedTo(Jenkins.READ, Job.READ) .invokeWithArgs(PROJECT_NAME, "1-2"); assertThat(result, succeeded()); - assertThat(result.stdout(), containsString("Builds: 1,2\n")); + assertThat(result.stdout(), containsString("Builds: 1,2"+System.lineSeparator())); result = command .authorizedTo(Jenkins.READ, Job.READ) .invokeWithArgs(PROJECT_NAME, "+1-+2"); assertThat(result, succeeded()); - assertThat(result.stdout(), containsString("Builds: 1,2\n")); + assertThat(result.stdout(), containsString("Builds: 1,2"+System.lineSeparator())); result = command .authorizedTo(Jenkins.READ, Job.READ) .invokeWithArgs(PROJECT_NAME, "1-1"); assertThat(result, succeeded()); - assertThat(result.stdout(), containsString("Builds: 1\n")); + assertThat(result.stdout(), containsString("Builds: 1"+System.lineSeparator())); result = command .authorizedTo(Jenkins.READ, Job.READ) .invokeWithArgs(PROJECT_NAME, "+1-+1"); assertThat(result, succeeded()); - assertThat(result.stdout(), containsString("Builds: 1\n")); + assertThat(result.stdout(), containsString("Builds: 1"+System.lineSeparator())); result = command .authorizedTo(Jenkins.READ, Job.READ) @@ -536,49 +536,49 @@ public class AbstractBuildRangeCommandTest { builds += i; next = true; } - assertThat(result.stdout(), containsString("Builds: "+builds+"\n")); + assertThat(result.stdout(), containsString("Builds: "+builds+System.lineSeparator())); result = command .authorizedTo(Jenkins.READ, Job.READ) .invokeWithArgs(PROJECT_NAME, "+1-+"+deleted[0]); assertThat(result, succeeded()); - assertThat(result.stdout(), containsString("Builds: "+builds+"\n")); + assertThat(result.stdout(), containsString("Builds: "+builds+System.lineSeparator())); result = command .authorizedTo(Jenkins.READ, Job.READ) .invokeWithArgs(PROJECT_NAME, "0-1"); assertThat(result, succeeded()); - assertThat(result.stdout(), containsString("Builds: 1\n")); + assertThat(result.stdout(), containsString("Builds: 1"+System.lineSeparator())); result = command .authorizedTo(Jenkins.READ, Job.READ) .invokeWithArgs(PROJECT_NAME, "+0-+1"); assertThat(result, succeeded()); - assertThat(result.stdout(), containsString("Builds: 1\n")); + assertThat(result.stdout(), containsString("Builds: 1"+System.lineSeparator())); result = command .authorizedTo(Jenkins.READ, Job.READ) .invokeWithArgs(PROJECT_NAME, "0-2"); assertThat(result, succeeded()); - assertThat(result.stdout(), containsString("Builds: 1,2\n")); + assertThat(result.stdout(), containsString("Builds: 1,2"+System.lineSeparator())); result = command .authorizedTo(Jenkins.READ, Job.READ) .invokeWithArgs(PROJECT_NAME, "+0-+2"); assertThat(result, succeeded()); - assertThat(result.stdout(), containsString("Builds: 1,2\n")); + assertThat(result.stdout(), containsString("Builds: 1,2"+System.lineSeparator())); result = command .authorizedTo(Jenkins.READ, Job.READ) .invokeWithArgs(PROJECT_NAME, "0-0"); assertThat(result, succeeded()); - assertThat(result.stdout(), containsString("Builds: \n")); + assertThat(result.stdout(), containsString("Builds: "+System.lineSeparator())); result = command .authorizedTo(Jenkins.READ, Job.READ) .invokeWithArgs(PROJECT_NAME, "+0-+0"); assertThat(result, succeeded()); - assertThat(result.stdout(), containsString("Builds: \n")); + assertThat(result.stdout(), containsString("Builds: "+System.lineSeparator())); } @Test public void dummyRangeRangeSingleShouldSuccessIfSomeBuildDoesNotExist() throws Exception { @@ -586,19 +586,19 @@ public class AbstractBuildRangeCommandTest { .authorizedTo(Jenkins.READ, Job.READ) .invokeWithArgs(PROJECT_NAME, String.format("%d-%d", deleted[0], deleted[0]+1)); assertThat(result, succeeded()); - assertThat(result.stdout(), containsString(String.format("Builds: %d\n", deleted[0] + 1))); + assertThat(result.stdout(), containsString(String.format("Builds: %d"+System.lineSeparator(), deleted[0] + 1))); result = command .authorizedTo(Jenkins.READ, Job.READ) .invokeWithArgs(PROJECT_NAME, String.format("%d-%d", deleted[0]-1, deleted[0]+1)); assertThat(result, succeeded()); - assertThat(result.stdout(), containsString(String.format("Builds: %d,%d\n", deleted[0]-1, deleted[0]+1))); + assertThat(result.stdout(), containsString(String.format("Builds: %d,%d"+System.lineSeparator(), deleted[0]-1, deleted[0]+1))); result = command .authorizedTo(Jenkins.READ, Job.READ) .invokeWithArgs(PROJECT_NAME, String.format("%d-%d", deleted[0]-1, deleted[0])); assertThat(result, succeeded()); - assertThat(result.stdout(), containsString(String.format("Builds: %d\n", deleted[0]-1))); + assertThat(result.stdout(), containsString(String.format("Builds: %d"+System.lineSeparator(), deleted[0]-1))); } @Test public void dummyRangeRangeSingleShouldFailIfBuildRangeContainsZeroAndNegative() throws Exception { @@ -955,25 +955,25 @@ public class AbstractBuildRangeCommandTest { .authorizedTo(Jenkins.READ, Job.READ) .invokeWithArgs(PROJECT_NAME, "1-2,3-4"); assertThat(result, succeeded()); - assertThat(result.stdout(), containsString("Builds: 1,2,3,4\n")); + assertThat(result.stdout(), containsString("Builds: 1,2,3,4"+System.lineSeparator())); result = command .authorizedTo(Jenkins.READ, Job.READ) .invokeWithArgs(PROJECT_NAME, "1-3,3-4"); assertThat(result, succeeded()); - assertThat(result.stdout(), containsString("Builds: 1,2,3,3,4\n")); + assertThat(result.stdout(), containsString("Builds: 1,2,3,3,4"+System.lineSeparator())); result = command .authorizedTo(Jenkins.READ, Job.READ) .invokeWithArgs(PROJECT_NAME, "1-4,2-3"); assertThat(result, succeeded()); - assertThat(result.stdout(), containsString("Builds: 1,2,3,4,2,3\n")); + assertThat(result.stdout(), containsString("Builds: 1,2,3,4,2,3"+System.lineSeparator())); result = command .authorizedTo(Jenkins.READ, Job.READ) .invokeWithArgs(PROJECT_NAME, "1-2,4-5"); assertThat(result, succeeded()); - assertThat(result.stdout(), containsString("Builds: 1,2,4\n")); + assertThat(result.stdout(), containsString("Builds: 1,2,4"+System.lineSeparator())); } @Extension diff --git a/test/src/test/java/hudson/cli/ConsoleCommandTest.java b/test/src/test/java/hudson/cli/ConsoleCommandTest.java index f48f0fe1ed..1f4033e0c2 100644 --- a/test/src/test/java/hudson/cli/ConsoleCommandTest.java +++ b/test/src/test/java/hudson/cli/ConsoleCommandTest.java @@ -24,12 +24,14 @@ package hudson.cli; +import hudson.Functions; import hudson.model.FreeStyleProject; import hudson.model.Item; import hudson.model.Job; import hudson.model.Result; import hudson.model.Run; import hudson.model.labels.LabelAtom; +import hudson.tasks.BatchFile; import hudson.tasks.Shell; import jenkins.model.Jenkins; import org.junit.Before; @@ -156,7 +158,11 @@ public class ConsoleCommandTest { @Test public void consoleShouldSuccessWithLastBuild() throws Exception { FreeStyleProject project = j.createFreeStyleProject("aProject"); - project.getBuildersList().add(new Shell("echo 1")); + if (Functions.isWindows()) { + project.getBuildersList().add(new BatchFile("echo 1")); + } else { + project.getBuildersList().add(new Shell("echo 1")); + } assertThat(project.scheduleBuild2(0).get().getLog(), containsString("echo 1")); final CLICommandInvoker.Result result = command @@ -170,7 +176,11 @@ public class ConsoleCommandTest { @Test public void consoleShouldSuccessWithSpecifiedBuildNumber() throws Exception { FreeStyleProject project = j.createFreeStyleProject("aProject"); - project.getBuildersList().add(new Shell("echo ${BUILD_NUMBER}")); + if (Functions.isWindows()) { + project.getBuildersList().add(new BatchFile("echo %BUILD_NUMBER%")); + } else { + project.getBuildersList().add(new Shell("echo ${BUILD_NUMBER}")); + } assertThat(project.scheduleBuild2(0).get().getLog(), containsString("echo 1")); assertThat(project.scheduleBuild2(0).get().getLog(), containsString("echo 2")); assertThat(project.scheduleBuild2(0).get().getLog(), containsString("echo 3")); @@ -184,10 +194,15 @@ public class ConsoleCommandTest { } @Test public void consoleShouldSuccessWithFollow() throws Exception { - FreeStyleProject project = j.createFreeStyleProject("aProject"); - project.getBuildersList().add(new Shell("echo start - ${BUILD_NUMBER}\nsleep 10s\n" - + "echo after sleep - ${BUILD_NUMBER}")); + //TODO: do we really want to sleep for 10 seconds? + if(Functions.isWindows()) { + project.getBuildersList().add(new BatchFile("echo start - %BUILD_NUMBER%\r\n" + + "ping -n 10 127.0.0.1 >nul\r\necho after sleep - %BUILD_NUMBER%")); + } else { + project.getBuildersList().add(new Shell("echo start - ${BUILD_NUMBER}\nsleep 10s\n" + + "echo after sleep - ${BUILD_NUMBER}")); + } if (!project.scheduleBuild(0)) { fail("Job wasn't scheduled properly"); } @@ -229,14 +244,18 @@ public class ConsoleCommandTest { @Test public void consoleShouldSuccessWithLastNLines() throws Exception { FreeStyleProject project = j.createFreeStyleProject("aProject"); - project.getBuildersList().add(new Shell("echo 1\necho 2\necho 3\necho 4\necho 5")); + if(Functions.isWindows()) { + project.getBuildersList().add(new BatchFile("echo 1\r\necho 2\r\necho 3\r\necho 4\r\necho 5")); + } else { + project.getBuildersList().add(new Shell("echo 1\necho 2\necho 3\necho 4\necho 5")); + } project.scheduleBuild2(0).get(); assertThat(project.getBuildByNumber(1).getLog(), containsString("echo 1")); assertThat(project.getBuildByNumber(1).getLog(), containsString("echo 5")); final CLICommandInvoker.Result result = command .authorizedTo(Jenkins.READ, Job.READ, Item.BUILD) - .invokeWithArgs("aProject", "1", "-n", "4"); + .invokeWithArgs("aProject", "1", "-n", Functions.isWindows() ? "5" : "4"); assertThat(result, succeeded()); assertThat(result.stdout(), not(containsString("echo 1"))); @@ -246,9 +265,16 @@ public class ConsoleCommandTest { @Test public void consoleShouldSuccessWithLastNLinesAndFollow() throws Exception { FreeStyleProject project = j.createFreeStyleProject("aProject"); - project.getBuildersList().add(new Shell("echo 1\necho 2\necho 3\necho 4\necho 5\n" - + "sleep 10s\n" - + "echo 6\necho 7\necho 8\necho 9")); + //TODO: do we really want to sleep for 10 seconds? + if (Functions.isWindows()) { + // the ver >NUL is to reset ERRORLEVEL so we don't fail (ping causes the error) + project.getBuildersList().add(new BatchFile("echo 1\r\necho 2\r\necho 3\r\necho 4\r\necho 5\r\n" + + "ping -n 10 127.0.0.1 >nul\r\necho 6\r\necho 7\r\necho 8\r\necho 9")); + } else { + project.getBuildersList().add(new Shell("echo 1\necho 2\necho 3\necho 4\necho 5\n" + + "sleep 10s\n" + + "echo 6\necho 7\necho 8\necho 9")); + } if (!project.scheduleBuild(0)) { fail("Job wasn't scheduled properly"); @@ -270,7 +296,7 @@ public class ConsoleCommandTest { CLICommandInvoker.Result result = command .authorizedTo(Jenkins.READ, Job.READ, Item.BUILD) - .invokeWithArgs("aProject", "1", "-f", "-n", "4"); + .invokeWithArgs("aProject", "1", "-f", "-n", Functions.isWindows() ? "5" : "4"); assertThat(result, succeeded()); assertThat(result.stdout(), not(containsString("echo 1"))); diff --git a/test/src/test/java/hudson/cli/DeleteBuildsCommandTest.java b/test/src/test/java/hudson/cli/DeleteBuildsCommandTest.java index 59d338c2d6..0b111edd87 100644 --- a/test/src/test/java/hudson/cli/DeleteBuildsCommandTest.java +++ b/test/src/test/java/hudson/cli/DeleteBuildsCommandTest.java @@ -24,6 +24,7 @@ package hudson.cli; +import hudson.Functions; import hudson.model.ExecutorTest; import hudson.model.FreeStyleProject; import hudson.model.Job; @@ -43,6 +44,7 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.hasSize; +import static org.junit.Assume.assumeFalse; /** * @author pjanouse @@ -135,6 +137,7 @@ public class DeleteBuildsCommandTest { } @Test public void deleteBuildsShouldSuccessEvenTheBuildIsRunning() throws Exception { + assumeFalse("You can't delete files that are in use on Windows", Functions.isWindows()); FreeStyleProject project = j.createFreeStyleProject("aProject"); ExecutorTest.startBlockingBuild(project); assertThat(((FreeStyleProject) j.jenkins.getItem("aProject")).getBuilds(), hasSize(1)); diff --git a/test/src/test/java/hudson/cli/ReloadJobCommandTest.java b/test/src/test/java/hudson/cli/ReloadJobCommandTest.java index 2e21dc0b91..a012090070 100644 --- a/test/src/test/java/hudson/cli/ReloadJobCommandTest.java +++ b/test/src/test/java/hudson/cli/ReloadJobCommandTest.java @@ -25,8 +25,11 @@ package hudson.cli; import hudson.FilePath; +import hudson.Functions; import hudson.model.FreeStyleProject; import hudson.model.Job; +import hudson.tasks.BatchFile; +import hudson.tasks.Builder; import hudson.tasks.Shell; import jenkins.model.Jenkins; import org.junit.Before; @@ -58,7 +61,7 @@ public class ReloadJobCommandTest { @Test public void reloadJobShouldFailWithoutJobConfigurePermission() throws Exception { FreeStyleProject project = j.createFreeStyleProject("aProject"); - project.getBuildersList().add(new Shell("echo 1")); + project.getBuildersList().add(createScriptBuilder("echo 1")); assertThat(project.scheduleBuild2(0).get().getLog(), containsString("echo 1")); changeProjectOnTheDisc(project, "echo 1", "echo 2"); @@ -77,7 +80,7 @@ public class ReloadJobCommandTest { @Test public void reloadJobShouldFailWithoutJobReadPermission() throws Exception { FreeStyleProject project = j.createFreeStyleProject("aProject"); - project.getBuildersList().add(new Shell("echo 1")); + project.getBuildersList().add(createScriptBuilder("echo 1")); assertThat(project.scheduleBuild2(0).get().getLog(), containsString("echo 1")); changeProjectOnTheDisc(project, "echo 1", "echo 2"); @@ -96,7 +99,7 @@ public class ReloadJobCommandTest { @Test public void reloadJobShouldSucceed() throws Exception { FreeStyleProject project = j.createFreeStyleProject("aProject"); - project.getBuildersList().add(new Shell("echo 1")); + project.getBuildersList().add(createScriptBuilder("echo 1")); assertThat(project.scheduleBuild2(0).get().getLog(), containsString("echo 1")); @@ -134,13 +137,12 @@ public class ReloadJobCommandTest { } @Test public void reloadJobManyShouldSucceed() throws Exception { - FreeStyleProject project1 = j.createFreeStyleProject("aProject1"); - project1.getBuildersList().add(new Shell("echo 1")); + project1.getBuildersList().add(createScriptBuilder("echo 1")); FreeStyleProject project2 = j.createFreeStyleProject("aProject2"); - project2.getBuildersList().add(new Shell("echo 1")); + project2.getBuildersList().add(createScriptBuilder("echo 1")); FreeStyleProject project3 = j.createFreeStyleProject("aProject3"); - project3.getBuildersList().add(new Shell("echo 1")); + project3.getBuildersList().add(createScriptBuilder("echo 1")); assertThat(project1.scheduleBuild2(0).get().getLog(), containsString("echo 1")); assertThat(project2.scheduleBuild2(0).get().getLog(), containsString("echo 1")); @@ -164,9 +166,9 @@ public class ReloadJobCommandTest { @Test public void reloadJobManyShouldFailIfFirstJobDoesNotExist() throws Exception { FreeStyleProject project1 = j.createFreeStyleProject("aProject1"); - project1.getBuildersList().add(new Shell("echo 1")); + project1.getBuildersList().add(createScriptBuilder("echo 1")); FreeStyleProject project2 = j.createFreeStyleProject("aProject2"); - project2.getBuildersList().add(new Shell("echo 1")); + project2.getBuildersList().add(createScriptBuilder("echo 1")); assertThat(project1.scheduleBuild2(0).get().getLog(), containsString("echo 1")); assertThat(project2.scheduleBuild2(0).get().getLog(), containsString("echo 1")); @@ -190,9 +192,9 @@ public class ReloadJobCommandTest { @Test public void reloadJobManyShouldFailIfMiddleJobDoesNotExist() throws Exception { FreeStyleProject project1 = j.createFreeStyleProject("aProject1"); - project1.getBuildersList().add(new Shell("echo 1")); + project1.getBuildersList().add(createScriptBuilder("echo 1")); FreeStyleProject project2 = j.createFreeStyleProject("aProject2"); - project2.getBuildersList().add(new Shell("echo 1")); + project2.getBuildersList().add(createScriptBuilder("echo 1")); assertThat(project1.scheduleBuild2(0).get().getLog(), containsString("echo 1")); assertThat(project2.scheduleBuild2(0).get().getLog(), containsString("echo 1")); @@ -216,9 +218,9 @@ public class ReloadJobCommandTest { @Test public void reloadJobManyShouldFailIfLastJobDoesNotExist() throws Exception { FreeStyleProject project1 = j.createFreeStyleProject("aProject1"); - project1.getBuildersList().add(new Shell("echo 1")); + project1.getBuildersList().add(createScriptBuilder("echo 1")); FreeStyleProject project2 = j.createFreeStyleProject("aProject2"); - project2.getBuildersList().add(new Shell("echo 1")); + project2.getBuildersList().add(createScriptBuilder("echo 1")); assertThat(project1.scheduleBuild2(0).get().getLog(), containsString("echo 1")); assertThat(project2.scheduleBuild2(0).get().getLog(), containsString("echo 1")); @@ -242,9 +244,9 @@ public class ReloadJobCommandTest { @Test public void reloadJobManyShouldFailIfMoreJobsDoNotExist() throws Exception { FreeStyleProject project1 = j.createFreeStyleProject("aProject1"); - project1.getBuildersList().add(new Shell("echo 1")); + project1.getBuildersList().add(createScriptBuilder("echo 1")); FreeStyleProject project2 = j.createFreeStyleProject("aProject2"); - project2.getBuildersList().add(new Shell("echo 1")); + project2.getBuildersList().add(createScriptBuilder("echo 1")); assertThat(project1.scheduleBuild2(0).get().getLog(), containsString("echo 1")); assertThat(project2.scheduleBuild2(0).get().getLog(), containsString("echo 1")); @@ -267,11 +269,10 @@ public class ReloadJobCommandTest { } @Test public void reloadJobManyShouldSucceedEvenAJobIsSpecifiedTwice() throws Exception { - FreeStyleProject project1 = j.createFreeStyleProject("aProject1"); - project1.getBuildersList().add(new Shell("echo 1")); + project1.getBuildersList().add(createScriptBuilder("echo 1")); FreeStyleProject project2 = j.createFreeStyleProject("aProject2"); - project2.getBuildersList().add(new Shell("echo 1")); + project2.getBuildersList().add(createScriptBuilder("echo 1")); assertThat(project1.scheduleBuild2(0).get().getLog(), containsString("echo 1")); assertThat(project2.scheduleBuild2(0).get().getLog(), containsString("echo 1")); @@ -303,4 +304,13 @@ public class ReloadJobCommandTest { FilePath fp = new FilePath(new File(project.getRootDir()+"/config.xml")); fp.write(fp.readToString().replace(oldstr, newstr), null); } + + /** + * Create a script based builder (either Shell or BatchFile) depending on platform + * @param script the contents of the script to run + * @return A Builder instance of either Shell or BatchFile + */ + private Builder createScriptBuilder(String script) { + return Functions.isWindows() ? new BatchFile(script) : new Shell(script); + } } diff --git a/test/src/test/java/hudson/cli/SetBuildDescriptionCommandTest.java b/test/src/test/java/hudson/cli/SetBuildDescriptionCommandTest.java index acc4ec7799..3f2931f1aa 100644 --- a/test/src/test/java/hudson/cli/SetBuildDescriptionCommandTest.java +++ b/test/src/test/java/hudson/cli/SetBuildDescriptionCommandTest.java @@ -25,10 +25,13 @@ package hudson.cli; import hudson.FilePath; +import hudson.Functions; import hudson.model.FreeStyleBuild; import hudson.model.FreeStyleProject; import hudson.model.Job; import hudson.model.Run; +import hudson.tasks.BatchFile; +import hudson.tasks.Builder; import hudson.tasks.Shell; import jenkins.model.Jenkins; import org.junit.Before; @@ -61,7 +64,7 @@ public class SetBuildDescriptionCommandTest { @Test public void setBuildDescriptionShouldFailWithoutJobReadPermission() throws Exception { FreeStyleProject project = j.createFreeStyleProject("aProject"); - project.getBuildersList().add(new Shell("echo 1")); + project.getBuildersList().add(createScriptBuilder("echo 1")); assertThat(project.scheduleBuild2(0).get().getLog(), containsString("echo 1")); final CLICommandInvoker.Result result = command @@ -74,7 +77,7 @@ public class SetBuildDescriptionCommandTest { @Test public void setBuildDescriptionShouldFailWithoutRunUpdatePermission1() throws Exception { FreeStyleProject project = j.createFreeStyleProject("aProject"); - project.getBuildersList().add(new Shell("echo 1")); + project.getBuildersList().add(createScriptBuilder("echo 1")); assertThat(project.scheduleBuild2(0).get().getLog(), containsString("echo 1")); final CLICommandInvoker.Result result = command @@ -87,7 +90,7 @@ public class SetBuildDescriptionCommandTest { @Test public void setBuildDescriptionShouldSucceed() throws Exception { FreeStyleProject project = j.createFreeStyleProject("aProject"); - project.getBuildersList().add(new Shell("echo 1")); + project.getBuildersList().add(createScriptBuilder("echo 1")); FreeStyleBuild build = project.scheduleBuild2(0).get(); assertThat(build.getLog(), containsString("echo 1")); assertThat(build.getDescription(), equalTo(null)); @@ -133,7 +136,7 @@ public class SetBuildDescriptionCommandTest { @Test public void setBuildDescriptionShouldFailIfBuildDoesNotExist() throws Exception { FreeStyleProject project = j.createFreeStyleProject("aProject"); - project.getBuildersList().add(new Shell("echo 1")); + project.getBuildersList().add(createScriptBuilder("echo 1")); assertThat(project.scheduleBuild2(0).get().getLog(), containsString("echo 1")); final CLICommandInvoker.Result result = command @@ -145,4 +148,14 @@ public class SetBuildDescriptionCommandTest { assertThat(result.stderr(), containsString("ERROR: No such build #2")); } + //TODO: determine if this should be pulled out into JenkinsRule or something + /** + * Create a script based builder (either Shell or BatchFile) depending on platform + * @param script the contents of the script to run + * @return A Builder instance of either Shell or BatchFile + */ + private Builder createScriptBuilder(String script) { + return Functions.isWindows() ? new BatchFile(script) : new Shell(script); + } + } diff --git a/test/src/test/java/hudson/model/ParametersAction2Test.java b/test/src/test/java/hudson/model/ParametersAction2Test.java index 32a9d59b8f..0eb8c13995 100644 --- a/test/src/test/java/hudson/model/ParametersAction2Test.java +++ b/test/src/test/java/hudson/model/ParametersAction2Test.java @@ -1,6 +1,8 @@ package hudson.model; +import hudson.Functions; import hudson.Launcher; +import hudson.tasks.BatchFile; import hudson.tasks.Builder; import org.junit.Rule; import org.junit.Test; @@ -67,7 +69,8 @@ public class ParametersAction2Test { public void backwardCompatibility() throws Exception { // Local data contains a parameterized job with two parameters (FOO and BAR) and one build // with pre-fix format (generated with 1.609.3) with FOO, BAR and UNDEF. - FreeStyleProject p = j.jenkins.getItemByFullName("parameterized", FreeStyleProject.class); + FreeStyleProject p = j.jenkins.getItemByFullName(Functions.isWindows() ? "parameterized-windows" : "parameterized", FreeStyleProject.class); + FreeStyleBuild b1 = p.getBuildByNumber(1); ParametersAction pa = b1.getAction(ParametersAction.class); hasParameterWithName(pa, "FOO"); diff --git a/test/src/test/java/hudson/model/ProjectTest.java b/test/src/test/java/hudson/model/ProjectTest.java index b15128ce5d..b3bd860a20 100644 --- a/test/src/test/java/hudson/model/ProjectTest.java +++ b/test/src/test/java/hudson/model/ProjectTest.java @@ -25,8 +25,10 @@ package hudson.model; import com.gargoylesoftware.htmlunit.HttpMethod; import com.gargoylesoftware.htmlunit.WebRequest; +import hudson.*; import hudson.model.queue.QueueTaskFuture; import hudson.security.AccessDeniedException2; +import hudson.tasks.*; import org.acegisecurity.context.SecurityContextHolder; import hudson.security.HudsonPrivateSecurityRealm; import hudson.security.GlobalMatrixAuthorizationStrategy; @@ -38,9 +40,7 @@ import org.jvnet.hudson.reactor.ReactorException; import org.jvnet.hudson.test.FakeChangeLogSCM; import hudson.scm.SCMRevisionState; import hudson.scm.PollingResult; -import hudson.Launcher; import hudson.Launcher.RemoteLauncher; -import hudson.Util; import hudson.scm.NullSCM; import hudson.scm.SCM; import hudson.model.queue.SubTaskContributor; @@ -62,15 +62,13 @@ import java.io.Serializable; import jenkins.scm.DefaultSCMCheckoutStrategyImpl; import jenkins.scm.SCMCheckoutStrategy; import java.io.File; -import hudson.FilePath; + import hudson.slaves.EnvironmentVariablesNodeProperty; -import hudson.EnvVars; import hudson.model.labels.LabelAtom; import hudson.scm.SCMDescriptor; import hudson.slaves.Cloud; import hudson.slaves.DumbSlave; import hudson.slaves.NodeProvisioner; -import hudson.tasks.Shell; import org.jvnet.hudson.test.TestExtension; import java.util.List; import java.util.ArrayList; @@ -81,9 +79,7 @@ import org.junit.Rule; import org.junit.Test; import org.jvnet.hudson.test.JenkinsRule; import static org.junit.Assert.*; -import hudson.tasks.Fingerprinter; -import hudson.tasks.ArtifactArchiver; -import hudson.tasks.BuildTrigger; + import java.util.Map; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; @@ -194,7 +190,8 @@ public class ProjectTest { getFilePath = true; assertNotNull("Project should have any workspace because WorkspaceBrowser find some.", p.getSomeWorkspace()); getFilePath = false; - p.getBuildersList().add(new Shell("echo ahoj > some.log")); + String cmd = "echo ahoj > some.log"; + p.getBuildersList().add(Functions.isWindows() ? new BatchFile(cmd) : new Shell(cmd)); j.buildAndAssertSuccess(p); assertNotNull("Project should has any workspace.", p.getSomeWorkspace()); } @@ -202,7 +199,8 @@ public class ProjectTest { @Test public void testGetSomeBuildWithWorkspace() throws Exception{ FreeStyleProject p = j.createFreeStyleProject("project"); - p.getBuildersList().add(new Shell("echo ahoj > some.log")); + String cmd = "echo ahoj > some.log"; + p.getBuildersList().add(Functions.isWindows() ? new BatchFile(cmd) : new Shell(cmd)); assertNull("Project which has never run should not have any build with workspace.", p.getSomeBuildWithWorkspace()); j.buildAndAssertSuccess(p); assertEquals("Last build should have workspace.", p.getLastBuild(), p.getSomeBuildWithWorkspace()); @@ -213,7 +211,8 @@ public class ProjectTest { @Issue("JENKINS-10450") @Test public void workspaceBrowsing() throws Exception { FreeStyleProject p = j.createFreeStyleProject("project"); - p.getBuildersList().add(new Shell("echo ahoj > some.log")); + String cmd = "echo ahoj > some.log"; + p.getBuildersList().add(Functions.isWindows() ? new BatchFile(cmd) : new Shell(cmd)); j.buildAndAssertSuccess(p); JenkinsRule.WebClient wc = j.createWebClient(); wc.goTo("job/project/ws/some.log", "text/plain"); @@ -360,14 +359,14 @@ public class ProjectTest { @Test public void testGetCauseOfBlockage() throws Exception { FreeStyleProject p = j.createFreeStyleProject("project"); - p.getBuildersList().add(new Shell("sleep 10")); + p.getBuildersList().add(Functions.isWindows() ? new BatchFile("ping -n 10 127.0.0.1 >nul") : new Shell("sleep 10")); QueueTaskFuture b1 = waitForStart(p); assertInstanceOf("Build can not start because previous build has not finished: " + p.getCauseOfBlockage(), p.getCauseOfBlockage(), BlockedBecauseOfBuildInProgress.class); p.getLastBuild().getExecutor().interrupt(); b1.get(); // wait for it to finish FreeStyleProject downstream = j.createFreeStyleProject("project-downstream"); - downstream.getBuildersList().add(new Shell("sleep 10")); + downstream.getBuildersList().add(Functions.isWindows() ? new BatchFile("ping -n 10 127.0.0.1 >nul") : new Shell("sleep 10")); p.getPublishersList().add(new BuildTrigger(Collections.singleton(downstream), Result.SUCCESS)); Jenkins.getInstance().rebuildDependencyGraph(); p.setBlockBuildWhenDownstreamBuilding(true); @@ -606,7 +605,8 @@ public class ProjectTest { auth.add(Jenkins.READ, user.getId()); Slave slave = j.createOnlineSlave(); project.setAssignedLabel(slave.getSelfLabel()); - project.getBuildersList().add(new Shell("echo hello > change.log")); + String cmd = "echo hello > change.log"; + project.getBuildersList().add(Functions.isWindows()? new BatchFile(cmd) : new Shell(cmd)); j.buildAndAssertSuccess(project); JenkinsRule.WebClient wc = j.createWebClient().login(user.getId(), "password"); WebRequest request = new WebRequest(new URL(wc.getContextPath() + project.getUrl() + "doWipeOutWorkspace"), HttpMethod.POST); diff --git a/test/src/test/java/hudson/model/QueueTest.java b/test/src/test/java/hudson/model/QueueTest.java index 2812c1099c..35289643c1 100644 --- a/test/src/test/java/hudson/model/QueueTest.java +++ b/test/src/test/java/hudson/model/QueueTest.java @@ -30,6 +30,7 @@ import com.gargoylesoftware.htmlunit.html.HtmlForm; import com.gargoylesoftware.htmlunit.html.HtmlFormUtil; import com.gargoylesoftware.htmlunit.html.HtmlPage; import com.gargoylesoftware.htmlunit.xml.XmlPage; +import hudson.Functions; import hudson.Launcher; import hudson.XmlFile; import hudson.matrix.Axis; @@ -62,6 +63,7 @@ import hudson.slaves.DummyCloudImpl; import hudson.slaves.NodeProperty; import hudson.slaves.NodePropertyDescriptor; import hudson.slaves.NodeProvisionerRule; +import hudson.tasks.BatchFile; import hudson.tasks.BuildTrigger; import hudson.tasks.Shell; import hudson.triggers.SCMTrigger.SCMTriggerCause; @@ -118,6 +120,7 @@ import java.util.concurrent.atomic.AtomicInteger; import static org.hamcrest.Matchers.nullValue; import static org.junit.Assert.*; +import static org.junit.Assume.assumeFalse; /** * @author Kohsuke Kawaguchi @@ -378,7 +381,11 @@ public class QueueTest { m.addProperty(new ParametersDefinitionProperty( new StringParameterDefinition("FOO","value") )); - m.getBuildersList().add(new Shell("sleep 3")); + if (Functions.isWindows()) { + m.getBuildersList().add(new BatchFile("ping -n 3 127.0.0.1 >nul")); + } else { + m.getBuildersList().add(new Shell("sleep 3")); + } m.setAxes(new AxisList(new TextAxis("DoesntMatter", "aaa","bbb"))); List> futures = new ArrayList>(); diff --git a/test/src/test/java/hudson/model/labels/LabelExpressionTest.java b/test/src/test/java/hudson/model/labels/LabelExpressionTest.java index 057d80d994..e6a2fb45ba 100644 --- a/test/src/test/java/hudson/model/labels/LabelExpressionTest.java +++ b/test/src/test/java/hudson/model/labels/LabelExpressionTest.java @@ -24,8 +24,10 @@ package hudson.model.labels; import static org.junit.Assert.*; +import static org.junit.Assume.assumeFalse; import antlr.ANTLRException; +import hudson.Functions; import hudson.Launcher; import hudson.model.AbstractBuild; import hudson.model.AbstractProject; @@ -189,6 +191,7 @@ public class LabelExpressionTest { @Test public void dataCompatibilityWithHostNameWithWhitespace() throws Exception { + assumeFalse("Windows can't have paths with colons, skipping", Functions.isWindows()); DumbSlave slave = new DumbSlave("abc def (xyz) : test", "dummy", j.createTmpDir().getPath(), "1", Mode.NORMAL, "", j.createComputerLauncher(null), RetentionStrategy.NOOP, Collections.EMPTY_LIST); j.jenkins.addNode(slave); diff --git a/test/src/test/java/hudson/tasks/ArtifactArchiverTest.java b/test/src/test/java/hudson/tasks/ArtifactArchiverTest.java index 9ce04280ae..bd24bd1b26 100644 --- a/test/src/test/java/hudson/tasks/ArtifactArchiverTest.java +++ b/test/src/test/java/hudson/tasks/ArtifactArchiverTest.java @@ -26,6 +26,7 @@ package hudson.tasks; import hudson.AbortException; import hudson.FilePath; +import hudson.Functions; import hudson.Launcher; import hudson.Util; import hudson.model.AbstractBuild; @@ -266,7 +267,7 @@ public class ArtifactArchiverTest { @LocalData @Test public void fingerprintMigration() throws Exception { - FreeStyleProject p = j.jenkins.getItemByFullName("sample", FreeStyleProject.class); + FreeStyleProject p = j.jenkins.getItemByFullName(Functions.isWindows() ? "sample-windows" : "sample", FreeStyleProject.class); assertNotNull(p); String xml = p.getConfigFile().asString(); assertFalse(xml, xml.contains("")); diff --git a/test/src/test/java/hudson/tasks/FingerprinterTest.java b/test/src/test/java/hudson/tasks/FingerprinterTest.java index 4e2de32a92..d26ce52d1e 100644 --- a/test/src/test/java/hudson/tasks/FingerprinterTest.java +++ b/test/src/test/java/hudson/tasks/FingerprinterTest.java @@ -26,6 +26,7 @@ package hudson.tasks; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; +import hudson.Functions; import hudson.Launcher; import hudson.Util; import hudson.XmlFile; @@ -293,14 +294,18 @@ public class FingerprinterTest { @Issue("JENKINS-17125") @LocalData @Test public void actionSerialization() throws Exception { - FreeStyleProject job = j.jenkins.getItemByFullName("j", FreeStyleProject.class); + FreeStyleProject job = j.jenkins.getItemByFullName(Functions.isWindows() ? "j-windows" : "j", FreeStyleProject.class); assertNotNull(job); FreeStyleBuild build = job.getBuildByNumber(2); assertNotNull(build); Fingerprinter.FingerprintAction action = build.getAction(Fingerprinter.FingerprintAction.class); assertNotNull(action); assertEquals(build, action.getBuild()); - assertEquals("{a=2d5fac981a2e865baf0e15db655c7d63}", action.getRecords().toString()); + if (Functions.isWindows()) { + assertEquals("{a=603bc9e16cc05bdbc5e595969f42e3b8}", action.getRecords().toString()); + } else { + assertEquals("{a=2d5fac981a2e865baf0e15db655c7d63}", action.getRecords().toString()); + } j.assertBuildStatusSuccess(job.scheduleBuild2(0)); job._getRuns().purgeCache(); // force build records to be reloaded build = job.getBuildByNumber(3); @@ -309,7 +314,11 @@ public class FingerprinterTest { action = build.getAction(Fingerprinter.FingerprintAction.class); assertNotNull(action); assertEquals(build, action.getBuild()); - assertEquals("{a=f31efcf9afe30617d6c46b919e702822}", action.getRecords().toString()); + if (Functions.isWindows()) { + assertEquals("{a=a97a39fb51de0eee9fd908174dccc304}", action.getRecords().toString()); + } else { + assertEquals("{a=f31efcf9afe30617d6c46b919e702822}", action.getRecords().toString()); + } } @SuppressWarnings("unchecked") @@ -326,7 +335,8 @@ public class FingerprinterTest { j.assertBuildStatusSuccess(p2.scheduleBuild2(0)); j.assertBuildStatusSuccess(p3.scheduleBuild2(0)); - Fingerprint f = j.jenkins._getFingerprint(Util.getDigestOf(singleContents[0]+"\n")); + Fingerprint f = j.jenkins._getFingerprint(Util.getDigestOf(singleContents[0]+System.lineSeparator())); + assertNotNull(f); assertEquals(3,f.getUsages().size()); j.jenkins.rebuildDependencyGraph(); @@ -373,9 +383,15 @@ public class FingerprinterTest { StringBuilder targets = new StringBuilder(); for (int i = 0; i < contents.length; i++) { if (project instanceof MatrixProject) { - ((MatrixProject)project).getBuildersList().add(new Shell("echo " + contents[i] + " > " + files[i])); + ((MatrixProject)project).getBuildersList().add( + Functions.isWindows() + ? new BatchFile("echo " + contents[i] + "> " + files[i]) + : new Shell("echo " + contents[i] + " > " + files[i])); } else { - ((FreeStyleProject)project).getBuildersList().add(new Shell("echo " + contents[i] + " > " + files[i])); + ((FreeStyleProject)project).getBuildersList().add( + Functions.isWindows() + ? new BatchFile("echo " + contents[i] + "> " + files[i]) + : new Shell("echo " + contents[i] + " > " + files[i])); } targets.append(files[i]).append(','); diff --git a/test/src/test/java/hudson/tools/InstallerTranslatorTest.java b/test/src/test/java/hudson/tools/InstallerTranslatorTest.java index d38f780972..5319d4e406 100644 --- a/test/src/test/java/hudson/tools/InstallerTranslatorTest.java +++ b/test/src/test/java/hudson/tools/InstallerTranslatorTest.java @@ -24,6 +24,7 @@ package hudson.tools; +import hudson.Functions; import hudson.model.FreeStyleBuild; import hudson.model.FreeStyleProject; import hudson.model.JDK; @@ -32,6 +33,7 @@ import hudson.slaves.DumbSlave; import hudson.slaves.JNLPLauncher; import hudson.slaves.NodeProperty; import hudson.slaves.RetentionStrategy; +import hudson.tasks.BatchFile; import hudson.tasks.Shell; import hudson.util.StreamTaskListener; import java.nio.charset.Charset; @@ -66,38 +68,40 @@ public class InstallerTranslatorTest { @Issue("JENKINS-17667") @Test public void multipleSlavesAndTools() throws Exception { + String jdk1Path = Functions.isWindows() ? "C:\\jdk1" : "/opt/jdk1"; + String jdk2Path = Functions.isWindows() ? "C:\\jdk2" : "/opt/jdk2"; Node slave1 = r.createSlave(); Node slave2 = r.createSlave(); - JDK jdk1 = new JDK("jdk1", null, Collections.singletonList(new InstallSourceProperty(Collections.singletonList(new CommandInstaller(null, "echo installed jdk1", "/opt/jdk1"))))); - JDK jdk2 = new JDK("jdk2", null, Collections.singletonList(new InstallSourceProperty(Collections.singletonList(new CommandInstaller(null, "echo installed jdk2", "/opt/jdk2"))))); + JDK jdk1 = new JDK("jdk1", null, Collections.singletonList(new InstallSourceProperty(Collections.singletonList(Functions.isWindows() ? new BatchCommandInstaller(null, "echo installed jdk1", jdk1Path) : new CommandInstaller(null, "echo installed jdk1", jdk1Path))))); + JDK jdk2 = new JDK("jdk2", null, Collections.singletonList(new InstallSourceProperty(Collections.singletonList(Functions.isWindows() ? new BatchCommandInstaller(null, "echo installed jdk2", jdk2Path) : new CommandInstaller(null, "echo installed jdk2", jdk2Path))))); r.jenkins.getJDKs().add(jdk1); r.jenkins.getJDKs().add(jdk2); FreeStyleProject p = r.createFreeStyleProject(); p.setJDK(jdk1); - p.getBuildersList().add(new Shell("echo $JAVA_HOME")); + p.getBuildersList().add(Functions.isWindows() ? new BatchFile("echo %JAVA_HOME%") : new Shell("echo $JAVA_HOME")); p.setAssignedNode(slave1); FreeStyleBuild b1 = r.buildAndAssertSuccess(p); r.assertLogContains("installed jdk1", b1); - r.assertLogContains("/opt/jdk1", b1); + r.assertLogContains(jdk1Path, b1); p.setJDK(jdk2); FreeStyleBuild b2 = r.buildAndAssertSuccess(p); r.assertLogContains("installed jdk2", b2); - r.assertLogContains("/opt/jdk2", b2); + r.assertLogContains(jdk2Path, b2); FreeStyleBuild b3 = r.buildAndAssertSuccess(p); // An installer is run for every build, and it is up to a CommandInstaller configuration to do any up-to-date check. r.assertLogContains("installed jdk2", b3); - r.assertLogContains("/opt/jdk2", b3); + r.assertLogContains(jdk2Path, b3); p.setAssignedNode(slave2); FreeStyleBuild b4 = r.buildAndAssertSuccess(p); r.assertLogContains("installed jdk2", b4); - r.assertLogContains("/opt/jdk2", b4); + r.assertLogContains(jdk2Path, b4); p.setJDK(jdk1); FreeStyleBuild b5 = r.buildAndAssertSuccess(p); r.assertLogContains("installed jdk1", b5); - r.assertLogContains("/opt/jdk1", b5); + r.assertLogContains(jdk1Path, b5); FreeStyleBuild b6 = r.buildAndAssertSuccess(p); r.assertLogContains("installed jdk1", b6); - r.assertLogContains("/opt/jdk1", b6); + r.assertLogContains(jdk1Path, b6); } @Issue("JENKINS-26940") @@ -113,7 +117,7 @@ public class InstallerTranslatorTest { FreeStyleProject p = r.createFreeStyleProject(); p.setJDK(jdk); - p.getBuildersList().add(new Shell("echo $JAVA_HOME")); + p.getBuildersList().add(Functions.isWindows() ? new BatchFile("echo %JAVA_HOME%") : new Shell("echo $JAVA_HOME")); FreeStyleBuild b1 = r.buildAndAssertSuccess(p); r.assertLogContains(hudson.tools.Messages.CannotBeInstalled(ci.getDescriptor().getDisplayName(), jdk.getName(), r.jenkins.getDisplayName()), b1); r.assertLogContains(hudson.tools.Messages.CannotBeInstalled(bci.getDescriptor().getDisplayName(), jdk.getName(), r.jenkins.getDisplayName()), b1); @@ -122,8 +126,12 @@ public class InstallerTranslatorTest { @Issue("JENKINS-26940") @Test public void testNoMessageLoggedWhenAnyInstallerFound() throws Exception { - final CommandInstaller ci = new CommandInstaller("wrong1", "echo hello", "/opt/jdk"); - final CommandInstaller ci2 = new CommandInstaller("master", "echo hello", "/opt/jdk2"); + final AbstractCommandInstaller ci = Functions.isWindows() + ? new BatchCommandInstaller("wrong1", "echo hello", "C:\\jdk") + : new CommandInstaller("wrong1", "echo hello", "/opt/jdk"); + final AbstractCommandInstaller ci2 = Functions.isWindows() + ? new BatchCommandInstaller("master", "echo hello", "C:\\jdk2") + : new CommandInstaller("master", "echo hello", "/opt/jdk2"); InstallSourceProperty isp = new InstallSourceProperty(Arrays.asList(ci, ci2)); JDK jdk = new JDK("jdk", null, Collections.singletonList(isp)); @@ -132,7 +140,7 @@ public class InstallerTranslatorTest { FreeStyleProject p = r.createFreeStyleProject(); p.setJDK(jdk); - p.getBuildersList().add(new Shell("echo $JAVA_HOME")); + p.getBuildersList().add(Functions.isWindows() ? new BatchFile("echo %JAVA_HOME%") : new Shell("echo $JAVA_HOME")); FreeStyleBuild b1 = r.buildAndAssertSuccess(p); r.assertLogNotContains(ci.getDescriptor().getDisplayName(), b1); } diff --git a/test/src/test/java/hudson/util/ArgumentListBuilder2Test.java b/test/src/test/java/hudson/util/ArgumentListBuilder2Test.java index b5e4564b0b..c2f06e1e9c 100644 --- a/test/src/test/java/hudson/util/ArgumentListBuilder2Test.java +++ b/test/src/test/java/hudson/util/ArgumentListBuilder2Test.java @@ -28,6 +28,7 @@ import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.equalTo; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import static org.junit.Assume.assumeTrue; import hudson.Functions; import hudson.Launcher.LocalLauncher; @@ -45,6 +46,7 @@ import com.google.common.base.Joiner; import java.io.ByteArrayOutputStream; import java.io.StringWriter; +import java.net.URL; /** * @author Kohsuke Kawaguchi @@ -90,9 +92,18 @@ public class ArgumentListBuilder2Test { } public String echoArgs(String... arguments) throws Exception { - ArgumentListBuilder args = new ArgumentListBuilder(JavaEnvUtils.getJreExecutable("java"), "-cp", "target/test-classes/", "hudson.util.EchoCommand"); - args.add(arguments); - args = args.toWindowsCommand(); + String testHarnessJar = Class.forName("hudson.util.EchoCommand") + .getProtectionDomain() + .getCodeSource() + .getLocation() + .getFile() + .replaceAll("^/", ""); + + ArgumentListBuilder args = new ArgumentListBuilder( + JavaEnvUtils.getJreExecutable("java").replaceAll("^\"|\"$", ""), + "-cp", testHarnessJar, "hudson.util.EchoCommand") + .add(arguments) + .toWindowsCommand(); ByteArrayOutputStream out = new ByteArrayOutputStream(); final StreamTaskListener listener = new StreamTaskListener(out); diff --git a/test/src/test/java/jenkins/security/Security232Test.java b/test/src/test/java/jenkins/security/Security232Test.java index 6b3d8e3acf..f5a33ab6ab 100644 --- a/test/src/test/java/jenkins/security/Security232Test.java +++ b/test/src/test/java/jenkins/security/Security232Test.java @@ -170,6 +170,7 @@ public class Security232Test { long o2 = Long.parseLong(parts[ 1 ], 16); short o3 = Short.parseShort(parts[ 2 ], 16); + // Need to find Windows equivalent. exploit(new InetSocketAddress(isa.getAddress(), jrmpPort), obj, o1, o2, o3, new CommonsCollections1(), "touch " + pwned); } diff --git a/test/src/test/java/jenkins/security/security218/ysoserial/payloads/JRMPClient.java b/test/src/test/java/jenkins/security/security218/ysoserial/payloads/JRMPClient.java index a50f1fc947..e749bc9c43 100644 --- a/test/src/test/java/jenkins/security/security218/ysoserial/payloads/JRMPClient.java +++ b/test/src/test/java/jenkins/security/security218/ysoserial/payloads/JRMPClient.java @@ -79,7 +79,7 @@ public class JRMPClient extends PayloadRunner implements ObjectPayload String host; int port; int sep = command.indexOf(':'); - if ( sep < 0 ) { + if ( sep < 0 || ((sep+1) < command.length() && !Character.isDigit(command.charAt(sep+1)))) { port = new Random().nextInt(65535); host = command; } diff --git a/test/src/test/resources/hudson/model/ParametersAction2Test/backwardCompatibility.zip b/test/src/test/resources/hudson/model/ParametersAction2Test/backwardCompatibility.zip index 4148761cdd..0fe0cea6ff 100644 Binary files a/test/src/test/resources/hudson/model/ParametersAction2Test/backwardCompatibility.zip and b/test/src/test/resources/hudson/model/ParametersAction2Test/backwardCompatibility.zip differ diff --git a/test/src/test/resources/hudson/tasks/ArtifactArchiverTest/fingerprintMigration.zip b/test/src/test/resources/hudson/tasks/ArtifactArchiverTest/fingerprintMigration.zip index 206560069b..b342cc4f47 100644 Binary files a/test/src/test/resources/hudson/tasks/ArtifactArchiverTest/fingerprintMigration.zip and b/test/src/test/resources/hudson/tasks/ArtifactArchiverTest/fingerprintMigration.zip differ diff --git a/test/src/test/resources/hudson/tasks/FingerprinterTest/actionSerialization.zip b/test/src/test/resources/hudson/tasks/FingerprinterTest/actionSerialization.zip index b56ba95fac..f18392194c 100644 Binary files a/test/src/test/resources/hudson/tasks/FingerprinterTest/actionSerialization.zip and b/test/src/test/resources/hudson/tasks/FingerprinterTest/actionSerialization.zip differ