@Test public void blockSteps() throws Exception { st.assertRoundTrip(new ExecutorStep(null), "node {\n // some block\n}"); st.assertRoundTrip(new ExecutorStep("linux"), "node('linux') {\n // some block\n}"); st.assertRoundTrip(new WorkspaceStep(null), "ws {\n // some block\n}"); st.assertRoundTrip(new WorkspaceStep("loc"), "ws('loc') {\n // some block\n}"); }
@Issue("JENKINS-37721") @Test public void configRoundTripSCMTrigger() throws Exception { List<JobProperty> properties = Collections.<JobProperty>singletonList(new PipelineTriggersJobProperty(Collections.<Trigger>singletonList(new SCMTrigger("@daily")))); String snippetJson = "{'propertiesMap': {\n" + " 'stapler-class-bag': 'true',\n" + " 'org-jenkinsci-plugins-workflow-job-properties-PipelineTriggersJobProperty': {'triggers': {\n" + " 'stapler-class-bag': 'true',\n" + " 'hudson-triggers-SCMTrigger': {'scmpoll_spec': '@daily', 'ignorePostCommitHooks': false }\n" + " }}},\n" + " 'stapler-class': 'org.jenkinsci.plugins.workflow.multibranch.JobPropertyStep',\n" + " '$class': 'org.jenkinsci.plugins.workflow.multibranch.JobPropertyStep'}"; new SnippetizerTester(r).assertGenerateSnippet(snippetJson, "properties([pipelineTriggers([pollSCM('@daily')])])", null); new SnippetizerTester(r).assertRoundTrip(new JobPropertyStep(properties), "properties([pipelineTriggers([pollSCM('@daily')])])"); }
/** * An example of a step that will fail to generate docs correctly due to a lack of a {@link org.kohsuke.stapler.DataBoundConstructor}. */ @Test(expected = NoStaplerConstructorException.class) public void parallelStepDocs() throws Exception { SnippetizerTester.assertDocGeneration(ParallelStep.class); }
@Issue("JENKINS-37219") @Test public void snippetGeneratorOverrideIndexing() throws Exception { String snippetJson = "{'propertiesMap':\n" + "{'stapler-class-bag': 'true', 'jenkins-branch-OverrideIndexTriggersJobProperty': \n" + "{'specified': true, 'enableTriggers': true}},\n" + "'stapler-class': 'org.jenkinsci.plugins.workflow.multibranch.JobPropertyStep',\n" + "'$class': 'org.jenkinsci.plugins.workflow.multibranch.JobPropertyStep'}"; new SnippetizerTester(r).assertGenerateSnippet(snippetJson, "properties([overrideIndexTriggers(true)])", null); }
@Test public void configRoundTrip() throws Exception { SnippetizerTester st = new SnippetizerTester(rule); JUnitResultsStep step = new JUnitResultsStep("**/target/surefire-reports/TEST-*.xml"); st.assertRoundTrip(step, "junit '**/target/surefire-reports/TEST-*.xml'"); step.setAllowEmptyResults(true); st.assertRoundTrip(step, "junit allowEmptyResults: true, testResults: '**/target/surefire-reports/TEST-*.xml'"); step.setHealthScaleFactor(2.0); st.assertRoundTrip(step, "junit allowEmptyResults: true, healthScaleFactor: 2.0, testResults: '**/target/surefire-reports/TEST-*.xml'"); MockTestDataPublisher publisher = new MockTestDataPublisher("testing"); step.setTestDataPublishers(Collections.<TestDataPublisher>singletonList(publisher)); st.assertRoundTrip(step, "junit allowEmptyResults: true, healthScaleFactor: 2.0, testDataPublishers: [[$class: 'MockTestDataPublisher', name: 'testing']], testResults: '**/target/surefire-reports/TEST-*.xml'"); }
@Test public void generateSnippet() throws Exception { st.assertGenerateSnippet("{'stapler-class':'" + EchoStep.class.getName() + "', 'message':'hello world'}", "echo 'hello world'", null); st.assertGenerateSnippet("{'stapler-class':'" + Circle.class.getName() + "'}", "circle {\n // some block\n}", null); st.assertGenerateSnippet("{'stapler-class':'" + Polygon.class.getName() + "', 'n':5}", "polygon(5) {\n // some block\n}", null); st.assertGenerateSnippet("{'stapler-class':'" + CarbonMonoxide.class.getName() + "'}", "detect CO()", null); }
private static void recurseOnTypes(DescribableModel<?> model, ParameterType type) throws Exception { if (type instanceof ErrorType) { throw new Exception("could not describe " + model, ((ErrorType) type).getError()); } if (type instanceof ArrayType) { recurseOnTypes(model, ((ArrayType)type).getElementType()); } else if (type instanceof HomogeneousObjectType) { recurseOnModel(((HomogeneousObjectType) type).getSchemaType()); } else if (type instanceof HeterogeneousObjectType) { if (((HeterogeneousObjectType) type).getActualType() == Object.class) { // See html.groovy#describeType. For example, JENKINS-53917 ChoiceParameterDefinition.choices. System.err.println("Ignoring " + model.getType().getName() + " since a parameter is not enumerable"); return; } for (Map.Entry<String, DescribableModel<?>> entry : ((HeterogeneousObjectType) type).getTypes().entrySet()) { recurseOnModel(entry.getValue()); } } }
private static void recurseOnModel(DescribableModel<?> model) throws Exception { for (DescribableParameter param : model.getParameters()) { recurseOnTypes(model, param.getType()); } }
/** * Recurses through the model of a {@link Describable} class's {@link DescribableModel} and its parameters to verify that doc generation will work. * * @param describableClass * A {@link Class} implementing {@link Describable} * @throws Exception * If any errors are encountered. */ @SuppressWarnings("unchecked") public static void assertDocGeneration(Class<? extends Describable> describableClass) throws Exception { DescribableModel<?> model = DescribableModel.of(describableClass); assertNotNull(model); recurseOnModel(model); }
@Issue("JENKINS-26143") @Test public void testChoiceParameterSnippetizer() throws Exception { //new SnippetizerTester(r).assertGenerateSnippet(); new SnippetizerTester(r).assertRoundTrip(new JobPropertyStep(Arrays.asList(new ParametersDefinitionProperty(new ChoiceParameterDefinition("paramName", new String[] { "foo", "bar", "baz" }, "")))), "properties([parameters([choice(choices: ['foo', 'bar', 'baz'], description: '', name: 'paramName')])])"); }
@Test public void generateSnippetAdvancedDeprecated() throws Exception { st.assertGenerateSnippet("{'stapler-class':'" + CatchErrorStep.class.getName() + "'}", "// " + Messages.Snippetizer_this_step_should_not_normally_be_used_in() + "\ncatchError {\n // some block\n}", null); }
@Test public void basics() throws Exception { st.assertRoundTrip(new EchoStep("hello world"), "echo 'hello world'"); ReadFileStep s = new ReadFileStep("build.properties"); st.assertRoundTrip(s, "readFile 'build.properties'"); s.setEncoding("ISO-8859-1"); st.assertRoundTrip(s, "readFile encoding: 'ISO-8859-1', file: 'build.properties'"); }
@Issue("JENKINS-37477") @Test public void configRoundTripTrigger() throws Exception { List<JobProperty> properties = Collections.<JobProperty>singletonList(new PipelineTriggersJobProperty(Collections.<Trigger>singletonList(new TimerTrigger("@daily")))); String snippetJson = "{'propertiesMap': {\n" + " 'stapler-class-bag': 'true',\n" + " 'org-jenkinsci-plugins-workflow-job-properties-PipelineTriggersJobProperty': {'triggers': {\n" + " 'stapler-class-bag': 'true',\n" + " 'hudson-triggers-TimerTrigger': {'spec': '@daily'}\n" + " }}},\n" + " 'stapler-class': 'org.jenkinsci.plugins.workflow.multibranch.JobPropertyStep',\n" + " '$class': 'org.jenkinsci.plugins.workflow.multibranch.JobPropertyStep'}"; new SnippetizerTester(r).assertGenerateSnippet(snippetJson, "properties([pipelineTriggers([cron('@daily')])])", null); new SnippetizerTester(r).assertRoundTrip(new JobPropertyStep(properties), "properties([pipelineTriggers([cron('@daily')])])"); }
@SuppressWarnings("rawtypes") @Test public void configRoundTripParameters() throws Exception { List<JobProperty> properties = Collections.<JobProperty>singletonList(new ParametersDefinitionProperty(new BooleanParameterDefinition("flag", true, null))); // TODO *ParameterDefinition.description ought to be defaulted to null: new SnippetizerTester(r).assertRoundTrip(new JobPropertyStep(properties), "properties([parameters([booleanParam(defaultValue: true, name: 'flag')])])"); StepConfigTester tester = new StepConfigTester(r); properties = tester.configRoundTrip(new JobPropertyStep(properties)).getProperties(); assertEquals(1, properties.size()); ParametersDefinitionProperty pdp = getPropertyFromList(ParametersDefinitionProperty.class, properties); assertNotNull(pdp); assertEquals(1, pdp.getParameterDefinitions().size()); assertEquals(BooleanParameterDefinition.class, pdp.getParameterDefinitions().get(0).getClass()); BooleanParameterDefinition bpd = (BooleanParameterDefinition) pdp.getParameterDefinitions().get(0); assertEquals("flag", bpd.getName()); assertTrue(bpd.isDefaultValue()); List<JobProperty> emptyInput = tester.configRoundTrip(new JobPropertyStep(Collections.<JobProperty>emptyList())).getProperties(); assertEquals(Collections.emptyList(), removeTriggerProperty(emptyInput)); }
@Test public void generateSnippetForBuildTriggerNone() throws Exception { FreeStyleProject ds = r.jenkins.createProject(FreeStyleProject.class, "ds0"); FreeStyleProject us = r.jenkins.createProject(FreeStyleProject.class, "us0"); st.assertGenerateSnippet("{'stapler-class':'" + BuildTriggerStep.class.getName() + "', 'job':'ds0'}", "build 'ds0'", us.getAbsoluteUrl() + "configure"); }
@Test public void singleArgStepDocs() throws Exception { SnippetizerTester.assertDocGeneration(EchoStep.class); }
@Test public void buildTriggerStep() throws Exception { BuildTriggerStep step = new BuildTriggerStep("downstream"); st.assertRoundTrip(step, "build 'downstream'"); step.setParameters(Arrays.asList(new StringParameterValue("branch", "default"), new BooleanParameterValue("correct", true))); if (StringParameterDefinition.DescriptorImpl.class.isAnnotationPresent(Symbol.class)) { st.assertRoundTrip(step, "build job: 'downstream', parameters: [string(name: 'branch', value: 'default'), booleanParam(name: 'correct', value: true)]"); } else { // TODO 2.x delete st.assertRoundTrip(step, "build job: 'downstream', parameters: [[$class: 'StringParameterValue', name: 'branch', value: 'default'], [$class: 'BooleanParameterValue', name: 'correct', value: true]]"); } }
@Issue("JENKINS-34464") @Test public void configRoundTripReverseBuildTrigger() throws Exception { List<JobProperty> properties = Collections.<JobProperty>singletonList(new PipelineTriggersJobProperty(Collections.<Trigger>singletonList(new ReverseBuildTrigger("some-job", Result.UNSTABLE)))); String snippetJson = "{'propertiesMap': {\n" + " 'stapler-class-bag': 'true',\n" + " 'org-jenkinsci-plugins-workflow-job-properties-PipelineTriggersJobProperty': {'triggers': {\n" + " 'stapler-class-bag': 'true',\n" + " 'jenkins-triggers-ReverseBuildTrigger': { 'threshold': 'UNSTABLE', 'upstreamProjects': 'some-job'}\n" + " }}},\n" + " 'stapler-class': 'org.jenkinsci.plugins.workflow.multibranch.JobPropertyStep',\n" + " '$class': 'org.jenkinsci.plugins.workflow.multibranch.JobPropertyStep'}"; new SnippetizerTester(r).assertGenerateSnippet(snippetJson, "properties([pipelineTriggers([upstream(threshold: 'UNSTABLE', upstreamProjects: 'some-job')])])", null); new SnippetizerTester(r).assertRoundTrip(new JobPropertyStep(properties), "properties([pipelineTriggers([upstream(threshold: 'UNSTABLE', upstreamProjects: 'some-job')])])"); }
@SuppressWarnings("rawtypes") @Test public void configRoundTripBuildDiscarder() throws Exception { List<JobProperty> properties = Collections.<JobProperty>singletonList(new BuildDiscarderProperty(new LogRotator(1, 2, -1, 3))); // TODO structural form of LogRotator is awful; confusion between integer and string types, and failure to handle default values: new SnippetizerTester(r).assertRoundTrip(new JobPropertyStep(properties), "properties([buildDiscarder(logRotator(artifactDaysToKeepStr: '', artifactNumToKeepStr: '3', daysToKeepStr: '1', numToKeepStr: '2'))])"); StepConfigTester tester = new StepConfigTester(r); properties = tester.configRoundTrip(new JobPropertyStep(properties)).getProperties(); assertEquals(1, properties.size()); BuildDiscarderProperty bdp = getPropertyFromList(BuildDiscarderProperty.class, properties); assertNotNull(bdp); BuildDiscarder strategy = bdp.getStrategy(); assertNotNull(strategy); assertEquals(LogRotator.class, strategy.getClass()); LogRotator lr = (LogRotator) strategy; assertEquals(1, lr.getDaysToKeep()); assertEquals(2, lr.getNumToKeep()); assertEquals(-1, lr.getArtifactDaysToKeep()); assertEquals(3, lr.getArtifactNumToKeep()); }
@Issue("JENKINS-29739") @Test public void generateSnippetForBuildTriggerSingle() throws Exception { FreeStyleProject ds = r.jenkins.createProject(FreeStyleProject.class, "ds1"); FreeStyleProject us = r.jenkins.createProject(FreeStyleProject.class, "us1"); ds.addProperty(new ParametersDefinitionProperty(new StringParameterDefinition("key", ""))); String snippet; if (StringParameterDefinition.DescriptorImpl.class.isAnnotationPresent(Symbol.class)) { snippet = "build job: 'ds1', parameters: [string(name: 'key', value: 'stuff')]"; } else { // TODO 2.x delete snippet = "build job: 'ds1', parameters: [[$class: 'StringParameterValue', name: 'key', value: 'stuff']]"; } st.assertGenerateSnippet("{'stapler-class':'" + BuildTriggerStep.class.getName() + "', 'job':'ds1', 'parameter': {'name':'key', 'value':'stuff'}}", snippet, us.getAbsoluteUrl() + "configure"); }