/*
* The MIT License
*
* Copyright 2016 Red Hat, 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.cli;
import hudson.Extension;
import hudson.model.AbstractBuild;
import hudson.model.FreeStyleProject;
import hudson.model.Job;
import jenkins.model.Jenkins;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Test;
import org.jvnet.hudson.test.JenkinsRule;
import java.io.IOException;
import java.util.List;
import static hudson.cli.CLICommandInvoker.Matcher.failedWith;
import static hudson.cli.CLICommandInvoker.Matcher.hasNoStandardOutput;
import static hudson.cli.CLICommandInvoker.Matcher.succeeded;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.not;
/**
* @author pjanouse
*/
public class AbstractBuildRangeCommandTest {
private static CLICommandInvoker command = null;
private static FreeStyleProject project = null;
private static final String PROJECT_NAME = "aProject";
private static final int BUILDS = 10;
private static final int[] deleted = {5,8,9};
@ClassRule public static final JenkinsRule j = new JenkinsRule();
@BeforeClass public static void setUpClass() throws Exception {
command = new CLICommandInvoker(j, new DummyRangeCommand());
project = j.createFreeStyleProject(PROJECT_NAME);
for (int i=0; i<BUILDS; i++) {
assertThat(project.scheduleBuild2(0).get(), not(equalTo(null)));
}
assertThat(((FreeStyleProject) j.jenkins.getItem("aProject")).getBuilds().size(),
equalTo(BUILDS));
for (int i : deleted) {
project.getBuildByNumber(i).delete();
assertThat(project.getBuildByNumber(i), equalTo(null));
}
}
@Test public void dummyRangeShouldFailWithoutJobReadPermission() throws Exception {
final CLICommandInvoker.Result result = command
.authorizedTo(Jenkins.READ)
.invokeWithArgs(PROJECT_NAME, "1");
assertThat(result, failedWith(3));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(),
containsString(String.format("ERROR: No such job '%s'", PROJECT_NAME)));
}
@Test public void dummyRangeShouldFailIfJobDesNotExist() throws Exception {
final CLICommandInvoker.Result result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs("never_created", "1");
assertThat(result, failedWith(3));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: No such job 'never_created'"));
}
@Test public void dummyRangeShouldFailIfJobNameIsEmpty() throws Exception {
final CLICommandInvoker.Result result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs("", "1");
assertThat(result, failedWith(3));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(),
containsString(String.format("ERROR: No such job ''; perhaps you meant '%s'?", PROJECT_NAME)));
}
@Test public void dummyRangeShouldFailIfJobNameIsSpace() throws Exception {
final CLICommandInvoker.Result result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(" ", "1");
assertThat(result, failedWith(3));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(),
containsString(String.format("ERROR: No such job ' '; perhaps you meant '%s'?", PROJECT_NAME)));
}
@Test public void dummyRangeShouldSuccessIfBuildDoesNotExist() throws Exception {
CLICommandInvoker.Result result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, String.valueOf(BUILDS+1));
assertThat(result, succeeded());
assertThat(result.stdout(), containsString("Builds: \n"));
result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, String.valueOf(deleted[0]));
assertThat(result, succeeded());
assertThat(result.stdout(), containsString("Builds: \n"));
}
@Test public void dummyRangeNumberSingleShouldSuccess() throws Exception {
// First
CLICommandInvoker.Result result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "1");
assertThat(result, succeeded());
assertThat(result.stdout(), containsString("Builds: 1\n"));
// 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"));
// In the middle
result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "10");
assertThat(result, succeeded());
assertThat(result.stdout(), containsString("Builds: 10\n"));
// 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"));
// Last
result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, String.valueOf(BUILDS));
assertThat(result, succeeded());
assertThat(result.stdout(),
containsString(String.format("Builds: %s\n", String.valueOf(BUILDS))));
// Last with the plus symbol '+'
result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, '+' + String.valueOf(BUILDS));
assertThat(result, succeeded());
assertThat(result.stdout(),
containsString(String.format("Builds: %s\n", String.valueOf(BUILDS))));
}
@Test public void dummyRangeNumberSingleShouldSuccessIfBuildNumberIsZero() throws Exception {
CLICommandInvoker.Result result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "0");
assertThat(result, succeeded());
assertThat(result.stdout(), containsString("Builds: \n"));
result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "+0");
assertThat(result, succeeded());
assertThat(result.stdout(), containsString("Builds: \n"));
}
@Test public void dummyRangeNumberSingleShouldFailIfBuildNumberIsNegative() throws Exception {
final CLICommandInvoker.Result result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "-1");
assertThat(result, failedWith(2));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: \"-1\" is not a valid option"));
}
@Test public void dummyRangeNumberSingleShouldFailIfBuildNumberIsTooBig() throws Exception {
final CLICommandInvoker.Result result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "2147483648");
assertThat(result, failedWith(3));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: Unable to parse '2147483648', expected number"));
}
@Test public void dummyRangeNumberSingleShouldFailIfBuildNumberIsInvalid() throws Exception {
CLICommandInvoker.Result result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "1a");
assertThat(result, failedWith(3));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: Unable to parse '1a', expected number"));
result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "aa");
assertThat(result, failedWith(3));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: Unable to parse 'aa', expected number"));
}
@Test public void dummyRangeNumberSingleShouldSuccessIfBuildNumberIsEmpty() throws Exception {
final CLICommandInvoker.Result result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "");
assertThat(result, succeeded());
assertThat(result.stdout(), containsString("Builds: \n"));
}
@Test public void dummyRangeNumberSingleShouldFailIfBuildNumberIsSpace() throws Exception {
final CLICommandInvoker.Result result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, " ");
assertThat(result, failedWith(3));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: Unable to parse ' ', expected number"));
}
@Test public void dummyRangeNumberSingleShouldSuccessIfBuildNumberIsComma() throws Exception {
final CLICommandInvoker.Result result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, ",");
assertThat(result, succeeded());
assertThat(result.stdout(), containsString("Builds: \n"));
}
@Test public void dummyRangeNumberSingleShouldFailIfBuildNumberIsHyphen() throws Exception {
final CLICommandInvoker.Result result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "-");
assertThat(result, failedWith(2));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: \"-\" is not a valid option"));
}
@Test public void dummyRangeNumberMultiShouldSuccess() throws Exception {
CLICommandInvoker.Result result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "1,2");
assertThat(result, succeeded());
assertThat(result.stdout(), containsString("Builds: 1,2\n"));
// 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"));
// 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"));
// 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"));
result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "1,0,2");
assertThat(result, succeeded());
assertThat(result.stdout(), containsString("Builds: 1,2\n"));
result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "1,2,0");
assertThat(result, succeeded());
assertThat(result.stdout(), containsString("Builds: 1,2\n"));
}
@Test public void dummyRangeNumberMultiShouldSuccessIfSomeBuildDoesNotExist() throws Exception {
CLICommandInvoker.Result result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "1,2,"+deleted[0]);
assertThat(result, succeeded());
assertThat(result.stdout(), containsString("Builds: 1,2\n"));
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)));
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)));
}
@Test public void dummyRangeNumberMultiShouldFailIfBuildNumberIsNegative() throws Exception {
CLICommandInvoker.Result result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "-1,2,3");
assertThat(result, failedWith(2));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: \"-1,2,3\" is not a valid option"));
result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "1,-2,3");
assertThat(result, failedWith(3));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: Unable to parse \'1,-2,3\', expected string with a range M-N"));
result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "1,2,-3");
assertThat(result, failedWith(3));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: Unable to parse \'1,2,-3\', expected string with a range M-N"));
}
@Test public void dummyRangeNumberMultiShouldFailIfBuildNumberIsTooBig() throws Exception {
CLICommandInvoker.Result result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "2147483648,2,3");
assertThat(result, failedWith(3));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: Unable to parse '2147483648,2,3', expected number"));
result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "1,2147483648,3");
assertThat(result, failedWith(3));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: Unable to parse '1,2147483648,3', expected number"));
result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "1,2,2147483648");
assertThat(result, failedWith(3));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: Unable to parse '1,2,2147483648', expected number"));
}
@Test public void dummyRangeNumberMultiShouldFailIfBuildNumberIsInvalid() throws Exception {
CLICommandInvoker.Result result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "1a,2,3");
assertThat(result, failedWith(3));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: Unable to parse '1a,2,3', expected number"));
result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "aa,2,3");
assertThat(result, failedWith(3));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: Unable to parse 'aa,2,3', expected number"));
result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "1,2a,3");
assertThat(result, failedWith(3));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: Unable to parse '1,2a,3', expected number"));
result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "1,aa,3");
assertThat(result, failedWith(3));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: Unable to parse '1,aa,3', expected number"));
result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "1,2,3a");
assertThat(result, failedWith(3));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: Unable to parse '1,2,3a', expected number"));
result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "1,2,aa");
assertThat(result, failedWith(3));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: Unable to parse '1,2,aa', expected number"));
}
@Test public void dummyRangeNumberMultiShouldFailIfBuildNumberIsEmpty() throws Exception {
CLICommandInvoker.Result result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, ",2,3");
assertThat(result, failedWith(3));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: Unable to parse ',2,3', expected correct notation M,N or M-N"));
result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "1,,3");
assertThat(result, failedWith(3));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: Unable to parse '1,,3', expected correct notation M,N or M-N"));
result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "1,2,");
assertThat(result, failedWith(3));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: Unable to parse '1,2,', expected correct notation M,N or M-N"));
}
@Test public void dummyRangeNumberMultiShouldFailIfBuildNumberIsSpace() throws Exception {
CLICommandInvoker.Result result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, " ,2,3");
assertThat(result, failedWith(3));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: Unable to parse ' ,2,3', expected number"));
result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "1, ,3");
assertThat(result, failedWith(3));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: Unable to parse '1, ,3', expected number"));
result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "1,2, ");
assertThat(result, failedWith(3));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: Unable to parse '1,2, ', expected number"));
}
@Test public void dummyRangeNumberMultiShouldFailIfBuildNumberIsComma() throws Exception {
CLICommandInvoker.Result result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, ",,2,3");
assertThat(result, failedWith(3));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: Unable to parse ',,2,3', expected correct notation M,N or M-N"));
result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "1,,,3");
assertThat(result, failedWith(3));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: Unable to parse '1,,,3', expected correct notation M,N or M-N"));
result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "1,2,,");
assertThat(result, failedWith(3));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: Unable to parse '1,2,,', expected correct notation M,N or M-N"));
}
@Test public void dummyRangeNumberMultiShouldFailIfBuildNumberIsHyphen() throws Exception {
CLICommandInvoker.Result result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "-,2,3");
assertThat(result, failedWith(2));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: \"-,2,3\" is not a valid option"));
result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "1,-,3");
assertThat(result, failedWith(3));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: Unable to parse '1,-,3', expected string with a range M-N"));
result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "1,2,-");
assertThat(result, failedWith(3));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: Unable to parse '1,2,-', expected string with a range M-N"));
}
@Test public void dummyRangeRangeSingleShouldSuccess() throws Exception {
CLICommandInvoker.Result result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "1-2");
assertThat(result, succeeded());
assertThat(result.stdout(), containsString("Builds: 1,2\n"));
result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "+1-+2");
assertThat(result, succeeded());
assertThat(result.stdout(), containsString("Builds: 1,2\n"));
result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "1-1");
assertThat(result, succeeded());
assertThat(result.stdout(), containsString("Builds: 1\n"));
result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "+1-+1");
assertThat(result, succeeded());
assertThat(result.stdout(), containsString("Builds: 1\n"));
result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "1-"+deleted[0]);
assertThat(result, succeeded());
String builds = "";
boolean next = false;
for (int i = 1; i < deleted[0]; i++) {
if (next)
builds += ",";
builds += i;
next = true;
}
assertThat(result.stdout(), containsString("Builds: "+builds+"\n"));
result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "+1-+"+deleted[0]);
assertThat(result, succeeded());
assertThat(result.stdout(), containsString("Builds: "+builds+"\n"));
result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "0-1");
assertThat(result, succeeded());
assertThat(result.stdout(), containsString("Builds: 1\n"));
result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "+0-+1");
assertThat(result, succeeded());
assertThat(result.stdout(), containsString("Builds: 1\n"));
result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "0-2");
assertThat(result, succeeded());
assertThat(result.stdout(), containsString("Builds: 1,2\n"));
result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "+0-+2");
assertThat(result, succeeded());
assertThat(result.stdout(), containsString("Builds: 1,2\n"));
result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "0-0");
assertThat(result, succeeded());
assertThat(result.stdout(), containsString("Builds: \n"));
result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "+0-+0");
assertThat(result, succeeded());
assertThat(result.stdout(), containsString("Builds: \n"));
}
@Test public void dummyRangeRangeSingleShouldSuccessIfSomeBuildDoesNotExist() throws Exception {
CLICommandInvoker.Result result = command
.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)));
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)));
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)));
}
@Test public void dummyRangeRangeSingleShouldFailIfBuildRangeContainsZeroAndNegative() throws Exception {
CLICommandInvoker.Result result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "0--1");
assertThat(result, failedWith(3));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: Unable to parse '0--1', expected correct notation M,N or M-N"));
result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "+0--1");
assertThat(result, failedWith(3));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: Unable to parse '+0--1', expected correct notation M,N or M-N"));
result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "0--2");
assertThat(result, failedWith(3));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: Unable to parse '0--2', expected correct notation M,N or M-N"));
result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "+0--2");
assertThat(result, failedWith(3));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: Unable to parse '+0--2', expected correct notation M,N or M-N"));
result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "1-0");
assertThat(result, failedWith(3));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: Unable to parse '1-0', expected string with a range M-N where M<N"));
result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "+1-+0");
assertThat(result, failedWith(3));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: Unable to parse '+1-+0', expected string with a range M-N where M<N"));
result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "2-0");
assertThat(result, failedWith(3));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: Unable to parse '2-0', expected string with a range M-N where M<N"));
result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "+2-+0");
assertThat(result, failedWith(3));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: Unable to parse '+2-+0', expected string with a range M-N where M<N"));
result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "-1-0");
assertThat(result, failedWith(2));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: \"-1-0\" is not a valid option"));
result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "-1-+0");
assertThat(result, failedWith(2));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: \"-1-+0\" is not a valid option"));
result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "-2-0");
assertThat(result, failedWith(2));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: \"-2-0\" is not a valid option"));
result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "-2-+0");
assertThat(result, failedWith(2));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: \"-2-+0\" is not a valid option"));
}
@Test public void dummyRangeRangeSingleShouldFailIfBuildRangeContainsANegativeNumber() throws Exception {
CLICommandInvoker.Result result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "-1-1");
assertThat(result, failedWith(2));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: \"-1-1\" is not a valid option"));
result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "-1-+1");
assertThat(result, failedWith(2));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: \"-1-+1\" is not a valid option"));
result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "-1-2");
assertThat(result, failedWith(2));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: \"-1-2\" is not a valid option"));
result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "-1-+2");
assertThat(result, failedWith(2));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: \"-1-+2\" is not a valid option"));
result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "1--1");
assertThat(result, failedWith(3));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: Unable to parse '1--1', expected correct notation M,N or M-N"));
result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "+1--1");
assertThat(result, failedWith(3));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: Unable to parse '+1--1', expected correct notation M,N or M-N"));
result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "1--2");
assertThat(result, failedWith(3));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: Unable to parse '1--2', expected correct notation M,N or M-N"));
result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "+1--2");
assertThat(result, failedWith(3));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: Unable to parse '+1--2', expected correct notation M,N or M-N"));
result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "-1--1");
assertThat(result, failedWith(2));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: \"-1--1\" is not a valid option"));
result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "-2--1");
assertThat(result, failedWith(2));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: \"-2--1\" is not a valid option"));
}
@Test public void dummyRangeRangeSingleShouldFailIfBuildRangeContainsTooBigNumber() throws Exception {
CLICommandInvoker.Result result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "1-2147483648");
assertThat(result, failedWith(3));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: Unable to parse '1-2147483648', expected number"));
result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "2147483648-1");
assertThat(result, failedWith(3));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: Unable to parse '2147483648-1', expected number"));
result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "2147483648-2147483648");
assertThat(result, failedWith(3));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: Unable to parse '2147483648-2147483648', expected number"));
}
@Test public void dummyRangeRangeSingleShouldFailIfBuildRangeContainsInvalidNumber() throws Exception {
CLICommandInvoker.Result result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "1-2a");
assertThat(result, failedWith(3));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: Unable to parse '1-2a', expected number"));
result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "1-aa");
assertThat(result, failedWith(3));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: Unable to parse '1-aa', expected number"));
result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "2a-2");
assertThat(result, failedWith(3));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: Unable to parse '2a-2', expected number"));
result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "aa-2");
assertThat(result, failedWith(3));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: Unable to parse 'aa-2', expected number"));
result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "2a-2a");
assertThat(result, failedWith(3));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: Unable to parse '2a-2a', expected number"));
result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "aa-aa");
assertThat(result, failedWith(3));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: Unable to parse 'aa-aa', expected number"));
}
@Test public void dummyRangeRangeSingleShouldFailIfBuildRangeContainsEmptyNumber() throws Exception {
CLICommandInvoker.Result result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "-1");
assertThat(result, failedWith(2));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: \"-1\" is not a valid option"));
result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "1-");
assertThat(result, failedWith(3));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: Unable to parse '1-', expected string with a range M-N"));
result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "-");
assertThat(result, failedWith(2));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: \"-\" is not a valid option"));
}
@Test public void dummyRangeRangeSingleShouldFailIfBuildRangeContainsSpace() throws Exception {
CLICommandInvoker.Result result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, " -1");
assertThat(result, failedWith(3));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: Unable to parse ' -1', expected string with a range M-N"));
result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "1- ");
assertThat(result, failedWith(3));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: Unable to parse '1- ', expected string with a range M-N"));
result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, " - ");
assertThat(result, failedWith(3));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: Unable to parse ' - ', expected string with a range M-N"));
}
@Test public void dummyRangeRangeSingleShouldFailIfBuildRangeContainsComma() throws Exception {
CLICommandInvoker.Result result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, ",-1");
assertThat(result, failedWith(3));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: Unable to parse ',-1', expected string with a range M-N"));
result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "1-,");
assertThat(result, failedWith(3));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: Unable to parse '1-,', expected string with a range M-N"));
result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, ",-,");
assertThat(result, failedWith(3));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: Unable to parse ',-,', expected string with a range M-N"));
}
@Test public void dummyRangeRangeSingleShouldFailIfBuildRangeContainsHyphen() throws Exception {
CLICommandInvoker.Result result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "--1");
assertThat(result, failedWith(2));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: \"--1\" is not a valid option"));
result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "1--");
assertThat(result, failedWith(3));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: Unable to parse '1--', expected correct notation M,N or M-N"));
result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "---");
assertThat(result, failedWith(2));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: \"---\" is not a valid option"));
}
@Test public void dummyRangeRangeSingleShouldFailIfBuildRangeIsInverse() throws Exception {
CLICommandInvoker.Result result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "2-1");
assertThat(result, failedWith(3));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: Unable to parse '2-1', expected string with a range M-N where M<N"));
result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "10-1");
assertThat(result, failedWith(3));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: Unable to parse '10-1', expected string with a range M-N where M<N"));
result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "-1--2");
assertThat(result, failedWith(2));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: \"-1--2\" is not a valid option"));
}
@Test public void dummyRangeRangeSingleShouldFailIfBuildRangeIsInvalid() throws Exception {
final CLICommandInvoker.Result result = command
.authorizedTo(Jenkins.READ, Job.READ)
.invokeWithArgs(PROJECT_NAME, "1-3-");
assertThat(result, failedWith(3));
assertThat(result, hasNoStandardOutput());
assertThat(result.stderr(), containsString("ERROR: Unable to parse '1-3-', expected correct notation M,N or M-N"));
}
@Test public void dummyRangeRangeMultiShouldSuccess() throws Exception {
CLICommandInvoker.Result result = command
.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"));
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"));
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"));
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"));
}
@Extension
public static class DummyRangeCommand extends AbstractBuildRangeCommand {
@Override
public String getShortDescription() {
return "DummyRangeCommand";
}
@Override
protected int act(List<AbstractBuild<?, ?>> builds) throws IOException {
boolean comma = false;
stdout.print("Builds: ");
for (AbstractBuild build : builds) {
if (comma)
stdout.print(",");
else
comma = true;
stdout.print(build.getNumber());
}
stdout.println("");
return 0;
}
}
}