Skip to content

Commit

Permalink
[JENKINS-45047] Support for plugin-to-plugin integration tests (#336)
Browse files Browse the repository at this point in the history
Co-authored-by: Jesse Glick <jglick@cloudbees.com>
  • Loading branch information
basil and jglick authored Jul 25, 2022
1 parent 8a27d4b commit 7fdf067
Show file tree
Hide file tree
Showing 17 changed files with 1,215 additions and 9 deletions.
16 changes: 16 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
<maven.version>3.8.6</maven.version>
<maven-plugin-tools.version>3.6.4</maven-plugin-tools.version>
<plexus-containers.version>2.1.1</plexus-containers.version>
<aether.version>1.1.0</aether.version>
<spotbugs.excludeFilterFile>${project.basedir}/src/spotbugs/spotbugs-excludes.xml</spotbugs.excludeFilterFile>
</properties>

Expand Down Expand Up @@ -92,6 +93,16 @@
<artifactId>aether-api</artifactId>
<version>${aether.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.aether</groupId>
<artifactId>aether-impl</artifactId>
<version>${aether.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.aether</groupId>
<artifactId>aether-spi</artifactId>
<version>${aether.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.aether</groupId>
<artifactId>aether-util</artifactId>
Expand Down Expand Up @@ -153,6 +164,11 @@
<artifactId>maven-artifact-transfer</artifactId>
<version>0.13.1</version>
</dependency>
<dependency>
<groupId>org.apache.maven.shared</groupId>
<artifactId>maven-dependency-tree</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-component-annotations</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
invoker.goals=-ntp -DoverrideVersions=org.jenkins-ci.plugins.workflow:workflow-step-api:2.11 deploy
invoker.buildResult = failure
25 changes: 25 additions & 0 deletions src/it/override-test-dependencies-release-failure/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>plugin</artifactId>
<version>4.40</version>
<relativePath />
</parent>
<artifactId>check-core-version-failure</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>hpi</packaging>
<properties>
<jenkins.version>2.249.1</jenkins.version>
<hpi-plugin.version>@project.version@</hpi-plugin.version>
</properties>
<dependencies>
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>jackson2-api</artifactId>
<version>2.13.2-260.v43d711474c77</version>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
package org.jenkinsci.tools.hpi.its;

import com.fasterxml.jackson.databind.ObjectMapper;
import hudson.Launcher;
import hudson.Extension;
import hudson.util.FormValidation;
import hudson.model.AbstractBuild;
import hudson.model.BuildListener;
import hudson.model.AbstractProject;
import hudson.tasks.Builder;
import hudson.tasks.BuildStepDescriptor;
import java.lang.RuntimeException;
import net.sf.json.JSONObject;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.QueryParameter;

import javax.servlet.ServletException;
import java.io.IOException;

/**
* Sample {@link Builder}.
*
* <p>
* When the user configures the project and enables this builder,
* {@link org.jenkins.HelloWorldBuilder.DescriptorImpl#newInstance(StaplerRequest)} is invoked
* and a new {@link org.jenkins.HelloWorldBuilder} is created. The created
* instance is persisted to the project configuration XML by using
* XStream, so this allows you to use instance fields (like {@link #name})
* to remember the configuration.
*
* <p>
* When a build is performed, the {@link #perform(AbstractBuild, Launcher, BuildListener)} method
* will be invoked.
*
* @author Kohsuke Kawaguchi
*/
public class HelloWorldBuilder extends Builder {

private final String name;

// Fields in config.jelly must match the parameter names in the "DataBoundConstructor"
@DataBoundConstructor
public HelloWorldBuilder(String name) {
this.name = name;
}

/**
* We'll use this from the {@code config.jelly}.
*/
public String getName() {
return name;
}

@Override
public boolean perform(AbstractBuild build, Launcher launcher, BuildListener listener) {
// this is where you 'build' the project
// since this is a dummy, we just say 'hello world' and call that a build

// this also shows how you can consult the global configuration of the builder
if (getDescriptor().useFrench())
listener.getLogger().println("Bonjour, " + name + "!");
else
listener.getLogger().println("Hello, " + name + "!");
return true;
}

// overrided for better type safety.
// if your plugin doesn't really define any property on Descriptor,
// you don't have to do this.
@Override
public DescriptorImpl getDescriptor() {
return (DescriptorImpl) super.getDescriptor();
}

/**
* Descriptor for {@link org.jenkins.HelloWorldBuilder}. Used as a singleton.
* The class is marked as public so that it can be accessed from views.
*
* <p>
* See {@code views/hudson/plugins/hello_world/HelloWorldBuilder/*.jelly}
* for the actual HTML fragment for the configuration screen.
*/
@Extension // this marker indicates Hudson that this is an implementation of an extension point.
public static final class DescriptorImpl extends BuildStepDescriptor<Builder> {
/**
* To persist global configuration information,
* simply store it in a field and call save().
*
* <p>
* If you don't want fields to be persisted, use {@code transient}.
*/
private boolean useFrench;

/**
* Performs on-the-fly validation of the form field 'name'.
*
* @param value This parameter receives the value that the user has typed.
* @return Indicates the outcome of the validation. This is sent to the browser.
*/
public FormValidation doCheckName(@QueryParameter String value) throws IOException, ServletException {
if (value.length() == 0)
return FormValidation.error("Please set a name");
if (value.length() < 4)
return FormValidation.warning("Isn't the name too short?");
return FormValidation.ok();
}

public boolean isApplicable(Class<? extends AbstractProject> aClass) {
// indicates that this builder can be used with all kinds of project types
return true;
}

/**
* This human readable name is used in the configuration screen.
*/
public String getDisplayName() {
try {
return new ObjectMapper().writeValueAsString("Say hello world");
} catch (Exception e) {
throw new RuntimeException(e);
}
}

@Override
public boolean configure(StaplerRequest req, JSONObject formData) throws FormException {
// To persist global configuration information,
// set that to properties and call save().
useFrench = formData.getBoolean("useFrench");
// ^Can also use req.bindJSON(this, formData);
// (easier when there are many fields; need set* methods for this, like setUseFrench)
save();
return super.configure(req, formData);
}

/**
* This method returns true if the global configuration says we should speak French.
*/
public boolean useFrench() {
return useFrench;
}
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
assert new File(basedir, 'build.log').getText('UTF-8').contains('Cannot override dependencies when doing a release')

return true
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
invoker.goals=-ntp test
68 changes: 68 additions & 0 deletions src/it/override-test-dependencies-smokes/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>plugin</artifactId>
<version>4.40</version>
<relativePath/>
</parent>
<groupId>org.jenkins-ci.tools.hpi.its</groupId>
<artifactId>override-test-dependencies-smokes</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>hpi</packaging>
<properties>
<jenkins.version>2.249</jenkins.version>
<hpi-plugin.version>@project.version@</hpi-plugin.version>
<!-- TODO cannot include `invoker.goals=-DoverrideVersions=…,… test` in invoker.properties since then that is misinterpreted as multiple arguments for invoker.goals -->
<overrideVersions>org.jenkins-ci.plugins.workflow:workflow-step-api:2.11,org.jenkins-ci.plugins.workflow:workflow-api:2.17,org.jenkins-ci.plugins.workflow:workflow-cps:2.32</overrideVersions>
<test>SampleTest</test>
<maven.test.redirectTestOutputToFile>false</maven.test.redirectTestOutputToFile>
<surefire.rerunFailingTestsCount>0</surefire.rerunFailingTestsCount>
<workflow-step-api-plugin.version>2.9</workflow-step-api-plugin.version>
</properties>
<repositories>
<repository>
<id>repo.jenkins-ci.org</id>
<url>https://repo.jenkins-ci.org/public/</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>repo.jenkins-ci.org</id>
<url>https://repo.jenkins-ci.org/public/</url>
</pluginRepository>
</pluginRepositories>
<dependencies>
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>structs</artifactId>
<version>1.6</version>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-step-api</artifactId>
<version>${workflow-step-api-plugin.version}</version>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-step-api</artifactId>
<version>${workflow-step-api-plugin.version}</version>
<classifier>tests</classifier>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-cps</artifactId>
<version>2.30</version>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>antlr</groupId>
<artifactId>antlr</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?jelly escape-by-default='true'?>
<div/>
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package test;

import com.google.common.collect.ImmutableMap;
import hudson.remoting.Which;
import java.io.InputStream;
import java.net.URL;
import java.util.Enumeration;
import java.util.Map;
import java.util.jar.Manifest;
import org.jenkinsci.plugins.workflow.steps.StepConfigTester;
import org.junit.Test;
import static org.junit.Assert.*;
import org.junit.Rule;
import org.jvnet.hudson.test.JenkinsRule;

public class SampleTest {

@Rule
public JenkinsRule r = new JenkinsRule();

@Test
public void smokes() throws Exception {
Map<String, String> expectedVersions = ImmutableMap.of("workflow-step-api", "2.11", "workflow-api", "2.17", "workflow-cps", "2.32");
Enumeration<URL> manifests = SampleTest.class.getClassLoader().getResources("META-INF/MANIFEST.MF");
while (manifests.hasMoreElements()) {
URL url = manifests.nextElement();
try (InputStream is = url.openStream()) {
Manifest mf = new Manifest(is);
String pluginName = mf.getMainAttributes().getValue("Short-Name");
String expectedVersion = expectedVersions.get(pluginName);
if (expectedVersion != null) {
assertEquals("wrong version for " + pluginName + " as classpath entry", expectedVersion, mf.getMainAttributes().getValue("Plugin-Version"));
}
}
}
for (Map.Entry<String, String> entry : expectedVersions.entrySet()) {
assertEquals("wrong version for " + entry.getKey() + " as plugin", entry.getValue(), r.jenkins.pluginManager.getPlugin(entry.getKey()).getVersion());
}
assertEquals("workflow-step-api-2.11-tests.jar", Which.jarFile(StepConfigTester.class).getName());
}

}
3 changes: 3 additions & 0 deletions src/it/override-test-dependencies-smokes/verify.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
def log = new File(basedir, 'build.log').text
// TODO add anything needed, or delete this file
true
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
invoker.goals=-ntp test
Loading

0 comments on commit 7fdf067

Please sign in to comment.