Merge branch 'master' of github.com:jenkinsci/jenkins

This commit is contained in:
Kohsuke Kawaguchi committed 2017-02-26 13:17:05 -08:00
commit c63abe3e8c
33 files changed
+468 -209

No files matched your search

Vendored
+1 -1
View File
@@ -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++) {
@@ -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);
@@ -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).
*
* <p>This can typically have a few different reasons:</p>
*
* <ul>
* <li>The date is impossible. For example, June 31 does never happen, so <tt>0 0 31 6 *</tt> will never happen</li>
* <li>The date happens only rarely
* <ul>
* <li>February 29 being the obvious one</li>
* <li>Cron tab patterns specifying all of month, day of month, and day of week can also occur so rarely to trigger this exception</li>
* </ul>
* </li>
* </ul>
*
* @see CronTab#floor(Calendar)
* @see CronTab#ceil(Calendar)
* @since TODO
*/
@Restricted(NoExternalUse.class)
public class RareOrImpossibleDateException extends RuntimeException {
}
@@ -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<BuildableItem> {
}
private void updateValidationsForNextRun(Collection<FormValidation> 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()));
}
}
}
@@ -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
@@ -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()
@@ -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", "<?xml version='1.0' encoding='UTF-8'?>\n<run>\n <stuff>ok</stuff>\n <number>99</number>\n <otherstuff>ok</otherstuff>\n</run>");
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", "<run>\n <number>98</number>\n</run>");
link("98", "2014-01-02_03-04-04");
write("99/build.xml", "<?xml version='1.0' encoding='UTF-8'?>\n<run>\n <stuff>ok</stuff>\n <timestamp>1388649845000</timestamp>\n <otherstuff>ok</otherstuff>\n</run>");
@@ -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", "<?xml version='1.0' encoding='UTF-8'?>\n<run>\n <stuff>ok</stuff>\n <id>2014-01-02_03-04-05</id>\n <timestamp>1388649845000</timestamp>\n <otherstuff>ok</otherstuff>\n</run>");
@@ -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", "<?xml version='1.0' encoding='UTF-8'?>\n<run>\n <stuff>ok</stuff>\n <timestamp>1388649845000</timestamp>\n <otherstuff>ok</otherstuff>\n</run>");
@@ -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", "<?xml version='1.0' encoding='UTF-8'?>\n<run>\n <stuff>ok</stuff>\n <timestamp>1388649845000</timestamp>\n <otherstuff>ok</otherstuff>\n</run>");
@@ -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", "<?xml version='1.0' encoding='UTF-8'?>\n<run>\n <stuff>ok</stuff>\n <timestamp>1388649845000</timestamp>\n <otherstuff>ok</otherstuff>\n</run>");
@@ -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);
@@ -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<ParameterDefinition> 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);
}
}
@@ -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 &lt;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, "<maven2-moduleset />")
@@ -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!");
@@ -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
@@ -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<UpdateSite> 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<UpdateSite> sites = r.jenkins.getUpdateCenter().getSites();
sites.clear();
URL url = PluginManagerTest.class.getResource("/plugins/upload-test-update-center.json");
@@ -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;
+4
View File
@@ -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));
@@ -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()));
}
}
@@ -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
@@ -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")));
@@ -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));
@@ -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);
}
}
@@ -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);
}
}
@@ -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");
@@ -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<FreeStyleBuild> 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);
@@ -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<Future<MatrixBuild>> futures = new ArrayList<Future<MatrixBuild>>();
@@ -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);
@@ -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("<recordBuildArtifacts>"));
@@ -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(',');
@@ -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);
}
@@ -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);
@@ -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);
}
@@ -79,7 +79,7 @@ public class JRMPClient extends PayloadRunner implements ObjectPayload<Registry>
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;
}