package net.serenitybdd.integration.jenkins; import com.beust.jcommander.internal.Lists; import net.serenitybdd.integration.jenkins.client.JenkinsClient; import net.serenitybdd.integration.jenkins.environment.PluginDescription; import net.serenitybdd.integration.jenkins.environment.rules.ApplicativeTestRule; import net.serenitybdd.integration.jenkins.environment.rules.InstallPlugins; import net.serenitybdd.integration.jenkins.environment.rules.ManageJenkinsServer; import net.serenitybdd.integration.utils.RuleChains; import org.junit.rules.RuleChain; import org.junit.rules.TestRule; import org.junit.runner.Description; import org.junit.runners.model.Statement; import java.net.MalformedURLException; import java.net.URL; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; import static com.google.common.collect.ImmutableList.copyOf; import static java.lang.String.format; import static java.util.Arrays.asList; import static net.serenitybdd.integration.utils.ListFunctions.concat; public class JenkinsInstance implements TestRule { private final PluginDescription pluginUnderTest; private Path jenkinsHome = Paths.get(System.getProperty("java.io.tmpdir")); private int portNumber = 8080; private JenkinsClient client = null; // instantiated when the Jenkins server is up and running private List<? extends ApplicativeTestRule<JenkinsInstance>> customRulesToApplyBeforeStart = Lists.newArrayList(); private List<? extends ApplicativeTestRule<JenkinsInstance>> defaultRules; private List<? extends ApplicativeTestRule<JenkinsInstance>> customRulesToApplyAfterStart = Lists.newArrayList(); /** * @param pluginUnderTest * Path to the plugin under test, either a .hpi or a .jpi file */ public JenkinsInstance(Path pluginUnderTest) { this(PluginDescription.of(pluginUnderTest)); } /** * @param description * Plugin meta-data derived from the manifest file packaged with the plugin */ public JenkinsInstance(PluginDescription description) { this.pluginUnderTest = description; defaultRules = asList( InstallPlugins.fromDisk(pluginUnderTest.path()), new ManageJenkinsServer() ); } public String pluginUnderTestName() { return pluginUnderTest.fullName(); } public String pluginUnderTestVersion() { return pluginUnderTest.version(); } public String version() { return pluginUnderTest.requiredJenkinsVersion(); } public Path home() { return this.jenkinsHome; } public void setHome(Path jenkinsHome) { this.jenkinsHome = jenkinsHome; } public JenkinsClient client() { return client; } public void setClient(JenkinsClient client) { this.client = client; } public URL url() { try { return new URL(format("http://localhost:%d/", portNumber)); } catch (MalformedURLException e) { throw new RuntimeException(format("Couldn't instantiate a URL as 'http://localhost:%d/'", portNumber)); } } public int port() { return portNumber; } public void setPort(int portNumber) { this.portNumber = portNumber; } public <ATR extends ApplicativeTestRule<JenkinsInstance>> JenkinsInstance beforeStartApply(List<ATR> customRulesToBeApplied) { this.customRulesToApplyBeforeStart = copyOf(customRulesToBeApplied); return this; } public <ATR extends ApplicativeTestRule<JenkinsInstance>> JenkinsInstance afterStartApply(List<ATR> customRulesToBeApplied) { this.customRulesToApplyAfterStart = copyOf(customRulesToBeApplied); return this; } @Override public Statement apply(final Statement base, final Description description) { return chainOf(concat(customRulesToApplyBeforeStart, defaultRules, customRulesToApplyAfterStart)).apply(base, description); } private <ATR extends ApplicativeTestRule<JenkinsInstance>> RuleChain chainOf(List<ATR> rules) { return RuleChains.chained(instantiated(rules)); } private <ATR extends ApplicativeTestRule<JenkinsInstance>> List<TestRule> instantiated(List<ATR> rules) { List<TestRule> instantiatedRules = new ArrayList<>(rules.size()); for (ATR testRule : rules) { instantiatedRules.add(testRule.applyTo(this)); } return instantiatedRules; } }