From a53638db339113f6a90f2a54d2bb7f0337226acb Mon Sep 17 00:00:00 2001 From: strangelookingnerd <49242855+strangelookingnerd@users.noreply.github.com> Date: Wed, 17 Jan 2024 14:41:33 +0100 Subject: [PATCH] Provide JenkinsRule.restart() implementation --- .../org/jvnet/hudson/test/JenkinsRule.java | 37 ++++++++++++++- .../jvnet/hudson/test/JenkinsRuleTest.java | 30 +++++++++++++ .../junit/jupiter/JUnit5JenkinsRuleTest.java | 45 +++++++++++++++++++ .../jupiter/JenkinsRuleClassResolverTest.java | 0 .../jupiter/JenkinsRuleResolverTest.java | 6 +++ ...enkinsRuleResolverWithMethodScopeTest.java | 7 +++ 6 files changed, 124 insertions(+), 1 deletion(-) create mode 100644 src/test/java/org/jvnet/hudson/test/junit/jupiter/JUnit5JenkinsRuleTest.java create mode 100644 src/test/java/org/jvnet/hudson/test/junit/jupiter/JenkinsRuleClassResolverTest.java diff --git a/src/main/java/org/jvnet/hudson/test/JenkinsRule.java b/src/main/java/org/jvnet/hudson/test/JenkinsRule.java index 06b2206e2..169cb5051 100644 --- a/src/main/java/org/jvnet/hudson/test/JenkinsRule.java +++ b/src/main/java/org/jvnet/hudson/test/JenkinsRule.java @@ -42,6 +42,7 @@ import hudson.EnvVars; import hudson.Extension; import hudson.ExtensionList; +import hudson.FilePath; import hudson.Functions; import hudson.Launcher; import hudson.Main; @@ -170,7 +171,6 @@ import jenkins.security.MasterToSlaveCallable; import net.sf.json.JSON; import net.sf.json.JSONObject; -import org.acegisecurity.GrantedAuthorityImpl; import org.apache.commons.beanutils.PropertyUtils; import org.apache.commons.io.FileUtils; import org.eclipse.jetty.http.HttpCompliance; @@ -3040,6 +3040,41 @@ public Description getTestDescription() { return testDescription; } + /** + * Restart the current instance with the same port and a copy of its {@code JENKINS_HOME}. + */ + public void restart() throws Throwable { + // create backup of current instance in new home + URL source = jenkins.getRootDir().toURI().toURL(); + File copy = new TemporaryDirectoryAllocator().allocate(); + + if(source.getProtocol().equals("file")) { + File src = new File(source.toURI()); + if (src.isDirectory()) { + new FilePath(src).copyRecursiveTo("**/*",new FilePath(copy)); + } else if (src.getName().endsWith(".zip")) { + new FilePath(src).unzip(new FilePath(copy)); + } + } else { + File tmp = File.createTempFile("hudson","zip"); + try { + FileUtils.copyURLToFile(source,tmp); + new FilePath(tmp).unzip(new FilePath(copy)); + } finally { + FileUtils.deleteQuietly(tmp); + } + } + + // shutdown and cleanup current instance + after(); + + // init new instance with backup + withExistingHome(copy); + + // startup new instance + before(); + } + private NameValuePair getCrumbHeaderNVP() { return new NameValuePair(jenkins.getCrumbIssuer().getDescriptor().getCrumbRequestField(), jenkins.getCrumbIssuer().getCrumb( null )); diff --git a/src/test/java/org/jvnet/hudson/test/JenkinsRuleTest.java b/src/test/java/org/jvnet/hudson/test/JenkinsRuleTest.java index 87c932af7..346d39385 100644 --- a/src/test/java/org/jvnet/hudson/test/JenkinsRuleTest.java +++ b/src/test/java/org/jvnet/hudson/test/JenkinsRuleTest.java @@ -2,6 +2,9 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.not; +import static org.hamcrest.collection.IsCollectionWithSize.hasSize; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; @@ -14,6 +17,7 @@ import hudson.model.FreeStyleProject; import hudson.model.RootAction; import hudson.model.User; +import java.io.File; import java.io.IOException; import java.net.URL; import java.nio.file.Files; @@ -27,6 +31,7 @@ import org.htmlunit.WebRequest; import org.junit.Rule; import org.junit.Test; +import org.junit.runner.Description; import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.DataBoundSetter; import org.kohsuke.stapler.HttpResponse; @@ -421,4 +426,29 @@ public void waitForCompletion() throws Exception { j.assertBuildStatusSuccess(j.waitForCompletion(b)); } + @Test + public void restart() throws Throwable { + // preserve relevant properties + URL previousUrl = j.getURL(); + Description previousTestDescription = j.testDescription; + File previousRoot = j.jenkins.getRootDir(); + + // create some configuration + j.createFreeStyleProject(); + assertThat(j.jenkins.getJobNames(), hasSize(1)); + + // restart the instance with same port and new JENKINS_HOME + j.restart(); + + // validate properties and configuration were preserved + assertThat(j.getURL(), equalTo(previousUrl)); + assertThat(j.testDescription, equalTo(previousTestDescription)); + assertThat(j.jenkins.getRootDir(), not(previousRoot)); + assertThat(j.jenkins.getJobNames(), hasSize(1)); + + // validate restarted instance is working + j.createFreeStyleProject(); + assertThat(j.jenkins.getJobNames(), hasSize(2)); + } + } diff --git a/src/test/java/org/jvnet/hudson/test/junit/jupiter/JUnit5JenkinsRuleTest.java b/src/test/java/org/jvnet/hudson/test/junit/jupiter/JUnit5JenkinsRuleTest.java new file mode 100644 index 000000000..f4760dba5 --- /dev/null +++ b/src/test/java/org/jvnet/hudson/test/junit/jupiter/JUnit5JenkinsRuleTest.java @@ -0,0 +1,45 @@ +package org.jvnet.hudson.test.junit.jupiter; + +import org.junit.jupiter.api.Test; +import org.jvnet.hudson.test.JenkinsRule; +import org.junit.runner.Description; +import java.io.File; +import java.net.URL; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.not; +import static org.hamcrest.collection.IsCollectionWithSize.hasSize; + +/** + * Test {@link JUnit5JenkinsRule}. + */ +@WithJenkins +class JUnit5JenkinsRuleTest { + + @Test + void restart(JenkinsRule rule) throws Throwable { + // preserve relevant properties + URL previousUrl = rule.getURL(); + Description previousTestDescription = rule.getTestDescription(); + File previousRoot = rule.jenkins.getRootDir(); + + // create some configuration + rule.createFreeStyleProject(); + assertThat(rule.jenkins.getJobNames(), hasSize(1)); + + // restart the instance with same port and new JENKINS_HOME + rule.restart(); + + // validate properties and configuration were preserved + assertThat(rule.getURL(), equalTo(previousUrl)); + assertThat(rule.getTestDescription(), equalTo(previousTestDescription)); + assertThat(rule.jenkins.getRootDir(), not(previousRoot)); + assertThat(rule.jenkins.getJobNames(), hasSize(1)); + + // validate restarted instance is working + rule.createFreeStyleProject(); + assertThat(rule.jenkins.getJobNames(), hasSize(2)); + } + +} diff --git a/src/test/java/org/jvnet/hudson/test/junit/jupiter/JenkinsRuleClassResolverTest.java b/src/test/java/org/jvnet/hudson/test/junit/jupiter/JenkinsRuleClassResolverTest.java new file mode 100644 index 000000000..e69de29bb diff --git a/src/test/java/org/jvnet/hudson/test/junit/jupiter/JenkinsRuleResolverTest.java b/src/test/java/org/jvnet/hudson/test/junit/jupiter/JenkinsRuleResolverTest.java index bf9c8c900..d0618ca36 100644 --- a/src/test/java/org/jvnet/hudson/test/junit/jupiter/JenkinsRuleResolverTest.java +++ b/src/test/java/org/jvnet/hudson/test/junit/jupiter/JenkinsRuleResolverTest.java @@ -3,6 +3,7 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.collection.IsCollectionWithSize.hasSize; import static org.hamcrest.collection.IsEmptyCollection.empty; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; import java.io.IOException; import org.junit.jupiter.api.Test; @@ -17,4 +18,9 @@ void jenkinsRuleIsAccessible(JenkinsRule rule) throws IOException { rule.createFreeStyleProject("job-0"); assertThat(rule.jenkins.getJobNames(), hasSize(1)); } + + @Test + void instanceOf(JenkinsRule rule) { + assertInstanceOf(JUnit5JenkinsRule.class, rule); + } } diff --git a/src/test/java/org/jvnet/hudson/test/junit/jupiter/JenkinsRuleResolverWithMethodScopeTest.java b/src/test/java/org/jvnet/hudson/test/junit/jupiter/JenkinsRuleResolverWithMethodScopeTest.java index 3bb7b7335..37548b86b 100644 --- a/src/test/java/org/jvnet/hudson/test/junit/jupiter/JenkinsRuleResolverWithMethodScopeTest.java +++ b/src/test/java/org/jvnet/hudson/test/junit/jupiter/JenkinsRuleResolverWithMethodScopeTest.java @@ -3,6 +3,7 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.collection.IsCollectionWithSize.hasSize; import static org.hamcrest.collection.IsEmptyCollection.empty; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; import java.io.IOException; import org.junit.jupiter.api.Test; @@ -17,4 +18,10 @@ void jenkinsRuleIsAccessible(JenkinsRule rule) throws IOException { rule.createFreeStyleProject("job-0"); assertThat(rule.jenkins.getJobNames(), hasSize(1)); } + + @Test + @WithJenkins + void instanceOf(JenkinsRule rule) { + assertInstanceOf(JUnit5JenkinsRule.class, rule); + } }