From 0d14dd6a9981cb23798e63c1993afa4b671bf615 Mon Sep 17 00:00:00 2001 From: strangelookingnerd <49242855+strangelookingnerd@users.noreply.github.com> Date: Thu, 31 Jul 2025 11:25:26 +0200 Subject: [PATCH 1/2] Migrate tests to JUnit5 * first batch of green tests --- test/pom.xml | 2 +- .../java/hudson/ExtensionListRjrTest.java | 23 +- .../ProxyConfigurationManagerGUITest.java | 20 +- .../bugs/JnlpAccessWithSecuredHudsonTest.java | 64 ++-- .../hudson/cli/DisablePluginCommandTest.java | 80 ++--- .../hudson/cli/OfflineNodeCommandTest.java | 71 ++--- .../ReverseProxySetupMonitorTest.java | 293 +++++++----------- .../java/hudson/lifecycle/LifecycleTest.java | 14 +- .../java/hudson/model/AbstractItem2Test.java | 21 +- .../hudson/model/AsyncPeriodicWorkTest.java | 22 +- .../test/java/hudson/model/ExecutorTest.java | 2 +- .../FileParameterValuePersistenceTest.java | 26 +- .../test/java/hudson/model/ProjectTest.java | 286 ++++++++--------- .../java/hudson/model/QueueRestartTest.java | 23 +- .../test/java/hudson/model/RunActionTest.java | 16 +- .../java/hudson/model/UserRestartTest.java | 23 +- .../ResponseTimeMonitorTest.java | 35 ++- .../HudsonPrivateSecurityRealmFIPSTest.java | 43 ++- .../test/java/hudson/security/LoginTest.java | 55 ++-- .../hudson/slaves/AgentInboundUrlTest.java | 54 ++-- .../hudson/slaves/JNLPLauncherRealTest.java | 26 +- .../java/hudson/slaves/NodeParallelTest.java | 31 +- .../hudson/slaves/NodeProvisionerTest.java | 55 ++-- .../java/hudson/tasks/BuildTriggerTest.java | 2 +- .../hudson/util/ArgumentListBuilder2Test.java | 35 ++- .../hudson/util/DoubleLaunchCheckerTest.java | 20 +- .../hudson/util/XStream2AnnotationTest.java | 17 +- .../jenkins/agents/InboundAgentTlsTest.java | 40 +-- .../agents/JnlpProtocol4ProxyHandlerTest.java | 27 +- .../jenkins/agents/WebSocketAgentsTest.java | 42 +-- .../install/SetupWizardRestartTest.java | 32 +- .../BuiltInNodeMigrationRestartTest.java | 72 ++--- ...insBuildsAndWorkspacesDirectoriesTest.java | 120 +++---- .../jenkins/model/JenkinsLogRecordsTest.java | 16 +- .../model/JenkinsManagePermissionTest.java | 58 ++-- .../test/java/jenkins/model/JenkinsTest.java | 153 +++++---- .../java/jenkins/model/NodesRestartTest.java | 20 +- .../BasicHeaderApiTokenAuthenticatorTest.java | 21 +- .../security/CustomClassFilterTest.java | 85 +++-- .../JettySameSiteCookieSetupTest.java | 80 +++-- .../jenkins/security/Security218Test.java | 42 +-- .../jenkins/security/Security3430Test.java | 55 ++-- .../jenkins/security/Security637Test.java | 44 +-- .../apitoken/ApiTokenStatsRestartTest.java | 26 +- .../seed/UserSeedPropertyRestartTest.java | 22 +- .../JenkinsSupportAnnotationsTest.java | 22 +- .../JnlpSlaveRestarterInstallerTest.java | 37 ++- .../ReverseBuildTriggerAfterRestartTest.java | 16 +- .../util/SetContextClassLoaderTest.java | 18 +- .../jenkins/util/SystemPropertiesTest.java | 10 +- .../java/lib/layout/RenderOnDemandTest.java | 4 +- .../jenkins/ui/symbol/SymbolJenkinsTest.java | 19 +- 52 files changed, 1286 insertions(+), 1154 deletions(-) diff --git a/test/pom.xml b/test/pom.xml index 5689c9d581..53d0348abb 100644 --- a/test/pom.xml +++ b/test/pom.xml @@ -442,7 +442,7 @@ THE SOFTWARE. maven-surefire-plugin - org.jvnet.hudson.test.SmokeTest + SmokeTest diff --git a/test/src/test/java/hudson/ExtensionListRjrTest.java b/test/src/test/java/hudson/ExtensionListRjrTest.java index b35a8bd161..8d551846cd 100644 --- a/test/src/test/java/hudson/ExtensionListRjrTest.java +++ b/test/src/test/java/hudson/ExtensionListRjrTest.java @@ -3,7 +3,7 @@ package hudson; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.empty; import static org.hamcrest.Matchers.hasSize; -import static org.junit.Assert.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNotNull; import java.util.Collection; import jenkins.plugins.dependee.Dependee; @@ -12,16 +12,17 @@ import jenkins.plugins.dynamic_extension_loading.CustomExtensionLoadedViaConstru import jenkins.plugins.dynamic_extension_loading.CustomExtensionLoadedViaListener; import jenkins.plugins.dynamic_extension_loading.CustomPeriodicWork; import jenkins.plugins.optional_depender.OptionalDepender; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.jvnet.hudson.test.Issue; import org.jvnet.hudson.test.JenkinsRule; -import org.jvnet.hudson.test.RealJenkinsRule; -import org.jvnet.hudson.test.RealJenkinsRule.SyntheticPlugin; +import org.jvnet.hudson.test.junit.jupiter.RealJenkinsExtension; +import org.jvnet.hudson.test.junit.jupiter.RealJenkinsExtension.SyntheticPlugin; -public class ExtensionListRjrTest { - @Rule - public RealJenkinsRule rjr = new RealJenkinsRule(); +class ExtensionListRjrTest { + + @RegisterExtension + public RealJenkinsExtension rjr = new RealJenkinsExtension(); /** * Check that dynamically loading a plugin does not lead to extension lists with duplicate entries. @@ -30,7 +31,7 @@ public class ExtensionListRjrTest { */ @Test @Issue("JENKINS-75232") - public void checkDynamicLoad_singleRegistration() throws Throwable { + void checkDynamicLoad_singleRegistration() throws Throwable { var pluginJpi = rjr.createSyntheticPlugin(new SyntheticPlugin(CustomPeriodicWork.class.getPackage()) .shortName("dynamic-extension-loading") .header("Plugin-Dependencies", "variant:0")); @@ -57,8 +58,8 @@ public class ExtensionListRjrTest { } @Test - @Issue({ "JENKINS-50336", "JENKINS-60449" }) - public void installDependedOptionalPluginWithoutRestart() throws Throwable { + @Issue({"JENKINS-50336", "JENKINS-60449"}) + void installDependedOptionalPluginWithoutRestart() throws Throwable { var optionalDependerJpi = rjr.createSyntheticPlugin(new SyntheticPlugin(OptionalDepender.class.getPackage()) .header("Plugin-Dependencies", "variant:0,dependee:0;resolution:=optional")); var dependeeJpi = rjr.createSyntheticPlugin(new SyntheticPlugin(Dependee.class.getPackage()).shortName("dependee")); diff --git a/test/src/test/java/hudson/ProxyConfigurationManagerGUITest.java b/test/src/test/java/hudson/ProxyConfigurationManagerGUITest.java index 5309e43d04..08e67ec304 100644 --- a/test/src/test/java/hudson/ProxyConfigurationManagerGUITest.java +++ b/test/src/test/java/hudson/ProxyConfigurationManagerGUITest.java @@ -24,22 +24,24 @@ package hudson; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; import hudson.util.Secret; import java.io.File; import org.apache.commons.io.FileUtils; -import org.junit.Rule; -import org.junit.Test; -import org.jvnet.hudson.test.JenkinsSessionRule; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.jvnet.hudson.test.junit.jupiter.JenkinsSessionExtension; -public final class ProxyConfigurationManagerGUITest { +class ProxyConfigurationManagerGUITest { - @Rule public JenkinsSessionRule rr = new JenkinsSessionRule(); + @RegisterExtension + public JenkinsSessionExtension rr = new JenkinsSessionExtension(); - @Test public void configRoundtrip() throws Throwable { + @Test + void configRoundtrip() throws Throwable { rr.then(r -> { assertNull(r.jenkins.proxy); r.jenkins.proxy = new ProxyConfiguration("proxy.mycorp", 80); diff --git a/test/src/test/java/hudson/bugs/JnlpAccessWithSecuredHudsonTest.java b/test/src/test/java/hudson/bugs/JnlpAccessWithSecuredHudsonTest.java index a6544fd361..7a045c3246 100644 --- a/test/src/test/java/hudson/bugs/JnlpAccessWithSecuredHudsonTest.java +++ b/test/src/test/java/hudson/bugs/JnlpAccessWithSecuredHudsonTest.java @@ -24,8 +24,8 @@ package hudson.bugs; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; import hudson.model.Slave; import hudson.model.User; @@ -34,6 +34,7 @@ import java.io.File; import java.net.HttpURLConnection; import java.net.URL; import java.util.Locale; +import jenkins.model.Jenkins; import jenkins.security.s2m.AdminWhitelistRule; import org.dom4j.Document; import org.dom4j.Element; @@ -41,32 +42,42 @@ import org.dom4j.io.DOMReader; import org.htmlunit.Page; import org.htmlunit.html.HtmlPage; import org.htmlunit.xml.XmlPage; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.jvnet.hudson.test.Email; -import org.jvnet.hudson.test.InboundAgentRule; import org.jvnet.hudson.test.JenkinsRule; -import org.jvnet.hudson.test.recipes.PresetData; -import org.jvnet.hudson.test.recipes.PresetData.DataSet; +import org.jvnet.hudson.test.MockAuthorizationStrategy; +import org.jvnet.hudson.test.junit.jupiter.InboundAgentExtension; +import org.jvnet.hudson.test.junit.jupiter.WithJenkins; /** * Makes sure that the jars that web start needs are readable, even when the anonymous user doesn't have any read access. * * @author Kohsuke Kawaguchi */ -public class JnlpAccessWithSecuredHudsonTest { +@WithJenkins +class JnlpAccessWithSecuredHudsonTest { - @Rule - public JenkinsRule r = new JenkinsRule(); + @RegisterExtension + private final InboundAgentExtension inboundAgents = new InboundAgentExtension(); - @Rule - public InboundAgentRule inboundAgents = new InboundAgentRule(); + private JenkinsRule r; + + @BeforeEach + void setUp(JenkinsRule rule) { + r = rule; + } - @PresetData(DataSet.NO_ANONYMOUS_READACCESS) @Email("http://markmail.org/message/on4wkjdaldwi2atx") @Test - public void anonymousCanAlwaysLoadJARs() throws Exception { - inboundAgents.createAgent(r, InboundAgentRule.Options.newBuilder().name("test").skipStart().build()); + void anonymousCanAlwaysLoadJARs() throws Exception { + JenkinsRule.DummySecurityRealm realm = r.createDummySecurityRealm(); + r.jenkins.setSecurityRealm(realm); + r.jenkins.setAuthorizationStrategy(new MockAuthorizationStrategy() + .grant(Jenkins.ADMINISTER).everywhere().toAuthenticated()); + + inboundAgents.createAgent(r, InboundAgentExtension.Options.newBuilder().name("test").skipStart().build()); JenkinsRule.WebClient wc = r.createWebClient(); HtmlPage p = wc.withBasicApiToken(User.getById("alice", true)).goTo("computer/test/"); @@ -87,21 +98,30 @@ public class JnlpAccessWithSecuredHudsonTest { } } - @PresetData(DataSet.ANONYMOUS_READONLY) @Test - public void anonymousCannotGetSecrets() throws Exception { - inboundAgents.createAgent(r, InboundAgentRule.Options.newBuilder().name("test").skipStart().build()); + void anonymousCannotGetSecrets() throws Exception { + JenkinsRule.DummySecurityRealm realm = r.createDummySecurityRealm(); + r.jenkins.setSecurityRealm(realm); + r.jenkins.setAuthorizationStrategy(new MockAuthorizationStrategy() + .grant(Jenkins.READ).everywhere().toEveryone() + .grant(Jenkins.ADMINISTER).everywhere().toAuthenticated()); + + inboundAgents.createAgent(r, InboundAgentExtension.Options.newBuilder().name("test").skipStart().build()); r.createWebClient().assertFails("computer/test/jenkins-agent.jnlp", HttpURLConnection.HTTP_FORBIDDEN); } - @PresetData(DataSet.NO_ANONYMOUS_READACCESS) @Test - public void serviceUsingDirectSecret() throws Exception { - Slave slave = inboundAgents.createAgent(r, InboundAgentRule.Options.newBuilder().name("test").secret().build()); + void serviceUsingDirectSecret() throws Exception { + JenkinsRule.DummySecurityRealm realm = r.createDummySecurityRealm(); + r.jenkins.setSecurityRealm(realm); + r.jenkins.setAuthorizationStrategy(new MockAuthorizationStrategy() + .grant(Jenkins.ADMINISTER).everywhere().toAuthenticated()); + + Slave slave = inboundAgents.createAgent(r, InboundAgentExtension.Options.newBuilder().name("test").build()); try { r.createWebClient().goTo("computer/test/jenkins-agent.jnlp?encrypt=true", "application/octet-stream"); Channel channel = slave.getComputer().getChannel(); - assertFalse("SECURITY-206", channel.isRemoteClassLoadingAllowed()); + assertFalse(channel.isRemoteClassLoadingAllowed(), "SECURITY-206"); r.jenkins.getExtensionList(AdminWhitelistRule.class).get(AdminWhitelistRule.class).setMasterKillSwitch(false); final File f = new File(r.jenkins.getRootDir(), "config.xml"); assertTrue(f.exists()); diff --git a/test/src/test/java/hudson/cli/DisablePluginCommandTest.java b/test/src/test/java/hudson/cli/DisablePluginCommandTest.java index b4a4f5f49c..9fe95ec573 100644 --- a/test/src/test/java/hudson/cli/DisablePluginCommandTest.java +++ b/test/src/test/java/hudson/cli/DisablePluginCommandTest.java @@ -33,27 +33,33 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.emptyOrNullString; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.notNullValue; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; import hudson.Functions; import hudson.PluginWrapper; import java.io.IOException; import java.util.function.BiPredicate; import org.apache.commons.lang3.StringUtils; -import org.junit.Assume; -import org.junit.Ignore; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Assumptions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; import org.jvnet.hudson.test.Issue; import org.jvnet.hudson.test.JenkinsRule; +import org.jvnet.hudson.test.junit.jupiter.WithJenkins; import org.jvnet.hudson.test.recipes.WithPlugin; -public class DisablePluginCommandTest { +@WithJenkins +class DisablePluginCommandTest { - @Rule - public JenkinsRule j = new JenkinsRule(); + private JenkinsRule j; + + @BeforeEach + void setUp(JenkinsRule rule) { + j = rule; + } /** * Can disable a plugin with an optional dependent plugin. @@ -62,7 +68,7 @@ public class DisablePluginCommandTest { @Test @Issue("JENKINS-27177") @WithPlugin({"depender-0.0.2.hpi", "dependee-0.0.2.hpi"}) - public void canDisablePluginWithOptionalDependerStrategyNone() { + void canDisablePluginWithOptionalDependerStrategyNone() { assertThat(disablePluginsCLiCommand("-strategy", "NONE", "dependee"), succeeded()); assertPluginDisabled("dependee"); } @@ -70,12 +76,12 @@ public class DisablePluginCommandTest { @Test @Issue("JENKINS-27177") @WithPlugin({"depender-0.0.2.hpi", "dependee-0.0.2.hpi", "mandatory-depender-0.0.2.hpi"}) - public void canDisablePluginWithDependentsDisabledStrategyNone() throws IOException { + void canDisablePluginWithDependentsDisabledStrategyNone() throws IOException { disablePlugin("mandatory-depender"); CLICommandInvoker.Result result = disablePluginsCLiCommand("-strategy", "NONE", "dependee"); assertThat(result, succeeded()); - assertEquals("Disabling only dependee", 1, StringUtils.countMatches(result.stdout(), "Disabling")); + assertEquals(1, StringUtils.countMatches(result.stdout(), "Disabling"), "Disabling only dependee"); assertPluginDisabled("dependee"); } @@ -86,7 +92,7 @@ public class DisablePluginCommandTest { @Test @Issue("JENKINS-27177") @WithPlugin({"mandatory-depender-0.0.2.hpi", "dependee-0.0.2.hpi"}) - public void cannotDisablePluginWithMandatoryDependerStrategyNone() { + void cannotDisablePluginWithMandatoryDependerStrategyNone() { assertThat(disablePluginsCLiCommand("dependee"), failedWith(RETURN_CODE_NOT_DISABLED_DEPENDANTS)); assertPluginEnabled("dependee"); } @@ -98,7 +104,7 @@ public class DisablePluginCommandTest { @Test @Issue("JENKINS-27177") @WithPlugin({"mandatory-depender-0.0.2.hpi", "dependee-0.0.2.hpi"}) - public void cannotDisableDependentPluginWrongOrderStrategyNone() { + void cannotDisableDependentPluginWrongOrderStrategyNone() { assertThat(disablePluginsCLiCommand("dependee", "mandatory-depender"), failedWith(RETURN_CODE_NOT_DISABLED_DEPENDANTS)); assertPluginDisabled("mandatory-depender"); assertPluginEnabled("dependee"); @@ -110,7 +116,7 @@ public class DisablePluginCommandTest { @Test @Issue("JENKINS-27177") @WithPlugin({"mandatory-depender-0.0.2.hpi", "dependee-0.0.2.hpi"}) - public void canDisableDependentPluginWrongOrderStrategyAll() { + void canDisableDependentPluginWrongOrderStrategyAll() { assertThat(disablePluginsCLiCommand("dependee", "mandatory-depender", "-strategy", "all"), succeeded()); assertPluginDisabled("mandatory-depender"); assertPluginDisabled("dependee"); @@ -123,7 +129,7 @@ public class DisablePluginCommandTest { @Test @Issue("JENKINS-27177") @WithPlugin({"mandatory-depender-0.0.2.hpi", "dependee-0.0.2.hpi"}) - public void canDisableDependentPluginsRightOrderStrategyNone() { + void canDisableDependentPluginsRightOrderStrategyNone() { assertThat(disablePluginsCLiCommand("mandatory-depender", "dependee"), succeeded()); assertPluginDisabled("dependee"); assertPluginDisabled("mandatory-depender"); @@ -132,11 +138,11 @@ public class DisablePluginCommandTest { /** * Can disable a plugin without dependents plugins and Jenkins restart after it if -restart argument is passed. */ - @Ignore("TODO calling restart seems to break Surefire") + @Disabled("TODO calling restart seems to break Surefire") @Test @Issue("JENKINS-27177") @WithPlugin("dependee-0.0.2.hpi") - public void restartAfterDisable() { + void restartAfterDisable() { assumeNotWindows(); assertThat(disablePluginsCLiCommand("-restart", "dependee"), succeeded()); assertPluginDisabled("dependee"); @@ -149,7 +155,7 @@ public class DisablePluginCommandTest { @Test @Issue("JENKINS-27177") @WithPlugin("dependee-0.0.2.hpi") - public void notRestartAfterDisablePluginWithoutArgumentRestart() throws Exception { + void notRestartAfterDisablePluginWithoutArgumentRestart() throws Exception { assertThat(disablePluginsCLiCommand("dependee"), succeeded()); assertPluginDisabled("dependee"); assertJenkinsNotInQuietMode(); @@ -162,7 +168,7 @@ public class DisablePluginCommandTest { @Test @Issue("JENKINS-27177") @WithPlugin("dependee-0.0.2.hpi") - public void returnCodeDisableInvalidPlugin() { + void returnCodeDisableInvalidPlugin() { assertThat(disablePluginsCLiCommand("wrongname"), failedWith(RETURN_CODE_NO_SUCH_PLUGIN)); } @@ -173,7 +179,7 @@ public class DisablePluginCommandTest { @Test @Issue("JENKINS-27177") @WithPlugin("dependee-0.0.2.hpi") - public void disableAlreadyDisabledPluginNotRestart() throws Exception { + void disableAlreadyDisabledPluginNotRestart() throws Exception { // Disable before the command call disablePlugin("dependee"); @@ -187,11 +193,11 @@ public class DisablePluginCommandTest { /** * If some plugins are disabled, Jenkins will restart even though the status code isn't 0 (is 16). */ - @Ignore("TODO calling restart seems to break Surefire") + @Disabled("TODO calling restart seems to break Surefire") @Test @Issue("JENKINS-27177") @WithPlugin({"depender-0.0.2.hpi", "mandatory-depender-0.0.2.hpi", "plugin-first.hpi", "dependee-0.0.2.hpi"}) - public void restartAfterDisablePluginsAndErrors() { + void restartAfterDisablePluginsAndErrors() { assumeNotWindows(); assertThat(disablePluginsCLiCommand("-restart", "dependee", "depender", "plugin-first", "mandatory-depender"), failedWith(RETURN_CODE_NOT_DISABLED_DEPENDANTS)); assertPluginEnabled("dependee"); @@ -207,7 +213,7 @@ public class DisablePluginCommandTest { @Test @Issue("JENKINS-27177") @WithPlugin({"depender-0.0.2.hpi", "mandatory-depender-0.0.2.hpi", "plugin-first.hpi", "dependee-0.0.2.hpi"}) - public void disablePluginsStrategyAll() { + void disablePluginsStrategyAll() { assertPluginEnabled("dependee"); assertPluginEnabled("depender"); assertPluginEnabled("mandatory-depender"); @@ -224,7 +230,7 @@ public class DisablePluginCommandTest { @Test @Issue("JENKINS-27177") @WithPlugin({"depender-0.0.2.hpi", "mandatory-depender-0.0.2.hpi", "plugin-first.hpi", "dependee-0.0.2.hpi"}) - public void disablePluginsStrategyMandatory() { + void disablePluginsStrategyMandatory() { assertThat(disablePluginsCLiCommand("-strategy", "mandatory", "dependee", "plugin-first"), succeeded()); assertPluginDisabled("dependee"); assertPluginEnabled("depender"); @@ -239,15 +245,15 @@ public class DisablePluginCommandTest { @Test @Issue("JENKINS-27177") @WithPlugin({"depender-0.0.2.hpi", "dependee-0.0.2.hpi"}) - public void disablePluginsMessageAlreadyDisabled() { + void disablePluginsMessageAlreadyDisabled() { CLICommandInvoker.Result result = disablePluginsCLiCommand("-strategy", "all", "dependee", "depender"); assertThat(result, succeeded()); assertPluginDisabled("dependee"); assertPluginDisabled("depender"); - assertTrue("An occurrence of the depender plugin in the log says it was successfully disabled", checkResultWith(result, StringUtils::contains, "depender", PluginWrapper.PluginDisableStatus.DISABLED)); - assertTrue("An occurrence of the depender plugin in the log says it was already disabled", checkResultWith(result, StringUtils::contains, "depender", PluginWrapper.PluginDisableStatus.ALREADY_DISABLED)); + assertTrue(checkResultWith(result, StringUtils::contains, "depender", PluginWrapper.PluginDisableStatus.DISABLED), "An occurrence of the depender plugin in the log says it was successfully disabled"); + assertTrue(checkResultWith(result, StringUtils::contains, "depender", PluginWrapper.PluginDisableStatus.ALREADY_DISABLED), "An occurrence of the depender plugin in the log says it was already disabled"); } /** @@ -257,7 +263,7 @@ public class DisablePluginCommandTest { @Test @Issue("JENKINS-27177") @WithPlugin({"dependee-0.0.2.hpi", "mandatory-depender-0.0.2.hpi"}) - public void returnCodeFirstErrorIsDependents() { + void returnCodeFirstErrorIsDependents() { CLICommandInvoker.Result result = disablePluginsCLiCommand("dependee", "badplugin"); assertThat(result, failedWith(RETURN_CODE_NOT_DISABLED_DEPENDANTS)); @@ -270,7 +276,7 @@ public class DisablePluginCommandTest { @Test @Issue("JENKINS-27177") @WithPlugin({"dependee-0.0.2.hpi", "mandatory-depender-0.0.2.hpi"}) - public void returnCodeFirstErrorIsNoSuchPlugin() { + void returnCodeFirstErrorIsNoSuchPlugin() { CLICommandInvoker.Result result = disablePluginsCLiCommand("badplugin", "dependee"); assertThat(result, failedWith(RETURN_CODE_NO_SUCH_PLUGIN)); @@ -283,7 +289,7 @@ public class DisablePluginCommandTest { @Test @Issue("JENKINS-27177") @WithPlugin({"depender-0.0.2.hpi", "dependee-0.0.2.hpi", "mandatory-depender-0.0.2.hpi"}) - public void quietModeEmptyOutputSucceed() { + void quietModeEmptyOutputSucceed() { CLICommandInvoker.Result result = disablePluginsCLiCommand("-strategy", "all", "-quiet", "dependee"); assertThat(result, succeeded()); @@ -300,7 +306,7 @@ public class DisablePluginCommandTest { @Test @Issue("JENKINS-27177") @WithPlugin({"depender-0.0.2.hpi", "dependee-0.0.2.hpi", "mandatory-depender-0.0.2.hpi"}) - public void quietModeWithErrorNoSuch() { + void quietModeWithErrorNoSuch() { CLICommandInvoker.Result result = disablePluginsCLiCommand("-quiet", "-strategy", "all", "dependee", "badplugin"); assertThat(result, failedWith(RETURN_CODE_NO_SUCH_PLUGIN)); @@ -308,7 +314,7 @@ public class DisablePluginCommandTest { assertPluginDisabled("depender"); assertPluginDisabled("mandatory-depender"); - assertTrue("Only error NO_SUCH_PLUGIN in quiet mode", checkResultWith(result, StringUtils::startsWith, "badplugin", PluginWrapper.PluginDisableStatus.NO_SUCH_PLUGIN)); + assertTrue(checkResultWith(result, StringUtils::startsWith, "badplugin", PluginWrapper.PluginDisableStatus.NO_SUCH_PLUGIN), "Only error NO_SUCH_PLUGIN in quiet mode"); } /** @@ -317,7 +323,7 @@ public class DisablePluginCommandTest { @Test @Issue("JENKINS-27177") @WithPlugin({"depender-0.0.2.hpi", "dependee-0.0.2.hpi", "mandatory-depender-0.0.2.hpi"}) - public void quietModeWithErrorDependents() { + void quietModeWithErrorDependents() { CLICommandInvoker.Result result = disablePluginsCLiCommand("-quiet", "-strategy", "none", "dependee"); assertThat(result, failedWith(RETURN_CODE_NOT_DISABLED_DEPENDANTS)); @@ -325,7 +331,7 @@ public class DisablePluginCommandTest { assertPluginEnabled("depender"); assertPluginEnabled("mandatory-depender"); - assertTrue("Only error NOT_DISABLED_DEPENDANTS in quiet mode", checkResultWith(result, StringUtils::startsWith, "dependee", PluginWrapper.PluginDisableStatus.NOT_DISABLED_DEPENDANTS)); + assertTrue(checkResultWith(result, StringUtils::startsWith, "dependee", PluginWrapper.PluginDisableStatus.NOT_DISABLED_DEPENDANTS), "Only error NOT_DISABLED_DEPENDANTS in quiet mode"); } /** @@ -388,6 +394,6 @@ public class DisablePluginCommandTest { } private void assumeNotWindows() { - Assume.assumeFalse(Functions.isWindows()); + Assumptions.assumeFalse(Functions.isWindows()); } } diff --git a/test/src/test/java/hudson/cli/OfflineNodeCommandTest.java b/test/src/test/java/hudson/cli/OfflineNodeCommandTest.java index 878001e1b1..669cd42583 100644 --- a/test/src/test/java/hudson/cli/OfflineNodeCommandTest.java +++ b/test/src/test/java/hudson/cli/OfflineNodeCommandTest.java @@ -41,37 +41,38 @@ import hudson.slaves.DumbSlave; import hudson.slaves.OfflineCause; import hudson.util.OneShotEvent; import jenkins.model.Jenkins; -import org.junit.Before; -import org.junit.ClassRule; -import org.junit.Rule; -import org.junit.Test; -import org.jvnet.hudson.test.BuildWatcher; -import org.jvnet.hudson.test.InboundAgentRule; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.jvnet.hudson.test.JenkinsRule; +import org.jvnet.hudson.test.junit.jupiter.BuildWatcherExtension; +import org.jvnet.hudson.test.junit.jupiter.InboundAgentExtension; +import org.jvnet.hudson.test.junit.jupiter.WithJenkins; /** * @author pjanouse */ -public class OfflineNodeCommandTest { +@WithJenkins +class OfflineNodeCommandTest { private CLICommandInvoker command; - @ClassRule - public static final BuildWatcher buildWatcher = new BuildWatcher(); + @RegisterExtension + private static final BuildWatcherExtension buildWatcher = new BuildWatcherExtension(); - @Rule - public final JenkinsRule j = new JenkinsRule(); + @RegisterExtension + private final InboundAgentExtension inboundAgents = new InboundAgentExtension(); - @Rule - public InboundAgentRule inboundAgents = new InboundAgentRule(); + private JenkinsRule j; - @Before - public void setUp() { + @BeforeEach + void setUp(JenkinsRule rule) { + j = rule; command = new CLICommandInvoker(j, "offline-node"); } @Test - public void offlineNodeShouldFailWithoutComputerDisconnectPermission() throws Exception { + void offlineNodeShouldFailWithoutComputerDisconnectPermission() throws Exception { j.createSlave("aNode", "", null); final CLICommandInvoker.Result result = command @@ -84,7 +85,7 @@ public class OfflineNodeCommandTest { } @Test - public void offlineNodeShouldFailIfNodeDoesNotExist() { + void offlineNodeShouldFailIfNodeDoesNotExist() { final CLICommandInvoker.Result result = command .authorizedTo(Computer.DISCONNECT, Jenkins.READ) .invokeWithArgs("never_created"); @@ -95,7 +96,7 @@ public class OfflineNodeCommandTest { } @Test - public void offlineNodeShouldSucceedOnOnlineNode() throws Exception { + void offlineNodeShouldSucceedOnOnlineNode() throws Exception { DumbSlave slave = j.createSlave("aNode", "", null); slave.toComputer().waitUntilOnline(); assertThat(slave.toComputer().isOnline(), equalTo(true)); @@ -113,8 +114,8 @@ public class OfflineNodeCommandTest { } @Test - public void offlineNodeShouldSucceedOnOfflineNode() throws Exception { - Slave slave = inboundAgents.createAgent(j, InboundAgentRule.Options.newBuilder().name("aNode").skipStart().build()); + void offlineNodeShouldSucceedOnOfflineNode() throws Exception { + Slave slave = inboundAgents.createAgent(j, InboundAgentExtension.Options.newBuilder().name("aNode").skipStart().build()); slave.toComputer().setTemporarilyOffline(true, null); assertThat(slave.toComputer().isOffline(), equalTo(true)); assertThat(slave.toComputer().isTemporarilyOffline(), equalTo(true)); @@ -131,7 +132,7 @@ public class OfflineNodeCommandTest { } @Test - public void offlineNodeShouldSucceedOnDisconnectedNode() throws Exception { + void offlineNodeShouldSucceedOnDisconnectedNode() throws Exception { DumbSlave slave = j.createSlave("aNode", "", null); slave.toComputer().waitUntilOnline(); assertThat(slave.toComputer().isOnline(), equalTo(true)); @@ -154,7 +155,7 @@ public class OfflineNodeCommandTest { } @Test - public void offlineNodeShouldSucceedOnOnlineNodeWithCause() throws Exception { + void offlineNodeShouldSucceedOnOnlineNodeWithCause() throws Exception { DumbSlave slave = j.createSlave("aNode", "", null); slave.toComputer().waitUntilOnline(); assertThat(slave.toComputer().isOnline(), equalTo(true)); @@ -172,8 +173,8 @@ public class OfflineNodeCommandTest { } @Test - public void offlineNodeShouldSucceedOnOfflineNodeWithCause() throws Exception { - Slave slave = inboundAgents.createAgent(j, InboundAgentRule.Options.newBuilder().name("aNode").skipStart().build()); + void offlineNodeShouldSucceedOnOfflineNodeWithCause() throws Exception { + Slave slave = inboundAgents.createAgent(j, InboundAgentExtension.Options.newBuilder().name("aNode").skipStart().build()); slave.toComputer().setTemporarilyOffline(true, null); assertThat(slave.toComputer().isOffline(), equalTo(true)); assertThat(slave.toComputer().isTemporarilyOffline(), equalTo(true)); @@ -190,7 +191,7 @@ public class OfflineNodeCommandTest { } @Test - public void offlineNodeShouldSucceedOnDisconnectedNodeWithCause() throws Exception { + void offlineNodeShouldSucceedOnDisconnectedNodeWithCause() throws Exception { DumbSlave slave = j.createSlave("aNode", "", null); slave.toComputer().waitUntilOnline(); assertThat(slave.toComputer().isOnline(), equalTo(true)); @@ -213,7 +214,7 @@ public class OfflineNodeCommandTest { } @Test - public void offlineNodeShouldSucceedOnBuildingNode() throws Exception { + void offlineNodeShouldSucceedOnBuildingNode() throws Exception { final OneShotEvent finish = new OneShotEvent(); DumbSlave slave = j.createSlave("aNode", "", null); slave.toComputer().waitUntilOnline(); @@ -239,7 +240,7 @@ public class OfflineNodeCommandTest { } @Test - public void offlineNodeShouldSucceedOnBuildingNodeWithCause() throws Exception { + void offlineNodeShouldSucceedOnBuildingNodeWithCause() throws Exception { final OneShotEvent finish = new OneShotEvent(); DumbSlave slave = j.createSlave("aNode", "", null); slave.toComputer().waitUntilOnline(); @@ -265,7 +266,7 @@ public class OfflineNodeCommandTest { } @Test - public void offlineNodeManyShouldSucceed() throws Exception { + void offlineNodeManyShouldSucceed() throws Exception { DumbSlave slave1 = j.createSlave("aNode1", "", null); DumbSlave slave2 = j.createSlave("aNode2", "", null); DumbSlave slave3 = j.createSlave("aNode3", "", null); @@ -295,7 +296,7 @@ public class OfflineNodeCommandTest { } @Test - public void offlineNodeManyShouldSucceedWithCause() throws Exception { + void offlineNodeManyShouldSucceedWithCause() throws Exception { DumbSlave slave1 = j.createSlave("aNode1", "", null); DumbSlave slave2 = j.createSlave("aNode2", "", null); DumbSlave slave3 = j.createSlave("aNode3", "", null); @@ -325,7 +326,7 @@ public class OfflineNodeCommandTest { } @Test - public void offlineNodeManyShouldFailIfANodeDoesNotExist() throws Exception { + void offlineNodeManyShouldFailIfANodeDoesNotExist() throws Exception { DumbSlave slave1 = j.createSlave("aNode1", "", null); DumbSlave slave2 = j.createSlave("aNode2", "", null); slave1.toComputer().waitUntilOnline(); @@ -351,7 +352,7 @@ public class OfflineNodeCommandTest { } @Test - public void offlineNodeManyShouldFailIfANodeDoesNotExistWithCause() throws Exception { + void offlineNodeManyShouldFailIfANodeDoesNotExistWithCause() throws Exception { DumbSlave slave1 = j.createSlave("aNode1", "", null); DumbSlave slave2 = j.createSlave("aNode2", "", null); slave1.toComputer().waitUntilOnline(); @@ -377,7 +378,7 @@ public class OfflineNodeCommandTest { } @Test - public void offlineNodeManyShouldSucceedEvenANodeIsSpecifiedTwice() throws Exception { + void offlineNodeManyShouldSucceedEvenANodeIsSpecifiedTwice() throws Exception { DumbSlave slave1 = j.createSlave("aNode1", "", null); DumbSlave slave2 = j.createSlave("aNode2", "", null); slave1.toComputer().waitUntilOnline(); @@ -400,7 +401,7 @@ public class OfflineNodeCommandTest { } @Test - public void offlineNodeManyShouldSucceedEvenANodeIsSpecifiedTwiceWithCause() throws Exception { + void offlineNodeManyShouldSucceedEvenANodeIsSpecifiedTwiceWithCause() throws Exception { DumbSlave slave1 = j.createSlave("aNode1", "", null); DumbSlave slave2 = j.createSlave("aNode2", "", null); slave1.toComputer().waitUntilOnline(); @@ -423,7 +424,7 @@ public class OfflineNodeCommandTest { } @Test - public void offlineNodeShouldSucceedOnMaster() { + void offlineNodeShouldSucceedOnMaster() { final Computer masterComputer = Jenkins.get().getComputer(""); final CLICommandInvoker.Result result = command @@ -437,7 +438,7 @@ public class OfflineNodeCommandTest { } @Test - public void offlineNodeShouldSucceedOnMasterWithCause() { + void offlineNodeShouldSucceedOnMasterWithCause() { final Computer masterComputer = Jenkins.get().getComputer(""); final CLICommandInvoker.Result result = command diff --git a/test/src/test/java/hudson/diagnosis/ReverseProxySetupMonitorTest.java b/test/src/test/java/hudson/diagnosis/ReverseProxySetupMonitorTest.java index a9bb7278a8..285abb8b3b 100644 --- a/test/src/test/java/hudson/diagnosis/ReverseProxySetupMonitorTest.java +++ b/test/src/test/java/hudson/diagnosis/ReverseProxySetupMonitorTest.java @@ -24,7 +24,7 @@ package hudson.diagnosis; -import static org.junit.Assert.assertThrows; +import static org.junit.jupiter.api.Assertions.assertThrows; import java.net.URL; import java.util.List; @@ -32,250 +32,165 @@ import jenkins.model.JenkinsLocationConfiguration; import org.htmlunit.FailingHttpStatusCodeException; import org.htmlunit.WebRequest; import org.htmlunit.util.NameValuePair; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.Description; -import org.junit.runners.model.Statement; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.jvnet.hudson.test.JenkinsRule; -import org.jvnet.hudson.test.RestartableJenkinsRule; +import org.jvnet.hudson.test.junit.jupiter.WithJenkins; -public class ReverseProxySetupMonitorTest { +@WithJenkins +class ReverseProxySetupMonitorTest { - @Rule - public RestartableJenkinsRule rr = new RestartableJenkinsRule() { - @Override - protected JenkinsRule createJenkinsRule(Description description) { - JenkinsRule j = super.createJenkinsRule(description); - j.contextPath = desiredContextPath; - return j; - } - }; + private JenkinsRule j; - private String desiredContextPath; - - @Before - public void resetContextPath() { - this.desiredContextPath = "/jenkins"; + @BeforeEach + void setUp(JenkinsRule rule) { + j = rule; } @Test - public void localhost_correct() { - rr.addStep(new Statement() { - @Override - public void evaluate() throws Throwable { - JenkinsRule j = rr.j; - JenkinsRule.WebClient wc = rr.j.createWebClient(); - WebRequest request = new WebRequest(new URL(j.getURL(), getAdminMonitorTestUrl(j))); - request.setAdditionalHeader("Referer", j.getURL() + "manage"); - wc.getPage(request); - } - }); + void localhost_correct() throws Exception { + JenkinsRule.WebClient wc = j.createWebClient(); + WebRequest request = new WebRequest(new URL(j.getURL(), getAdminMonitorTestUrl(j))); + request.setAdditionalHeader("Referer", j.getURL() + "manage"); + wc.getPage(request); } @Test - public void localhost_testingForContext() { - rr.addStep(new Statement() { - @Override - public void evaluate() throws Throwable { - JenkinsRule j = rr.j; - JenkinsRule.WebClient wc = rr.j.createWebClient(); - WebRequest request = new WebRequest(new URL(j.getURL(), getAdminMonitorTestUrl(j))); - request.setAdditionalHeader("Referer", j.getURL() + "manage"); + void localhost_testingForContext() throws Exception { + JenkinsRule.WebClient wc = j.createWebClient(); + WebRequest request = new WebRequest(new URL(j.getURL(), getAdminMonitorTestUrl(j))); + request.setAdditionalHeader("Referer", j.getURL() + "manage"); - // As the context was already set inside the referer, adding another one will fail - request.setRequestParameters(List.of(new NameValuePair("testWithContext", "true"))); - assertThrows(FailingHttpStatusCodeException.class, () -> wc.getPage(request)); - } - }); + // As the context was already set inside the referer, adding another one will fail + request.setRequestParameters(List.of(new NameValuePair("testWithContext", "true"))); + assertThrows(FailingHttpStatusCodeException.class, () -> wc.getPage(request)); } @Test - public void localhost_withoutReferer() { - rr.addStep(new Statement() { - @Override - public void evaluate() throws Throwable { - JenkinsRule j = rr.j; - JenkinsRule.WebClient wc = rr.j.createWebClient(); - WebRequest request = new WebRequest(new URL(j.getURL(), getAdminMonitorTestUrl(j))); - // no referer - assertThrows(FailingHttpStatusCodeException.class, () -> wc.getPage(request)); - } - }); + void localhost_withoutReferer() throws Exception { + JenkinsRule.WebClient wc = j.createWebClient(); + WebRequest request = new WebRequest(new URL(j.getURL(), getAdminMonitorTestUrl(j))); + // no referer + assertThrows(FailingHttpStatusCodeException.class, () -> wc.getPage(request)); } @Test - public void localhost_withRefererNotComingFromManage() { - rr.addStep(new Statement() { - @Override - public void evaluate() throws Throwable { - JenkinsRule j = rr.j; - JenkinsRule.WebClient wc = rr.j.createWebClient(); - WebRequest request = new WebRequest(new URL(j.getURL(), getAdminMonitorTestUrl(j))); - // wrong referer - request.setAdditionalHeader("Referer", j.getURL() + "configure"); - assertThrows(FailingHttpStatusCodeException.class, () -> wc.getPage(request)); - } - }); + void localhost_withRefererNotComingFromManage() throws Exception { + JenkinsRule.WebClient wc = j.createWebClient(); + WebRequest request = new WebRequest(new URL(j.getURL(), getAdminMonitorTestUrl(j))); + // wrong referer + request.setAdditionalHeader("Referer", j.getURL() + "configure"); + assertThrows(FailingHttpStatusCodeException.class, () -> wc.getPage(request)); } @Test - public void withRootURL_localhost_missingContext() { - rr.addStep(new Statement() { - @Override - public void evaluate() throws Throwable { - JenkinsRule j = rr.j; + void withRootURL_localhost_missingContext() throws Exception { + String fullRootUrl = j.getURL().toString(); + String rootUrlWithoutContext = fullRootUrl.replace("/jenkins", ""); + JenkinsLocationConfiguration.get().setUrl(rootUrlWithoutContext); - String fullRootUrl = j.getURL().toString(); - String rootUrlWithoutContext = fullRootUrl.replace("/jenkins", ""); - JenkinsLocationConfiguration.get().setUrl(rootUrlWithoutContext); + JenkinsRule.WebClient wc = j.createWebClient(); + WebRequest request = new WebRequest(new URL(j.getURL(), getAdminMonitorTestUrl(j))); + request.setAdditionalHeader("Referer", j.getURL() + "manage"); - JenkinsRule.WebClient wc = rr.j.createWebClient(); - WebRequest request = new WebRequest(new URL(j.getURL(), getAdminMonitorTestUrl(j))); - request.setAdditionalHeader("Referer", j.getURL() + "manage"); + // As the rootURL is missing the context, a regular test will fail + assertThrows(FailingHttpStatusCodeException.class, () -> wc.getPage(request)); - // As the rootURL is missing the context, a regular test will fail - assertThrows(FailingHttpStatusCodeException.class, () -> wc.getPage(request)); - - // When testing with the context, it will be OK, allowing to display an additional message - request.setRequestParameters(List.of(new NameValuePair("testWithContext", "true"))); - wc.getPage(request); - } - }); + // When testing with the context, it will be OK, allowing to display an additional message + request.setRequestParameters(List.of(new NameValuePair("testWithContext", "true"))); + wc.getPage(request); } @Test - public void withRootURL_localhost_wrongContext() { - rr.addStep(new Statement() { - @Override - public void evaluate() throws Throwable { - JenkinsRule j = rr.j; + void withRootURL_localhost_wrongContext() throws Exception { + String fullRootUrl = j.getURL().toString(); + String rootUrlWithoutContext = fullRootUrl.replace("/jenkins", "/wrong"); + JenkinsLocationConfiguration.get().setUrl(rootUrlWithoutContext); - String fullRootUrl = j.getURL().toString(); - String rootUrlWithoutContext = fullRootUrl.replace("/jenkins", "/wrong"); - JenkinsLocationConfiguration.get().setUrl(rootUrlWithoutContext); + JenkinsRule.WebClient wc = j.createWebClient(); + WebRequest request = new WebRequest(new URL(j.getURL(), getAdminMonitorTestUrl(j))); + request.setAdditionalHeader("Referer", j.getURL() + "manage"); - JenkinsRule.WebClient wc = rr.j.createWebClient(); - WebRequest request = new WebRequest(new URL(j.getURL(), getAdminMonitorTestUrl(j))); - request.setAdditionalHeader("Referer", j.getURL() + "manage"); + assertThrows(FailingHttpStatusCodeException.class, () -> wc.getPage(request)); - assertThrows(FailingHttpStatusCodeException.class, () -> wc.getPage(request)); - - request.setRequestParameters(List.of(new NameValuePair("testWithContext", "true"))); - assertThrows(FailingHttpStatusCodeException.class, () -> wc.getPage(request)); - } - }); + request.setRequestParameters(List.of(new NameValuePair("testWithContext", "true"))); + assertThrows(FailingHttpStatusCodeException.class, () -> wc.getPage(request)); } @Test - public void desiredContextPathEmpty_localhost() { - desiredContextPath = ""; - rr.addStep(new Statement() { - @Override - public void evaluate() throws Throwable { - JenkinsRule j = rr.j; + void desiredContextPathEmpty_localhost() throws Throwable { + j.contextPath = ""; - JenkinsRule.WebClient wc = rr.j.createWebClient(); - WebRequest request = new WebRequest(new URL(j.getURL(), getAdminMonitorTestUrl(j))); - request.setAdditionalHeader("Referer", j.getURL() + "manage"); + j.restart(); - wc.getPage(request); + JenkinsRule.WebClient wc = j.createWebClient(); + WebRequest request = new WebRequest(new URL(j.getURL(), getAdminMonitorTestUrl(j))); + request.setAdditionalHeader("Referer", j.getURL() + "manage"); - // adding the context does not have any impact as there is no configured context - request.setRequestParameters(List.of(new NameValuePair("testWithContext", "true"))); - wc.getPage(request); - } - }); + wc.getPage(request); + + // adding the context does not have any impact as there is no configured context + request.setRequestParameters(List.of(new NameValuePair("testWithContext", "true"))); + wc.getPage(request); } @Test - public void usingIp_butRefererUsingRootUrl() { - rr.addStep(new Statement() { - @Override - public void evaluate() throws Throwable { - JenkinsRule j = rr.j; - JenkinsRule.WebClient wc = rr.j.createWebClient(); - WebRequest request = new WebRequest(new URL(getRootUrlWithIp(j), getAdminMonitorTestUrl(j))); - request.setAdditionalHeader("Referer", j.getURL() + "manage"); - wc.getPage(request); - } - }); + void usingIp_butRefererUsingRootUrl() throws Exception { + JenkinsRule.WebClient wc = j.createWebClient(); + WebRequest request = new WebRequest(new URL(getRootUrlWithIp(j), getAdminMonitorTestUrl(j))); + request.setAdditionalHeader("Referer", j.getURL() + "manage"); + wc.getPage(request); } @Test - public void usingIp_withoutReferer() { - rr.addStep(new Statement() { - @Override - public void evaluate() throws Throwable { - JenkinsRule j = rr.j; - JenkinsRule.WebClient wc = rr.j.createWebClient(); - WebRequest request = new WebRequest(new URL(getRootUrlWithIp(j), getAdminMonitorTestUrl(j))); - // no referer - assertThrows(FailingHttpStatusCodeException.class, () -> wc.getPage(request)); - } - }); + void usingIp_withoutReferer() throws Exception { + JenkinsRule.WebClient wc = j.createWebClient(); + WebRequest request = new WebRequest(new URL(getRootUrlWithIp(j), getAdminMonitorTestUrl(j))); + // no referer + assertThrows(FailingHttpStatusCodeException.class, () -> wc.getPage(request)); } @Test - public void usingIp_withRefererIp() { - rr.addStep(new Statement() { - @Override - public void evaluate() throws Throwable { - JenkinsRule j = rr.j; - JenkinsRule.WebClient wc = rr.j.createWebClient(); - WebRequest request = new WebRequest(new URL(getRootUrlWithIp(j), getAdminMonitorTestUrl(j))); - // referer using IP - request.setAdditionalHeader("Referer", getRootUrlWithIp(j) + "manage"); + void usingIp_withRefererIp() throws Exception { + JenkinsRule.WebClient wc = j.createWebClient(); + WebRequest request = new WebRequest(new URL(getRootUrlWithIp(j), getAdminMonitorTestUrl(j))); + // referer using IP + request.setAdditionalHeader("Referer", getRootUrlWithIp(j) + "manage"); - // by default the JenkinsRule set the rootURL to localhost:/jenkins - // even with similar request and referer, if the root URL is set, this will show a wrong proxy setting - assertThrows(FailingHttpStatusCodeException.class, () -> wc.getPage(request)); - } - }); + // by default the JenkinsRule set the rootURL to localhost:/jenkins + // even with similar request and referer, if the root URL is set, this will show a wrong proxy setting + assertThrows(FailingHttpStatusCodeException.class, () -> wc.getPage(request)); } @Test - public void withRootURL_usingIp_withRefererIp() { - rr.addStep(new Statement() { - @Override - public void evaluate() throws Throwable { - JenkinsRule j = rr.j; - JenkinsLocationConfiguration.get().setUrl(getRootUrlWithIp(j).toString()); + void withRootURL_usingIp_withRefererIp() throws Exception { + JenkinsLocationConfiguration.get().setUrl(getRootUrlWithIp(j).toString()); - JenkinsRule.WebClient wc = rr.j.createWebClient(); - WebRequest request = new WebRequest(new URL(getRootUrlWithIp(j), getAdminMonitorTestUrl(j))); - // referer using IP - request.setAdditionalHeader("Referer", getRootUrlWithIp(j) + "manage"); + JenkinsRule.WebClient wc = j.createWebClient(); + WebRequest request = new WebRequest(new URL(getRootUrlWithIp(j), getAdminMonitorTestUrl(j))); + // referer using IP + request.setAdditionalHeader("Referer", getRootUrlWithIp(j) + "manage"); - wc.getPage(request); - } - }); + wc.getPage(request); } @Test - public void withRootURL_usingIp_missingContext_withRefererIp() { - rr.addStep(new Statement() { - @Override - public void evaluate() throws Throwable { - JenkinsRule j = rr.j; + void withRootURL_usingIp_missingContext_withRefererIp() throws Exception { + String fullRootUrl = getRootUrlWithIp(j).toString(); + String rootUrlWithoutContext = fullRootUrl.replace("/jenkins", ""); + JenkinsLocationConfiguration.get().setUrl(rootUrlWithoutContext); - String fullRootUrl = getRootUrlWithIp(j).toString(); - String rootUrlWithoutContext = fullRootUrl.replace("/jenkins", ""); - JenkinsLocationConfiguration.get().setUrl(rootUrlWithoutContext); + JenkinsRule.WebClient wc = j.createWebClient(); + WebRequest request = new WebRequest(new URL(getRootUrlWithIp(j), getAdminMonitorTestUrl(j))); + // referer using IP + request.setAdditionalHeader("Referer", getRootUrlWithIp(j) + "manage"); - JenkinsRule.WebClient wc = rr.j.createWebClient(); - WebRequest request = new WebRequest(new URL(getRootUrlWithIp(j), getAdminMonitorTestUrl(j))); - // referer using IP - request.setAdditionalHeader("Referer", getRootUrlWithIp(j) + "manage"); + // As the rootURL is missing the context, a regular test will fail + assertThrows(FailingHttpStatusCodeException.class, () -> wc.getPage(request)); - // As the rootURL is missing the context, a regular test will fail - assertThrows(FailingHttpStatusCodeException.class, () -> wc.getPage(request)); - - // When testing with the context, it will be OK, allowing to display an additional message - request.setRequestParameters(List.of(new NameValuePair("testWithContext", "true"))); - wc.getPage(request); - } - }); + // When testing with the context, it will be OK, allowing to display an additional message + request.setRequestParameters(List.of(new NameValuePair("testWithContext", "true"))); + wc.getPage(request); } private String getAdminMonitorTestUrl(JenkinsRule j) { diff --git a/test/src/test/java/hudson/lifecycle/LifecycleTest.java b/test/src/test/java/hudson/lifecycle/LifecycleTest.java index 691dc0477b..91d0cd6eb8 100644 --- a/test/src/test/java/hudson/lifecycle/LifecycleTest.java +++ b/test/src/test/java/hudson/lifecycle/LifecycleTest.java @@ -30,21 +30,21 @@ import static org.hamcrest.Matchers.is; import java.lang.reflect.Field; import java.util.logging.Level; import jenkins.model.Jenkins; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.jvnet.hudson.test.JenkinsRule; -import org.jvnet.hudson.test.RealJenkinsRule; +import org.jvnet.hudson.test.junit.jupiter.RealJenkinsExtension; -public final class LifecycleTest { +class LifecycleTest { - @Rule - public RealJenkinsRule rr = new RealJenkinsRule() + @RegisterExtension + private final RealJenkinsExtension rr = new RealJenkinsExtension() .addPlugins("plugins/custom-lifecycle.hpi") .javaOptions("-Dhudson.lifecycle=test.custom_lifecycle.CustomLifecycle") .withLogger(Lifecycle.class, Level.FINE); @Test - public void definedInPlugin() throws Throwable { + void definedInPlugin() throws Throwable { rr.then(LifecycleTest::_definedInPlugin); } diff --git a/test/src/test/java/hudson/model/AbstractItem2Test.java b/test/src/test/java/hudson/model/AbstractItem2Test.java index 23e2113a01..76d2a61a8c 100644 --- a/test/src/test/java/hudson/model/AbstractItem2Test.java +++ b/test/src/test/java/hudson/model/AbstractItem2Test.java @@ -27,27 +27,26 @@ package hudson.model; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.not; -import static org.junit.Assert.assertEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; import hudson.XmlFile; import java.util.logging.Level; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.jvnet.hudson.test.Issue; -import org.jvnet.hudson.test.JenkinsSessionRule; -import org.jvnet.hudson.test.LoggerRule; +import org.jvnet.hudson.test.LogRecorder; +import org.jvnet.hudson.test.junit.jupiter.JenkinsSessionExtension; -public class AbstractItem2Test { +class AbstractItem2Test { - @Rule - public JenkinsSessionRule sessions = new JenkinsSessionRule(); + @RegisterExtension + private final JenkinsSessionExtension sessions = new JenkinsSessionExtension(); - @Rule - public LoggerRule logging = new LoggerRule().record(XmlFile.class, Level.WARNING).capture(100); + private final LogRecorder logging = new LogRecorder().record(XmlFile.class, Level.WARNING).capture(100); @Issue("JENKINS-45892") @Test - public void badSerialization() throws Throwable { + void badSerialization() throws Throwable { sessions.then(j -> { FreeStyleProject p1 = j.createFreeStyleProject("p1"); p1.setDescription("this is p1"); diff --git a/test/src/test/java/hudson/model/AsyncPeriodicWorkTest.java b/test/src/test/java/hudson/model/AsyncPeriodicWorkTest.java index af9d09561d..c24fc50e68 100644 --- a/test/src/test/java/hudson/model/AsyncPeriodicWorkTest.java +++ b/test/src/test/java/hudson/model/AsyncPeriodicWorkTest.java @@ -8,17 +8,24 @@ import static org.hamcrest.Matchers.lessThan; import hudson.ExtensionList; import java.time.Duration; import java.util.concurrent.TimeUnit; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.jvnet.hudson.test.JenkinsRule; import org.jvnet.hudson.test.TestExtension; +import org.jvnet.hudson.test.junit.jupiter.WithJenkins; -public class AsyncPeriodicWorkTest { - @Rule - public JenkinsRule r = new JenkinsRule(); +@WithJenkins +class AsyncPeriodicWorkTest { + + private JenkinsRule r; + + @BeforeEach + void setUp(JenkinsRule rule) { + r = rule; + } @Test - public void extraCallGetsIgnored() { + void extraCallGetsIgnored() { var instance = ExtensionList.lookupSingleton(AsyncPeriodicWorkTestImpl.class); assertThat(instance.getCount(), is(0)); instance.run(); @@ -29,7 +36,7 @@ public class AsyncPeriodicWorkTest { } @Test - public void extraCallGetsQueued() { + void extraCallGetsQueued() { var instance = ExtensionList.lookupSingleton(AsyncPeriodicWorkTestImpl.class); instance.setQueueIfAlreadyRunning(true); assertThat(instance.getCount(), is(0)); @@ -44,6 +51,7 @@ public class AsyncPeriodicWorkTest { private boolean queueIfAlreadyRunning; private int count = 0; + @SuppressWarnings(value = "checkstyle:redundantmodifier") public AsyncPeriodicWorkTestImpl() { super(AsyncPeriodicWorkTestImpl.class.getSimpleName()); } diff --git a/test/src/test/java/hudson/model/ExecutorTest.java b/test/src/test/java/hudson/model/ExecutorTest.java index dd2b473506..e0c665a028 100644 --- a/test/src/test/java/hudson/model/ExecutorTest.java +++ b/test/src/test/java/hudson/model/ExecutorTest.java @@ -241,7 +241,7 @@ public class ExecutorTest { } @Test - public void recordCauseOfInterruption() throws Exception { + void recordCauseOfInterruption() throws Exception { FreeStyleProject p = j.createFreeStyleProject(); p.getBuildersList().add(TestBuilder.of((build, launcher, listener) -> { Executor exec = build.getExecutor(); diff --git a/test/src/test/java/hudson/model/FileParameterValuePersistenceTest.java b/test/src/test/java/hudson/model/FileParameterValuePersistenceTest.java index 660c305e05..37acc41f6f 100644 --- a/test/src/test/java/hudson/model/FileParameterValuePersistenceTest.java +++ b/test/src/test/java/hudson/model/FileParameterValuePersistenceTest.java @@ -2,8 +2,8 @@ package hudson.model; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; import hudson.Functions; import hudson.tasks.BatchFile; @@ -15,32 +15,32 @@ import java.nio.file.Path; import org.htmlunit.html.HtmlForm; import org.htmlunit.html.HtmlInput; import org.htmlunit.html.HtmlPage; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TemporaryFolder; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.junit.jupiter.api.io.TempDir; import org.jvnet.hudson.test.Issue; import org.jvnet.hudson.test.JenkinsRule; -import org.jvnet.hudson.test.JenkinsSessionRule; +import org.jvnet.hudson.test.junit.jupiter.JenkinsSessionExtension; -public class FileParameterValuePersistenceTest { +class FileParameterValuePersistenceTest { private static final String FILENAME = "file.txt"; private static final String CONTENTS = "foobar"; - @Rule - public JenkinsSessionRule sessions = new JenkinsSessionRule(); + @RegisterExtension + private final JenkinsSessionExtension sessions = new JenkinsSessionExtension(); - @Rule - public TemporaryFolder tmp = new TemporaryFolder(); + @TempDir + private File tmp; @Issue("JENKINS-13536") @Test - public void fileParameterValuePersistence() throws Throwable { + void fileParameterValuePersistence() throws Throwable { sessions.then(j -> { FreeStyleProject p = j.createFreeStyleProject("p"); p.addProperty(new ParametersDefinitionProperty(new FileParameterDefinition(FILENAME, "The file."))); p.getBuildersList().add(Functions.isWindows() ? new BatchFile("type " + FILENAME) : new Shell("cat " + FILENAME)); - File test = tmp.newFile(); + File test = File.createTempFile("junit", null, tmp); Files.writeString(test.toPath(), CONTENTS, StandardCharsets.UTF_8); try (JenkinsRule.WebClient wc = j.createWebClient()) { // ParametersDefinitionProperty/index.jelly sends a 405 diff --git a/test/src/test/java/hudson/model/ProjectTest.java b/test/src/test/java/hudson/model/ProjectTest.java index 389837e46a..6349d374fa 100644 --- a/test/src/test/java/hudson/model/ProjectTest.java +++ b/test/src/test/java/hudson/model/ProjectTest.java @@ -28,12 +28,12 @@ import static java.nio.file.StandardCopyOption.REPLACE_EXISTING; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.instanceOf; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertThrows; -import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; import hudson.EnvVars; import hudson.FilePath; @@ -98,139 +98,149 @@ import org.htmlunit.html.HtmlElement; import org.htmlunit.html.HtmlForm; import org.htmlunit.html.HtmlPage; import org.htmlunit.javascript.host.event.Event; -import org.junit.Ignore; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.jvnet.hudson.reactor.ReactorException; import org.jvnet.hudson.test.FakeChangeLogSCM; -import org.jvnet.hudson.test.InboundAgentRule; import org.jvnet.hudson.test.Issue; import org.jvnet.hudson.test.JenkinsRule; import org.jvnet.hudson.test.TestBuilder; import org.jvnet.hudson.test.TestExtension; +import org.jvnet.hudson.test.junit.jupiter.InboundAgentExtension; +import org.jvnet.hudson.test.junit.jupiter.WithJenkins; import org.kohsuke.stapler.StaplerRequest2; /** * * @author Lucie Votypkova */ +@WithJenkins public class ProjectTest { - @Rule public JenkinsRule j = new JenkinsRule(); - - @Rule public InboundAgentRule inboundAgents = new InboundAgentRule(); + @RegisterExtension + private final InboundAgentExtension inboundAgents = new InboundAgentExtension(); public static boolean createAction = false; public static boolean getFilePath = false; public static boolean createSubTask = false; + private JenkinsRule j; + + @BeforeEach + void setUp(JenkinsRule rule) { + j = rule; + } + @Test - public void testSave() throws IOException, InterruptedException, ReactorException { + void testSave() throws IOException, InterruptedException, ReactorException { FreeStyleProject p = j.createFreeStyleProject("project"); p.disabled = true; p.nextBuildNumber = 5; p.description = "description"; p.save(); j.jenkins.reload(); - assertEquals("All persistent data should be saved.", "description", p.description); - assertEquals("All persistent data should be saved.", 5, p.nextBuildNumber); - assertTrue("All persistent data should be saved", p.disabled); + assertEquals("description", p.description, "All persistent data should be saved."); + assertEquals(5, p.nextBuildNumber, "All persistent data should be saved."); + assertTrue(p.disabled, "All persistent data should be saved"); } @Test - public void testOnCreateFromScratch() throws Exception { + void testOnCreateFromScratch() throws Exception { FreeStyleProject p = j.createFreeStyleProject("project"); j.buildAndAssertSuccess(p); p.removeRun(p.getLastBuild()); createAction = true; p.onCreatedFromScratch(); - assertNotNull("Project should have last build.", p.getLastBuild()); - assertNotNull("Project should have transient action TransientAction.", p.getAction(TransientAction.class)); + assertNotNull(p.getLastBuild(), "Project should have last build."); + assertNotNull(p.getAction(TransientAction.class), "Project should have transient action TransientAction."); createAction = false; } @Test - public void testOnLoad() throws Exception { + void testOnLoad() throws Exception { FreeStyleProject p = j.createFreeStyleProject("project"); j.buildAndAssertSuccess(p); p.removeRun(p.getLastBuild()); createAction = true; p.onLoad(j.jenkins, "project"); - assertNotNull("Project should have a build.", p.getLastBuild()); - assertNotNull("Project should have a scm.", p.getScm()); - assertNotNull("Project should have Transient Action TransientAction.", p.getAction(TransientAction.class)); + assertNotNull(p.getLastBuild(), "Project should have a build."); + assertNotNull(p.getScm(), "Project should have a scm."); + assertNotNull(p.getAction(TransientAction.class), "Project should have Transient Action TransientAction."); createAction = false; } @Test - public void testGetEnvironment() throws Exception { + void testGetEnvironment() throws Exception { FreeStyleProject p = j.createFreeStyleProject("project"); Slave slave = j.createOnlineSlave(); EnvironmentVariablesNodeProperty.Entry entry = new EnvironmentVariablesNodeProperty.Entry("jdk", "some_java"); slave.getNodeProperties().add(new EnvironmentVariablesNodeProperty(entry)); EnvVars var = p.getEnvironment(slave, TaskListener.NULL); - assertEquals("Environment should have set jdk.", "some_java", var.get("jdk")); + assertEquals("some_java", var.get("jdk"), "Environment should have set jdk."); } @Test - public void testPerformDelete() throws Exception { + void testPerformDelete() throws Exception { FreeStyleProject p = j.createFreeStyleProject("project"); p.performDelete(); - assertFalse("Project should be deleted from disk.", p.getConfigFile().exists()); - assertTrue("Project should be disabled when deleting start.", p.isDisabled()); + assertFalse(p.getConfigFile().exists(), "Project should be deleted from disk."); + assertTrue(p.isDisabled(), "Project should be disabled when deleting start."); } @Test - public void testGetAssignedLabel() throws Exception { + void testGetAssignedLabel() throws Exception { FreeStyleProject p = j.createFreeStyleProject("project"); p.setAssignedLabel(j.jenkins.getSelfLabel()); Slave slave = j.createOnlineSlave(); - assertEquals("Project should have Jenkins's self label.", j.jenkins.getSelfLabel(), p.getAssignedLabel()); + assertEquals(j.jenkins.getSelfLabel(), p.getAssignedLabel(), "Project should have Jenkins's self label."); p.setAssignedLabel(null); - assertNull("Project should not have any label.", p.getAssignedLabel()); + assertNull(p.getAssignedLabel(), "Project should not have any label."); p.setAssignedLabel(slave.getSelfLabel()); - assertEquals("Project should have self label of slave", slave.getSelfLabel(), p.getAssignedLabel()); + assertEquals(slave.getSelfLabel(), p.getAssignedLabel(), "Project should have self label of slave"); } @Test - public void testGetAssignedLabelString() throws Exception { + void testGetAssignedLabelString() throws Exception { FreeStyleProject p = j.createFreeStyleProject("project"); Slave slave = j.createOnlineSlave(); - assertNull("Project should not have any label.", p.getAssignedLabelString()); + assertNull(p.getAssignedLabelString(), "Project should not have any label."); p.setAssignedLabel(j.jenkins.getSelfLabel()); - assertNull("Project should return null, because assigned label is Jenkins.", p.getAssignedLabelString()); + assertNull(p.getAssignedLabelString(), "Project should return null, because assigned label is Jenkins."); p.setAssignedLabel(slave.getSelfLabel()); - assertEquals("Project should return name of slave.", slave.getSelfLabel().name, p.getAssignedLabelString()); + assertEquals(slave.getSelfLabel().name, p.getAssignedLabelString(), "Project should return name of slave."); } @Test - public void testGetSomeWorkspace() throws Exception { + void testGetSomeWorkspace() throws Exception { FreeStyleProject p = j.createFreeStyleProject("project"); - assertNull("Project which has never run should not have any workspace.", p.getSomeWorkspace()); + assertNull(p.getSomeWorkspace(), "Project which has never run should not have any workspace."); getFilePath = true; - assertNotNull("Project should have any workspace because WorkspaceBrowser find some.", p.getSomeWorkspace()); + assertNotNull(p.getSomeWorkspace(), "Project should have any workspace because WorkspaceBrowser find some."); getFilePath = false; String cmd = "echo ahoj > some.log"; p.getBuildersList().add(Functions.isWindows() ? new BatchFile(cmd) : new Shell(cmd)); j.buildAndAssertSuccess(p); - assertNotNull("Project should has any workspace.", p.getSomeWorkspace()); + assertNotNull(p.getSomeWorkspace(), "Project should has any workspace."); } @Test - public void testGetSomeBuildWithWorkspace() throws Exception { + void testGetSomeBuildWithWorkspace() throws Exception { FreeStyleProject p = j.createFreeStyleProject("project"); String cmd = "echo ahoj > some.log"; p.getBuildersList().add(Functions.isWindows() ? new BatchFile(cmd) : new Shell(cmd)); - assertNull("Project which has never run should not have any build with workspace.", p.getSomeBuildWithWorkspace()); + assertNull(p.getSomeBuildWithWorkspace(), "Project which has never run should not have any build with workspace."); j.buildAndAssertSuccess(p); - assertEquals("Last build should have workspace.", p.getLastBuild(), p.getSomeBuildWithWorkspace()); + assertEquals(p.getLastBuild(), p.getSomeBuildWithWorkspace(), "Last build should have workspace."); p.getLastBuild().delete(); - assertNull("Project should not have build with some workspace.", p.getSomeBuildWithWorkspace()); + assertNull(p.getSomeBuildWithWorkspace(), "Project should not have build with some workspace."); } @Issue("JENKINS-10450") - @Test public void workspaceBrowsing() throws Exception { + @Test + void workspaceBrowsing() throws Exception { FreeStyleProject p = j.createFreeStyleProject("project"); String cmd = "echo ahoj > some.log"; p.getBuildersList().add(Functions.isWindows() ? new BatchFile(cmd) : new Shell(cmd)); @@ -243,83 +253,83 @@ public class ProjectTest { } @Test - public void testGetQuietPeriod() throws IOException { + void testGetQuietPeriod() throws IOException { FreeStyleProject p = j.createFreeStyleProject("project"); - assertEquals("Quiet period should be default.", j.jenkins.getQuietPeriod(), p.getQuietPeriod()); + assertEquals(j.jenkins.getQuietPeriod(), p.getQuietPeriod(), "Quiet period should be default."); j.jenkins.setQuietPeriod(0); - assertEquals("Quiet period is not set so it should be the same as global quiet period.", 0, p.getQuietPeriod()); + assertEquals(0, p.getQuietPeriod(), "Quiet period is not set so it should be the same as global quiet period."); p.setQuietPeriod(10); - assertEquals("Quiet period was set.", 10, p.getQuietPeriod()); + assertEquals(10, p.getQuietPeriod(), "Quiet period was set."); } @Test - public void testGetScmCheckoutStrategy() throws IOException { + void testGetScmCheckoutStrategy() throws IOException { FreeStyleProject p = j.createFreeStyleProject("project"); p.setScmCheckoutStrategy(null); assertThat("Project should return default checkout strategy if scm checkout strategy is not set.", p.getScmCheckoutStrategy(), instanceOf(DefaultSCMCheckoutStrategyImpl.class)); SCMCheckoutStrategy strategy = new SCMCheckoutStrategyImpl(); p.setScmCheckoutStrategy(strategy); - assertEquals("Project should return its scm checkout strategy if this strategy is not null", strategy, p.getScmCheckoutStrategy()); + assertEquals(strategy, p.getScmCheckoutStrategy(), "Project should return its scm checkout strategy if this strategy is not null"); } @Test - public void testGetScmCheckoutRetryCount() throws Exception { + void testGetScmCheckoutRetryCount() throws Exception { FreeStyleProject p = j.createFreeStyleProject("project"); - assertEquals("Scm retry count should be default.", j.jenkins.getScmCheckoutRetryCount(), p.getScmCheckoutRetryCount()); + assertEquals(j.jenkins.getScmCheckoutRetryCount(), p.getScmCheckoutRetryCount(), "Scm retry count should be default."); j.jenkins.setScmCheckoutRetryCount(6); - assertEquals("Scm retry count should be the same as global scm retry count.", 6, p.getScmCheckoutRetryCount()); + assertEquals(6, p.getScmCheckoutRetryCount(), "Scm retry count should be the same as global scm retry count."); HtmlForm form = j.createWebClient().goTo(p.getUrl() + "/configure").getFormByName("config"); ((HtmlElement) form.querySelectorAll(".advancedButton").get(0)).click(); // required due to the new default behavior of click form.getInputByName("hasCustomScmCheckoutRetryCount").click(new Event(), false, false, false, true); form.getInputByName("scmCheckoutRetryCount").setValue("7"); j.submit(form); - assertEquals("Scm retry count was set.", 7, p.getScmCheckoutRetryCount()); + assertEquals(7, p.getScmCheckoutRetryCount(), "Scm retry count was set."); } @Test - public void isBuildable() throws IOException { + void isBuildable() throws IOException { FreeStyleProject p = j.createFreeStyleProject("project"); - assertTrue("Project should be buildable.", p.isBuildable()); + assertTrue(p.isBuildable(), "Project should be buildable."); p.disable(); - assertFalse("Project should not be buildable if it is disabled.", p.isBuildable()); + assertFalse(p.isBuildable(), "Project should not be buildable if it is disabled."); p.enable(); AbstractProject p2 = (AbstractProject) j.jenkins.copy(j.jenkins.getItem("project"), "project2"); - assertFalse("Project should not be buildable until is saved.", p2.isBuildable()); + assertFalse(p2.isBuildable(), "Project should not be buildable until is saved."); p2.save(); - assertTrue("Project should be buildable after save.", p2.isBuildable()); + assertTrue(p2.isBuildable(), "Project should be buildable after save."); } @Test - public void testMakeDisabled() throws IOException { + void testMakeDisabled() throws IOException { FreeStyleProject p = j.createFreeStyleProject("project"); p.makeDisabled(false); - assertFalse("Project should be enabled.", p.isDisabled()); + assertFalse(p.isDisabled(), "Project should be enabled."); p.makeDisabled(true); - assertTrue("Project should be disabled.", p.isDisabled()); + assertTrue(p.isDisabled(), "Project should be disabled."); p.makeDisabled(false); p.setAssignedLabel(j.jenkins.getLabel("nonExist")); p.scheduleBuild2(0); p.makeDisabled(true); - assertNull("Project should be canceled.", Queue.getInstance().getItem(p)); + assertNull(Queue.getInstance().getItem(p), "Project should be canceled."); } @Test - public void testAddProperty() throws IOException { + void testAddProperty() throws IOException { FreeStyleProject p = j.createFreeStyleProject("project"); JobProperty prop = new JobPropertyImp(); createAction = true; p.addProperty(prop); - assertNotNull("Project does not contain added property.", p.getProperty(prop.getClass())); - assertNotNull("Project did not update transient actions.", p.getAction(TransientAction.class)); + assertNotNull(p.getProperty(prop.getClass()), "Project does not contain added property."); + assertNotNull(p.getAction(TransientAction.class), "Project did not update transient actions."); } @Test - public void testScheduleBuild2() throws Exception { + void testScheduleBuild2() throws Exception { FreeStyleProject p = j.createFreeStyleProject("project"); p.setAssignedLabel(j.jenkins.getLabel("nonExist")); p.scheduleBuild(0, new UserIdCause()); - assertNotNull("Project should be in queue.", Queue.getInstance().getItem(p)); + assertNotNull(Queue.getInstance().getItem(p), "Project should be in queue."); p.setAssignedLabel(null); int count = 0; while (count < 5 && p.getLastBuild() == null) { @@ -327,25 +337,25 @@ public class ProjectTest { count++; } FreeStyleBuild b = p.getLastBuild(); - assertNotNull("Build should be done or in progress.", b); + assertNotNull(b, "Build should be done or in progress."); j.assertBuildStatusSuccess(j.waitForCompletion(b)); } @Test - public void testSchedulePolling() throws IOException { + void testSchedulePolling() throws IOException { FreeStyleProject p = j.createFreeStyleProject("project"); - assertFalse("Project should not schedule polling because no scm trigger is set.", p.schedulePolling()); + assertFalse(p.schedulePolling(), "Project should not schedule polling because no scm trigger is set."); SCMTrigger trigger = new SCMTrigger("0 0 * * *"); p.addTrigger(trigger); trigger.start(p, true); - assertTrue("Project should schedule polling.", p.schedulePolling()); + assertTrue(p.schedulePolling(), "Project should schedule polling."); p.disable(); - assertFalse("Project should not schedule polling because project is disabled.", p.schedulePolling()); + assertFalse(p.schedulePolling(), "Project should not schedule polling because project is disabled."); } @Test - public void testSaveAfterSet() throws Exception { + void testSaveAfterSet() throws Exception { FreeStyleProject p = j.createFreeStyleProject("project"); p.setScm(new NullSCM()); p.setScmCheckoutStrategy(new SCMCheckoutStrategyImpl()); @@ -357,21 +367,21 @@ public class ProjectTest { p.setJDK(j.jenkins.getJDK("jdk")); p.setCustomWorkspace("/some/path"); j.jenkins.reload(); - assertNotNull("Project did not save scm.", p.getScm()); + assertNotNull(p.getScm(), "Project did not save scm."); assertThat("Project did not save scm checkout strategy.", p.getScmCheckoutStrategy(), instanceOf(SCMCheckoutStrategyImpl.class)); - assertEquals("Project did not save quiet period.", 15, p.getQuietPeriod()); - assertTrue("Project did not save block if downstream is building.", p.blockBuildWhenDownstreamBuilding()); - assertTrue("Project did not save block if upstream is building.", p.blockBuildWhenUpstreamBuilding()); - assertNotNull("Project did not save jdk", p.getJDK()); - assertEquals("Project did not save custom workspace.", "/some/path", p.getCustomWorkspace()); + assertEquals(15, p.getQuietPeriod(), "Project did not save quiet period."); + assertTrue(p.blockBuildWhenDownstreamBuilding(), "Project did not save block if downstream is building."); + assertTrue(p.blockBuildWhenUpstreamBuilding(), "Project did not save block if upstream is building."); + assertNotNull(p.getJDK(), "Project did not save jdk"); + assertEquals("/some/path", p.getCustomWorkspace(), "Project did not save custom workspace."); } @Test - public void testGetActions() throws IOException { + void testGetActions() throws IOException { FreeStyleProject p = j.createFreeStyleProject("project"); createAction = true; p.updateTransientActions(); - assertNotNull("Action should contain transient actions too.", p.getAction(TransientAction.class)); + assertNotNull(p.getAction(TransientAction.class), "Action should contain transient actions too."); createAction = false; } @@ -381,7 +391,7 @@ public class ProjectTest { // } @Test - public void testGetCauseOfBlockage() throws Exception { + void testGetCauseOfBlockage() throws Exception { FreeStyleProject p = j.createFreeStyleProject("project"); p.getBuildersList().add(Functions.isWindows() ? new BatchFile("ping -n 10 127.0.0.1 >nul") : new Shell("sleep 10")); QueueTaskFuture b1 = waitForStart(p); @@ -418,7 +428,7 @@ public class ProjectTest { } @Test - public void testGetSubTasks() throws IOException { + void testGetSubTasks() throws IOException { FreeStyleProject p = j.createFreeStyleProject("project"); p.addProperty(new JobPropertyImp()); createSubTask = true; @@ -432,27 +442,27 @@ public class ProjectTest { containsSubTaskImpl2 = true; } createSubTask = false; - assertTrue("Project should return subtasks provided by SubTaskContributor.", containsSubTaskImpl2); - assertTrue("Project should return subtasks provided by JobProperty.", containsSubTaskImpl); + assertTrue(containsSubTaskImpl2, "Project should return subtasks provided by SubTaskContributor."); + assertTrue(containsSubTaskImpl, "Project should return subtasks provided by JobProperty."); } @Test - public void testCreateExecutable() throws IOException { + void testCreateExecutable() throws IOException { FreeStyleProject p = j.createFreeStyleProject("project"); Build build = p.createExecutable(); - assertNotNull("Project should create executable.", build); - assertEquals("CreatedExecutable should be the last build.", build, p.getLastBuild()); - assertEquals("Next build number should be increased.", 2, p.nextBuildNumber); + assertNotNull(build, "Project should create executable."); + assertEquals(build, p.getLastBuild(), "CreatedExecutable should be the last build."); + assertEquals(2, p.nextBuildNumber, "Next build number should be increased."); p.disable(); build = p.createExecutable(); - assertNull("Disabled project should not create executable.", build); - assertEquals("Next build number should not be increased.", 2, p.nextBuildNumber); + assertNull(build, "Disabled project should not create executable."); + assertEquals(2, p.nextBuildNumber, "Next build number should not be increased."); } @Test - public void testCheckout() throws Exception { + void testCheckout() throws Exception { SCM scm = new NullSCM(); FreeStyleProject p = j.createFreeStyleProject("project"); Slave slave = j.createOnlineSlave(); @@ -462,59 +472,59 @@ public class ProjectTest { FilePath path = slave.toComputer().getWorkspaceList().allocate(ws, build).path; build.setWorkspace(path); BuildListener listener = new StreamBuildListener(TaskListener.NULL.getLogger(), Charset.defaultCharset()); - assertTrue("Project with null smc should perform checkout without problems.", p.checkout(build, new RemoteLauncher(listener, slave.getChannel(), true), listener, new File(build.getRootDir(), "changelog.xml"))); + assertTrue(p.checkout(build, new RemoteLauncher(listener, slave.getChannel(), true), listener, new File(build.getRootDir(), "changelog.xml")), "Project with null smc should perform checkout without problems."); p.setScm(scm); - assertTrue("Project should perform checkout without problems.", p.checkout(build, new RemoteLauncher(listener, slave.getChannel(), true), listener, new File(build.getRootDir(), "changelog.xml"))); + assertTrue(p.checkout(build, new RemoteLauncher(listener, slave.getChannel(), true), listener, new File(build.getRootDir(), "changelog.xml")), "Project should perform checkout without problems."); } - @Ignore("randomly failed: Project should have polling result no change expected: but was:") + @Disabled("randomly failed: Project should have polling result no change expected: but was:") @Test - public void testPoll() throws Exception { + void testPoll() throws Exception { FreeStyleProject p = j.createFreeStyleProject("project"); SCM scm = new NullSCM(); p.setScm(null); - assertEquals("Project with null scm should have have polling result no change.", PollingResult.Change.NONE, p.poll(TaskListener.NULL).change); + assertEquals(PollingResult.Change.NONE, p.poll(TaskListener.NULL).change, "Project with null scm should have have polling result no change."); p.setScm(scm); p.disable(); - assertEquals("Project which is disabled should have have polling result no change.", PollingResult.Change.NONE, p.poll(TaskListener.NULL).change); + assertEquals(PollingResult.Change.NONE, p.poll(TaskListener.NULL).change, "Project which is disabled should have have polling result no change."); p.enable(); - assertEquals("Project which has no builds should have have polling result incomparable.", PollingResult.Change.INCOMPARABLE, p.poll(TaskListener.NULL).change); + assertEquals(PollingResult.Change.INCOMPARABLE, p.poll(TaskListener.NULL).change, "Project which has no builds should have have polling result incomparable."); p.setAssignedLabel(j.jenkins.getLabel("nonExist")); p.scheduleBuild2(0); - assertEquals("Project which build is building should have polling result result no change.", PollingResult.Change.NONE, p.poll(TaskListener.NULL).change); + assertEquals(PollingResult.Change.NONE, p.poll(TaskListener.NULL).change, "Project which build is building should have polling result result no change."); p.setAssignedLabel(null); while (p.getLastBuild() == null) Thread.sleep(100); //wait until build start - assertEquals("Project should have polling result no change", PollingResult.Change.NONE, p.poll(TaskListener.NULL).change); + assertEquals(PollingResult.Change.NONE, p.poll(TaskListener.NULL).change, "Project should have polling result no change"); SCM alwaysChange = new AlwaysChangedSCM(); p.setScm(alwaysChange); j.buildAndAssertSuccess(p); - assertEquals("Project should have polling result significant", PollingResult.Change.SIGNIFICANT, p.poll(TaskListener.NULL).change); + assertEquals(PollingResult.Change.SIGNIFICANT, p.poll(TaskListener.NULL).change, "Project should have polling result significant"); } @Test - public void testHasParticipant() throws Exception { + void testHasParticipant() throws Exception { User user = User.get("John Smith", true, Collections.emptyMap()); FreeStyleProject project = j.createFreeStyleProject("project"); FreeStyleProject project2 = j.createFreeStyleProject("project2"); FakeChangeLogSCM scm = new FakeChangeLogSCM(); project2.setScm(scm); j.buildAndAssertSuccess(project2); - assertFalse("Project should not have any participant.", project2.hasParticipant(user)); + assertFalse(project2.hasParticipant(user), "Project should not have any participant."); scm.addChange().withAuthor(user.getId()); project.setScm(scm); j.buildAndAssertSuccess(project); - assertTrue("Project should have participant.", project.hasParticipant(user)); + assertTrue(project.hasParticipant(user), "Project should have participant."); } @Test - public void testGetRelationship() throws Exception { + void testGetRelationship() throws Exception { final FreeStyleProject upstream = j.createFreeStyleProject("upstream"); FreeStyleProject downstream = j.createFreeStyleProject("downstream"); j.buildAndAssertSuccess(upstream); j.buildAndAssertSuccess(upstream); j.buildAndAssertSuccess(downstream); - assertTrue("Project upstream should not have any relationship with downstream", upstream.getRelationship(downstream).isEmpty()); + assertTrue(upstream.getRelationship(downstream).isEmpty(), "Project upstream should not have any relationship with downstream"); upstream.getPublishersList().add(new Fingerprinter("change.log", true)); upstream.getBuildersList().add(new WorkspaceWriter("change.log", "hello")); @@ -542,17 +552,17 @@ public class ProjectTest { j.buildAndAssertSuccess(downstream); Map relationship = upstream.getRelationship(downstream); - assertFalse("Project upstream should have relationship with downstream", relationship.isEmpty()); - assertTrue("Relationship should contain upstream #3", relationship.containsKey(3)); - assertFalse("Relationship should not contain upstream #4 because previous fingerprinted file was not changed since #3", relationship.containsKey(4)); - assertEquals("downstream #2 should be the first build which depends on upstream #3", 2, relationship.get(3).min()); - assertEquals("downstream #3 should be the last build which depends on upstream #3", 3, relationship.get(3).max() - 1); - assertEquals("downstream #4 should depend only on upstream #5", 4, relationship.get(5).min()); - assertEquals("downstream #4 should depend only on upstream #5", 4, relationship.get(5).max() - 1); + assertFalse(relationship.isEmpty(), "Project upstream should have relationship with downstream"); + assertTrue(relationship.containsKey(3), "Relationship should contain upstream #3"); + assertFalse(relationship.containsKey(4), "Relationship should not contain upstream #4 because previous fingerprinted file was not changed since #3"); + assertEquals(2, relationship.get(3).min(), "downstream #2 should be the first build which depends on upstream #3"); + assertEquals(3, relationship.get(3).max() - 1, "downstream #3 should be the last build which depends on upstream #3"); + assertEquals(4, relationship.get(5).min(), "downstream #4 should depend only on upstream #5"); + assertEquals(4, relationship.get(5).max() - 1, "downstream #4 should depend only on upstream #5"); } @Test - public void testDoCancelQueue() throws Exception { + void testDoCancelQueue() throws Exception { FreeStyleProject project = j.createFreeStyleProject("project"); GlobalMatrixAuthorizationStrategy auth = new GlobalMatrixAuthorizationStrategy(); j.jenkins.setAuthorizationStrategy(auth); @@ -561,12 +571,12 @@ public class ProjectTest { j.jenkins.setSecurityRealm(realm); User user = realm.createAccount("John Smith", "password"); try (ACLContext as = ACL.as(user)) { - assertThrows("User should not have permission to build project", AccessDeniedException3.class, () -> project.doCancelQueue(null, null)); + assertThrows(AccessDeniedException3.class, () -> project.doCancelQueue(null, null), "User should not have permission to build project"); } } @Test - public void testDoDoDelete() throws Exception { + void testDoDoDelete() throws Exception { FreeStyleProject project = j.createFreeStyleProject("project"); GlobalMatrixAuthorizationStrategy auth = new GlobalMatrixAuthorizationStrategy(); j.jenkins.setAuthorizationStrategy(auth); @@ -574,7 +584,7 @@ public class ProjectTest { j.jenkins.setSecurityRealm(j.createDummySecurityRealm()); User user = User.getById("john", true); try (ACLContext as = ACL.as(user)) { - assertThrows("User should not have permission to build project", AccessDeniedException3.class, () -> project.doDoDelete((StaplerRequest2) null, null)); + assertThrows(AccessDeniedException3.class, () -> project.doDoDelete((StaplerRequest2) null, null), "User should not have permission to build project"); } auth.add(Jenkins.READ, user.getId()); auth.add(Item.READ, user.getId()); @@ -591,12 +601,12 @@ public class ProjectTest { j.submit(form); } } - assertNull("Project should be deleted form memory.", j.jenkins.getItem(project.getDisplayName())); - assertFalse("Project should be deleted form disk.", project.getRootDir().exists()); + assertNull(j.jenkins.getItem(project.getDisplayName()), "Project should be deleted form memory."); + assertFalse(project.getRootDir().exists(), "Project should be deleted form disk."); } @Test - public void testDoDoWipeOutWorkspace() throws Exception { + void testDoDoWipeOutWorkspace() throws Exception { FreeStyleProject project = j.createFreeStyleProject("project"); GlobalMatrixAuthorizationStrategy auth = new GlobalMatrixAuthorizationStrategy(); j.jenkins.setAuthorizationStrategy(auth); @@ -605,7 +615,7 @@ public class ProjectTest { j.jenkins.setSecurityRealm(realm); User user = realm.createAccount("John Smith", "password"); try (ACLContext as = ACL.as(user)) { - assertThrows("User should not have permission to build project", AccessDeniedException3.class, project::doDoWipeOutWorkspace); + assertThrows(AccessDeniedException3.class, project::doDoWipeOutWorkspace, "User should not have permission to build project"); } auth.add(Item.READ, user.getId()); auth.add(Item.BUILD, user.getId()); @@ -624,11 +634,11 @@ public class ProjectTest { assertEquals(200, p.getWebResponse().getStatusCode()); Thread.sleep(500); - assertFalse("Workspace should not exist.", project.getSomeWorkspace().exists()); + assertFalse(project.getSomeWorkspace().exists(), "Workspace should not exist."); } @Test - public void testDoDisable() throws Exception { + void testDoDisable() throws Exception { FreeStyleProject project = j.createFreeStyleProject("project"); GlobalMatrixAuthorizationStrategy auth = new GlobalMatrixAuthorizationStrategy(); j.jenkins.setAuthorizationStrategy(auth); @@ -637,7 +647,7 @@ public class ProjectTest { j.jenkins.setSecurityRealm(realm); User user = realm.createAccount("John Smith", "password"); try (ACLContext as = ACL.as(user)) { - assertThrows("User should not have permission to build project", AccessDeniedException3.class, project::doDisable); + assertThrows(AccessDeniedException3.class, project::doDisable, "User should not have permission to build project"); } auth.add(Item.READ, user.getId()); auth.add(Item.CONFIGURE, user.getId()); @@ -651,11 +661,11 @@ public class ProjectTest { form.getInputByName("enable").click(); j.submit(form); - assertTrue("Project should be disabled.", project.isDisabled()); + assertTrue(project.isDisabled(), "Project should be disabled."); } @Test - public void testDoEnable() throws Exception { + void testDoEnable() throws Exception { FreeStyleProject project = j.createFreeStyleProject("project"); GlobalMatrixAuthorizationStrategy auth = new GlobalMatrixAuthorizationStrategy(); j.jenkins.setAuthorizationStrategy(auth); @@ -667,7 +677,7 @@ public class ProjectTest { project.disable(); } try (ACLContext as = ACL.as(user)) { - assertThrows("User should not have permission to build project", AccessDeniedException3.class, project::doEnable); + assertThrows(AccessDeniedException3.class, project::doEnable, "User should not have permission to build project"); } auth.add(Item.READ, user.getId()); auth.add(Item.CONFIGURE, user.getId()); @@ -683,14 +693,14 @@ public class ProjectTest { j.submit(form); } } - assertFalse("Project should be enabled.", project.isDisabled()); + assertFalse(project.isDisabled(), "Project should be enabled."); } /** * Job is un-restricted (no nabel), this is submitted to queue, which spawns an on demand slave */ @Test - public void testJobSubmittedShouldSpawnCloud() throws Exception { + void testJobSubmittedShouldSpawnCloud() throws Exception { /* * Setup a project with an SCM. Jenkins should have no executors in itself. */ @@ -720,7 +730,7 @@ public class ProjectTest { * Job is restricted, but label can not be provided by any cloud, only normal agents. Then job will not submit, because no slave is available. */ @Test - public void testUnrestrictedJobNoLabelByCloudNoQueue() throws Exception { + void testUnrestrictedJobNoLabelByCloudNoQueue() throws Exception { assertTrue(j.jenkins.clouds.isEmpty()); //Create slave. (Online) Slave s1 = j.createOnlineSlave(); @@ -737,7 +747,7 @@ public class ProjectTest { //Now create another slave. And restrict the job to that slave. The slave is offline, leaving the job with no assignable nodes. //We tell our mock SCM to return that it has got changes. But since there are no agents, we get the desired result. - Slave s2 = inboundAgents.createAgent(j, InboundAgentRule.Options.newBuilder().skipStart().build()); + Slave s2 = inboundAgents.createAgent(j, InboundAgentExtension.Options.newBuilder().skipStart().build()); proj.setAssignedLabel(s2.getSelfLabel()); requiresWorkspaceScm.hasChange = true; @@ -764,7 +774,7 @@ public class ProjectTest { * Job is restricted. Label is on slave that can be started in cloud. Job is submitted to queue, which spawns an on demand slave. */ @Test - public void testRestrictedLabelOnSlaveYesQueue() throws Exception { + void testRestrictedLabelOnSlaveYesQueue() throws Exception { FreeStyleProject proj = j.createFreeStyleProject("JENKINS-21394-yesqueue"); RequiresWorkspaceSCM requiresWorkspaceScm = new RequiresWorkspaceSCM(true); proj.setScm(requiresWorkspaceScm); @@ -791,7 +801,7 @@ public class ProjectTest { @Issue("JENKINS-22750") @Test - public void testMasterJobPutInQueue() throws Exception { + void testMasterJobPutInQueue() throws Exception { FreeStyleProject proj = j.createFreeStyleProject("JENKINS-21394-yes-master-queue"); RequiresWorkspaceSCM requiresWorkspaceScm = new RequiresWorkspaceSCM(true); proj.setAssignedLabel(null); @@ -955,7 +965,7 @@ public class ProjectTest { } - public class ActionImpl extends InvisibleAction{ + public static class ActionImpl extends InvisibleAction { } diff --git a/test/src/test/java/hudson/model/QueueRestartTest.java b/test/src/test/java/hudson/model/QueueRestartTest.java index 5fac5ea498..73da9e1f02 100644 --- a/test/src/test/java/hudson/model/QueueRestartTest.java +++ b/test/src/test/java/hudson/model/QueueRestartTest.java @@ -24,28 +24,29 @@ package hudson.model; -import static org.junit.Assert.assertFalse; +import static org.junit.jupiter.api.Assertions.assertFalse; import java.io.File; import java.io.IOException; import java.util.concurrent.TimeUnit; -import org.junit.Ignore; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.jvnet.hudson.test.Issue; import org.jvnet.hudson.test.JenkinsRule; -import org.jvnet.hudson.test.RealJenkinsRule; +import org.jvnet.hudson.test.junit.jupiter.RealJenkinsExtension; import org.jvnet.hudson.test.recipes.LocalData; -public class QueueRestartTest { +class QueueRestartTest { - @Rule public RealJenkinsRule rr = new RealJenkinsRule(); + @RegisterExtension + private final RealJenkinsExtension rr = new RealJenkinsExtension(); - @Ignore("Pending JENKINS-68319 sometimes fails, in CI & locally") + @Disabled("Pending JENKINS-68319 sometimes fails, in CI & locally") @Issue("JENKINS-68319") @LocalData("quietDown") @Test - public void persistQueueOnRestart() throws Throwable { + void persistQueueOnRestart() throws Throwable { // Avoid periodic save in order to test that the cleanup process saves the queue. rr.javaOptions("-Dhudson.model.Queue.Saver.DELAY_SECONDS=" + TimeUnit.DAYS.toSeconds(1)); @@ -53,11 +54,11 @@ public class QueueRestartTest { rr.then(QueueRestartTest::assertBuildFinishes); } - @Ignore("Pending JENKINS-68319 sometimes fails, in CI & locally") + @Disabled("Pending JENKINS-68319 sometimes fails, in CI & locally") @Issue("JENKINS-68319") @LocalData("quietDown") @Test - public void persistQueueOnConsecutiveRestarts() throws Throwable { + void persistQueueOnConsecutiveRestarts() throws Throwable { // Avoid periodic save in order to test that the cleanup process saves the queue. rr.javaOptions("-Dhudson.model.Queue.Saver.DELAY_SECONDS=" + TimeUnit.DAYS.toSeconds(1)); diff --git a/test/src/test/java/hudson/model/RunActionTest.java b/test/src/test/java/hudson/model/RunActionTest.java index 2b077fe7f4..2c0d4a76b5 100644 --- a/test/src/test/java/hudson/model/RunActionTest.java +++ b/test/src/test/java/hudson/model/RunActionTest.java @@ -27,23 +27,23 @@ package hudson.model; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.not; -import static org.junit.Assert.assertEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; import hudson.XmlFile; import java.io.File; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.jvnet.hudson.test.Issue; -import org.jvnet.hudson.test.JenkinsSessionRule; +import org.jvnet.hudson.test.junit.jupiter.JenkinsSessionExtension; -public class RunActionTest { +class RunActionTest { - @Rule - public JenkinsSessionRule sessions = new JenkinsSessionRule(); + @RegisterExtension + private final JenkinsSessionExtension sessions = new JenkinsSessionExtension(); @Issue("JENKINS-45892") @Test - public void badSerialization() throws Throwable { + void badSerialization() throws Throwable { sessions.then(j -> { FreeStyleProject p = j.createFreeStyleProject("p"); FreeStyleBuild b1 = j.buildAndAssertSuccess(p); diff --git a/test/src/test/java/hudson/model/UserRestartTest.java b/test/src/test/java/hudson/model/UserRestartTest.java index d5b84b3520..c7c7172b82 100644 --- a/test/src/test/java/hudson/model/UserRestartTest.java +++ b/test/src/test/java/hudson/model/UserRestartTest.java @@ -28,8 +28,8 @@ 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.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; import hudson.FilePath; import hudson.tasks.Mailer; @@ -37,18 +37,19 @@ import java.net.URI; import java.nio.charset.StandardCharsets; import java.util.Base64; import org.htmlunit.WebRequest; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.jvnet.hudson.test.Issue; import org.jvnet.hudson.test.JenkinsRule; -import org.jvnet.hudson.test.JenkinsSessionRule; +import org.jvnet.hudson.test.junit.jupiter.JenkinsSessionExtension; -public class UserRestartTest { +class UserRestartTest { - @Rule - public JenkinsSessionRule sessions = new JenkinsSessionRule(); + @RegisterExtension + private final JenkinsSessionExtension sessions = new JenkinsSessionExtension(); - @Test public void persistedUsers() throws Throwable { + @Test + void persistedUsers() throws Throwable { sessions.then(r -> { User bob = User.getById("bob", true); bob.setFullName("Bob"); @@ -66,7 +67,7 @@ public class UserRestartTest { @Issue("JENKINS-45892") @Test - public void badSerialization() throws Throwable { + void badSerialization() throws Throwable { sessions.then(r -> { r.jenkins.setSecurityRealm(r.createDummySecurityRealm()); FreeStyleProject p = r.createFreeStyleProject("p"); @@ -103,7 +104,7 @@ public class UserRestartTest { @Test @Issue("SECURITY-897") - public void legacyConfigMoveCannotEscapeUserFolder() throws Throwable { + void legacyConfigMoveCannotEscapeUserFolder() throws Throwable { sessions.then(r -> { r.jenkins.setSecurityRealm(r.createDummySecurityRealm()); assertThat(r.jenkins.isUseSecurity(), equalTo(true)); diff --git a/test/src/test/java/hudson/node_monitors/ResponseTimeMonitorTest.java b/test/src/test/java/hudson/node_monitors/ResponseTimeMonitorTest.java index 99b9d85c27..8cfbddc54c 100644 --- a/test/src/test/java/hudson/node_monitors/ResponseTimeMonitorTest.java +++ b/test/src/test/java/hudson/node_monitors/ResponseTimeMonitorTest.java @@ -1,9 +1,9 @@ package hudson.node_monitors; import static org.awaitility.Awaitility.await; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; import hudson.model.Computer; import hudson.model.ComputerSet; @@ -14,29 +14,36 @@ import hudson.slaves.OfflineCause; import hudson.slaves.SlaveComputer; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; -import org.junit.Rule; -import org.junit.Test; -import org.jvnet.hudson.test.InboundAgentRule; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.jvnet.hudson.test.Issue; import org.jvnet.hudson.test.JenkinsRule; +import org.jvnet.hudson.test.junit.jupiter.InboundAgentExtension; +import org.jvnet.hudson.test.junit.jupiter.WithJenkins; /** * @author Andrew Bayer */ -public class ResponseTimeMonitorTest { +@WithJenkins +class ResponseTimeMonitorTest { - @Rule - public JenkinsRule j = new JenkinsRule(); + @RegisterExtension + private final InboundAgentExtension inboundAgents = new InboundAgentExtension(); - @Rule - public InboundAgentRule inboundAgents = new InboundAgentRule(); + private JenkinsRule j; + + @BeforeEach + void setUp(JenkinsRule rule) { + j = rule; + } /** * Makes sure that it doesn't try to monitor an already-offline agent. */ @Test @Issue("JENKINS-20272") - public void skipOfflineAgent() throws Exception { + void skipOfflineAgent() throws Exception { DumbSlave s = j.createSlave(); SlaveComputer c = s.getComputer(); c.connect(false).get(); // wait until it's connected @@ -64,8 +71,8 @@ public class ResponseTimeMonitorTest { } @Test - public void doNotDisconnectBeforeLaunched() throws Exception { - Slave slave = inboundAgents.createAgent(j, InboundAgentRule.Options.newBuilder().skipStart().build()); + void doNotDisconnectBeforeLaunched() throws Exception { + Slave slave = inboundAgents.createAgent(j, InboundAgentExtension.Options.newBuilder().skipStart().build()); Computer c = slave.toComputer(); assertNotNull(c); OfflineCause originalOfflineCause = c.getOfflineCause(); diff --git a/test/src/test/java/hudson/security/HudsonPrivateSecurityRealmFIPSTest.java b/test/src/test/java/hudson/security/HudsonPrivateSecurityRealmFIPSTest.java index 9fdcff52b9..a171473273 100644 --- a/test/src/test/java/hudson/security/HudsonPrivateSecurityRealmFIPSTest.java +++ b/test/src/test/java/hudson/security/HudsonPrivateSecurityRealmFIPSTest.java @@ -29,7 +29,7 @@ import static org.hamcrest.Matchers.hasItem; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.not; import static org.hamcrest.Matchers.startsWith; -import static org.junit.Assert.assertThrows; +import static org.junit.jupiter.api.Assertions.assertThrows; import hudson.logging.LogRecorder; import hudson.logging.LogRecorderManager; @@ -45,29 +45,28 @@ import org.htmlunit.FailingHttpStatusCodeException; import org.htmlunit.html.HtmlForm; import org.htmlunit.html.HtmlPage; import org.htmlunit.html.HtmlPasswordInput; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.jvnet.hudson.test.For; import org.jvnet.hudson.test.JenkinsRule; import org.jvnet.hudson.test.JenkinsRule.WebClient; -import org.jvnet.hudson.test.RealJenkinsRule; +import org.jvnet.hudson.test.junit.jupiter.RealJenkinsExtension; import org.jvnet.hudson.test.recipes.LocalData; - @For(HudsonPrivateSecurityRealm.class) -public class HudsonPrivateSecurityRealmFIPSTest { +class HudsonPrivateSecurityRealmFIPSTest { // the bcrypt encoded form of "passwordpassword" without the quotes private static final String JBCRYPT_ENCODED_PASSWORD = "#jbcrypt:$2a$10$Nm37vwdZwJ5T2QTBwYuBYONHD3qKilgd5UO7wuDXI83z5dAdrgi4i"; private static final String LOG_RECORDER_NAME = "HPSR_LOG_RECORDER"; - @Rule - public RealJenkinsRule rjr = new RealJenkinsRule().includeTestClasspathPlugins(false) + @RegisterExtension + private final RealJenkinsExtension rjr = new RealJenkinsExtension().includeTestClasspathPlugins(false) .javaOptions("-Xmx256M", "-Djenkins.security.FIPS140.COMPLIANCE=true"); @Test - public void generalLogin() throws Throwable { + void generalLogin() throws Throwable { rjr.then(HudsonPrivateSecurityRealmFIPSTest::generalLoginStep); } @@ -90,7 +89,7 @@ public class HudsonPrivateSecurityRealmFIPSTest { } @Test - public void userCreationWithHashedPasswords() throws Throwable { + void userCreationWithHashedPasswords() throws Throwable { rjr.then(HudsonPrivateSecurityRealmFIPSTest::userCreationWithHashedPasswordsStep); } @@ -112,11 +111,11 @@ public class HudsonPrivateSecurityRealmFIPSTest { @Test @LocalData - public void userLoginAfterEnablingFIPS() throws Throwable { + void userLoginAfterEnablingFIPS() throws Throwable { rjr.then(HudsonPrivateSecurityRealmFIPSTest::userLoginAfterEnablingFIPSStep); } - private static void userLoginAfterEnablingFIPSStep(JenkinsRule j) throws Exception { + private static void userLoginAfterEnablingFIPSStep(JenkinsRule j) { setupLogRecorder(); HudsonPrivateSecurityRealm securityRealm = new HudsonPrivateSecurityRealm(false, false, null); j.jenkins.setSecurityRealm(securityRealm); @@ -130,12 +129,12 @@ public class HudsonPrivateSecurityRealmFIPSTest { } @Test - public void userCreationWithJBCryptPasswords() throws Throwable { + void userCreationWithJBCryptPasswords() throws Throwable { rjr.then(HudsonPrivateSecurityRealmFIPSTest::userCreationWithJBCryptPasswordsStep); } - private static void userCreationWithJBCryptPasswordsStep(JenkinsRule j) throws Exception { + private static void userCreationWithJBCryptPasswordsStep(JenkinsRule j) { HudsonPrivateSecurityRealm securityRealm = new HudsonPrivateSecurityRealm(false, false, null); IllegalArgumentException illegalArgumentException = assertThrows(IllegalArgumentException.class, @@ -145,7 +144,7 @@ public class HudsonPrivateSecurityRealmFIPSTest { } @Test - public void validatePasswordLengthForFIPS() throws Throwable { + void validatePasswordLengthForFIPS() throws Throwable { rjr.then(HudsonPrivateSecurityRealmFIPSTest::validatePasswordLengthForFIPSStep); } @@ -166,13 +165,12 @@ public class HudsonPrivateSecurityRealmFIPSTest { password2.setText("mockPassword"); HtmlForm form = configurePage.getFormByName("config"); - assertThrows(FailingHttpStatusCodeException.class, () -> { - j.submit(form); - }); + assertThrows(FailingHttpStatusCodeException.class, () -> + j.submit(form)); } @Test - public void validatePasswordMismatchForFIPS() throws Throwable { + void validatePasswordMismatchForFIPS() throws Throwable { rjr.then(HudsonPrivateSecurityRealmFIPSTest::validatePasswordMismatchForFIPSStep); } @@ -194,13 +192,12 @@ public class HudsonPrivateSecurityRealmFIPSTest { password2.setText("14charPa$$word"); HtmlForm form = configurePage.getFormByName("config"); - assertThrows(FailingHttpStatusCodeException.class, () -> { - j.submit(form); - }); + assertThrows(FailingHttpStatusCodeException.class, () -> + j.submit(form)); } @Test - public void validatePasswordSuccessForFIPS() throws Throwable { + void validatePasswordSuccessForFIPS() throws Throwable { rjr.then(HudsonPrivateSecurityRealmFIPSTest::validatePasswordSuccessForFIPSStep); } diff --git a/test/src/test/java/hudson/security/LoginTest.java b/test/src/test/java/hudson/security/LoginTest.java index 30b016d717..16668db540 100644 --- a/test/src/test/java/hudson/security/LoginTest.java +++ b/test/src/test/java/hudson/security/LoginTest.java @@ -3,9 +3,9 @@ package hudson.security; import static jakarta.servlet.http.HttpServletResponse.SC_UNAUTHORIZED; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; import hudson.model.User; import java.io.IOException; @@ -14,30 +14,34 @@ import jenkins.model.Jenkins; import org.htmlunit.html.HtmlForm; import org.htmlunit.html.HtmlFormUtil; import org.htmlunit.html.HtmlPage; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.jvnet.hudson.test.JenkinsRule; import org.jvnet.hudson.test.JenkinsRule.WebClient; import org.jvnet.hudson.test.MockAuthorizationStrategy; -import org.jvnet.hudson.test.recipes.PresetData; -import org.jvnet.hudson.test.recipes.PresetData.DataSet; +import org.jvnet.hudson.test.junit.jupiter.WithJenkins; import org.springframework.security.web.authentication.rememberme.AbstractRememberMeServices; import org.xml.sax.SAXException; /** * @author Kohsuke Kawaguchi */ -public class LoginTest { +@WithJenkins +class LoginTest { - @Rule - public JenkinsRule j = new JenkinsRule(); + private JenkinsRule j; + + @BeforeEach + void setUp(JenkinsRule rule) { + j = rule; + } /** * Requesting a loginError page directly should result in a redirect, * on a non-secured Hudson. */ @Test - public void loginErrorRedirect1() throws Exception { + void loginErrorRedirect1() throws Exception { verifyNotError(j.createWebClient()); } @@ -52,8 +56,13 @@ public class LoginTest { * Same as {@link #loginErrorRedirect1()} if the user has already successfully authenticated. */ @Test - @PresetData(DataSet.ANONYMOUS_READONLY) - public void loginErrorRedirect2() throws Exception { + void loginErrorRedirect2() throws Exception { + JenkinsRule.DummySecurityRealm realm = j.createDummySecurityRealm(); + j.jenkins.setSecurityRealm(realm); + j.jenkins.setAuthorizationStrategy(new MockAuthorizationStrategy() + .grant(Jenkins.READ).everywhere().toEveryone() + .grant(Jenkins.ADMINISTER).everywhere().toAuthenticated()); + // in a secured Hudson, the error page should render. WebClient wc = j.createWebClient(); wc.assertFails("loginError", SC_UNAUTHORIZED); @@ -62,7 +71,7 @@ public class LoginTest { } @Test - public void loginError() throws Exception { + void loginError() throws Exception { j.jenkins.setSecurityRealm(j.createDummySecurityRealm()); j.jenkins.setAuthorizationStrategy(new MockAuthorizationStrategy().grant(Jenkins.ADMINISTER).everywhere().toAuthenticated()); WebClient wc = j.createWebClient(); @@ -97,8 +106,13 @@ public class LoginTest { * Test 'remember me' cookie */ @Test - @PresetData(DataSet.SECURED_ACEGI) - public void loginRememberMe() throws Exception { + void loginRememberMe() throws Exception { + JenkinsRule.DummySecurityRealm realm = j.createDummySecurityRealm(); + j.jenkins.setSecurityRealm(realm); + j.jenkins.setAuthorizationStrategy(new MockAuthorizationStrategy() + .grant(Jenkins.READ).everywhere().toEveryone() + .grant(Jenkins.ADMINISTER).everywhere().toAuthenticated()); + WebClient wc = j.createWebClient(); HtmlFormUtil.submit(prepareLoginFormWithRememberMeChecked(wc), null); @@ -111,8 +125,13 @@ public class LoginTest { * This models the case when the feature is disabled between another user loading and submitting the login page. */ @Test - @PresetData(DataSet.SECURED_ACEGI) - public void loginDisabledRememberMe() throws Exception { + void loginDisabledRememberMe() throws Exception { + JenkinsRule.DummySecurityRealm realm = j.createDummySecurityRealm(); + j.jenkins.setSecurityRealm(realm); + j.jenkins.setAuthorizationStrategy(new MockAuthorizationStrategy() + .grant(Jenkins.READ).everywhere().toEveryone() + .grant(Jenkins.ADMINISTER).everywhere().toAuthenticated()); + WebClient wc = j.createWebClient(); HtmlForm form = prepareLoginFormWithRememberMeChecked(wc); diff --git a/test/src/test/java/hudson/slaves/AgentInboundUrlTest.java b/test/src/test/java/hudson/slaves/AgentInboundUrlTest.java index ca6b1ac50e..9bf4f1ad32 100644 --- a/test/src/test/java/hudson/slaves/AgentInboundUrlTest.java +++ b/test/src/test/java/hudson/slaves/AgentInboundUrlTest.java @@ -24,7 +24,7 @@ package hudson.slaves; -import static org.junit.Assert.assertEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; import hudson.model.Slave; import java.util.logging.Level; @@ -33,44 +33,60 @@ import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.io.DOMReader; import org.htmlunit.xml.XmlPage; -import org.junit.Rule; -import org.junit.Test; -import org.jvnet.hudson.test.FlagRule; -import org.jvnet.hudson.test.InboundAgentRule; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.jvnet.hudson.test.Issue; import org.jvnet.hudson.test.JenkinsRule; -import org.jvnet.hudson.test.LoggerRule; +import org.jvnet.hudson.test.LogRecorder; import org.jvnet.hudson.test.MockAuthorizationStrategy; +import org.jvnet.hudson.test.junit.jupiter.InboundAgentExtension; +import org.jvnet.hudson.test.junit.jupiter.WithJenkins; /** * Tests of {@link JNLPLauncher} using a custom inbound agent url. */ -public class AgentInboundUrlTest { - @Rule - public JenkinsRule j = new JenkinsRule(); +@WithJenkins +class AgentInboundUrlTest { - @Rule - public InboundAgentRule inboundAgents = new InboundAgentRule(); + @RegisterExtension + private final InboundAgentExtension inboundAgents = new InboundAgentExtension(); - @Rule - public LoggerRule logging = new LoggerRule().record(Slave.class, Level.FINE); + private final LogRecorder logging = new LogRecorder().record(Slave.class, Level.FINE); // Override the inbound agent url - private static final String customInboundUrl = "http://localhost:8080/jenkins"; + private static final String CUSTOM_INBOUND_URL = "http://localhost:8080/jenkins"; - @Rule - public final FlagRule customInboundUrlRule = FlagRule.systemProperty(JNLPLauncher.CUSTOM_INBOUND_URL_PROPERTY, customInboundUrl); + private String customInboundUrlRule; + + private JenkinsRule j; + + @BeforeEach + void setUp(JenkinsRule rule) { + j = rule; + customInboundUrlRule = System.setProperty(JNLPLauncher.CUSTOM_INBOUND_URL_PROPERTY, CUSTOM_INBOUND_URL); + } + + @AfterEach + void tearDown() { + if (customInboundUrlRule != null) { + System.setProperty(JNLPLauncher.CUSTOM_INBOUND_URL_PROPERTY, customInboundUrlRule); + } else { + System.clearProperty(JNLPLauncher.CUSTOM_INBOUND_URL_PROPERTY); + } + } @Issue("JENKINS-63222") @Test - public void testInboundAgentUrlOverride() throws Exception { + void testInboundAgentUrlOverride() throws Exception { j.jenkins.setSecurityRealm(j.createDummySecurityRealm()); MockAuthorizationStrategy authorizationStrategy = new MockAuthorizationStrategy(); authorizationStrategy.grant(Jenkins.ADMINISTER).everywhere().toEveryone(); j.jenkins.setAuthorizationStrategy(authorizationStrategy); // Create an agent - inboundAgents.createAgent(j, InboundAgentRule.Options.newBuilder().name("test").skipStart().build()); + inboundAgents.createAgent(j, InboundAgentExtension.Options.newBuilder().name("test").skipStart().build()); // parse the JNLP page into DOM to inspect the jnlp url argument. JenkinsRule.WebClient agent = j.createWebClient(); @@ -78,6 +94,6 @@ public class AgentInboundUrlTest { Document dom = new DOMReader().read(jnlp.getXmlDocument()); Object arg = dom.selectSingleNode("//application-desc/argument[7]/following-sibling::argument[1]"); String val = ((Element) arg).getText(); - assertEquals(customInboundUrl, val); + assertEquals(CUSTOM_INBOUND_URL, val); } } diff --git a/test/src/test/java/hudson/slaves/JNLPLauncherRealTest.java b/test/src/test/java/hudson/slaves/JNLPLauncherRealTest.java index 9b4b9bed3f..8bf84abcc5 100644 --- a/test/src/test/java/hudson/slaves/JNLPLauncherRealTest.java +++ b/test/src/test/java/hudson/slaves/JNLPLauncherRealTest.java @@ -35,26 +35,29 @@ import hudson.model.FreeStyleProject; import hudson.model.Slave; import jenkins.agents.WebSocketAgentsTest; import jenkins.slaves.JnlpSlaveAgentProtocol4; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.jvnet.hudson.test.For; -import org.jvnet.hudson.test.InboundAgentRule; import org.jvnet.hudson.test.Issue; import org.jvnet.hudson.test.JenkinsRule; import org.jvnet.hudson.test.PrefixedOutputStream; -import org.jvnet.hudson.test.RealJenkinsRule; +import org.jvnet.hudson.test.junit.jupiter.InboundAgentExtension; +import org.jvnet.hudson.test.junit.jupiter.RealJenkinsExtension; @For({JNLPLauncher.class, JnlpSlaveAgentProtocol4.class}) -public class JNLPLauncherRealTest { +class JNLPLauncherRealTest { private static final String STATIC_AGENT_NAME = "static"; - @Rule public RealJenkinsRule rr = new RealJenkinsRule().withColor(PrefixedOutputStream.Color.BLUE); + @RegisterExtension + private final RealJenkinsExtension rr = new RealJenkinsExtension().withColor(PrefixedOutputStream.Color.BLUE); - @Rule public InboundAgentRule iar = new InboundAgentRule(); + @RegisterExtension + private final InboundAgentExtension iar = new InboundAgentExtension(); @Issue("JEP-230") - @Test public void smokes() throws Throwable { + @Test + void smokes() throws Throwable { /* Since RealJenkinsRuleInit.jpi will load detached and test scope plugins, to reproduce a failure use: rr.includeTestClasspathPlugins(false); FileUtils.touch(new File(rr.getHome(), "plugins/instance-identity.jpi.disabled")); @@ -66,14 +69,15 @@ public class JNLPLauncherRealTest { * Simplified version of {@link WebSocketAgentsTest#smokes} just checking Jetty/Winstone. */ @Issue("JENKINS-68933") - @Test public void webSocket() throws Throwable { + @Test + void webSocket() throws Throwable { then(true); } private void then(boolean websocket) throws Throwable { try { rr.startJenkins(); - InboundAgentRule.Options.Builder options = InboundAgentRule.Options.newBuilder().name(STATIC_AGENT_NAME).color(PrefixedOutputStream.Color.RED); + InboundAgentExtension.Options.Builder options = InboundAgentExtension.Options.newBuilder().name(STATIC_AGENT_NAME).color(PrefixedOutputStream.Color.RED); if (websocket) { options = options.webSocket(); } @@ -84,7 +88,7 @@ public class JNLPLauncherRealTest { } } - private static class RunJobStep implements RealJenkinsRule.Step { + private static class RunJobStep implements RealJenkinsExtension.Step { private final String agentName; private final boolean webSocket; diff --git a/test/src/test/java/hudson/slaves/NodeParallelTest.java b/test/src/test/java/hudson/slaves/NodeParallelTest.java index 05d1db6f11..1904422480 100644 --- a/test/src/test/java/hudson/slaves/NodeParallelTest.java +++ b/test/src/test/java/hudson/slaves/NodeParallelTest.java @@ -1,6 +1,6 @@ package hudson.slaves; -import static org.junit.Assert.fail; +import static org.junit.jupiter.api.Assertions.fail; import hudson.model.Slave; import java.util.ArrayList; @@ -14,27 +14,34 @@ import java.util.concurrent.Future; import java.util.concurrent.atomic.AtomicInteger; import java.util.logging.Level; import java.util.logging.Logger; -import org.junit.Rule; -import org.junit.Test; -import org.jvnet.hudson.test.InboundAgentRule; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.jvnet.hudson.test.Issue; import org.jvnet.hudson.test.JenkinsRule; +import org.jvnet.hudson.test.junit.jupiter.InboundAgentExtension; +import org.jvnet.hudson.test.junit.jupiter.WithJenkins; -public class NodeParallelTest { +@WithJenkins +class NodeParallelTest { - @Rule - public JenkinsRule r = new JenkinsRule(); - - @Rule - public InboundAgentRule inboundAgents = new InboundAgentRule(); + @RegisterExtension + public InboundAgentExtension inboundAgents = new InboundAgentExtension(); private static final Logger LOGGER = Logger.getLogger(NodeParallelTest.class.getName()); private final AtomicInteger count = new AtomicInteger(); + private JenkinsRule r; + + @BeforeEach + void setUp(JenkinsRule rule) { + r = rule; + } + @Test @Issue("JENKINS-53401") - public void createNodesWithParallelThreads() throws InterruptedException, ExecutionException { + void createNodesWithParallelThreads() throws InterruptedException, ExecutionException { int n = 50; List> tasks = Collections.nCopies(n, () -> { try { @@ -42,7 +49,7 @@ public class NodeParallelTest { LOGGER.log(Level.INFO, "Creating slave " + i); // JenkinsRule sync on Jenkins singleton, so this doesn't work // r.createSlave(); - Slave agent = inboundAgents.createAgent(r, InboundAgentRule.Options.newBuilder().name("agent-" + i).skipStart().build()); + Slave agent = inboundAgents.createAgent(r, InboundAgentExtension.Options.newBuilder().name("agent-" + i).skipStart().build()); agent.setNodeProperties(List.of(new EnvironmentVariablesNodeProperty(new EnvironmentVariablesNodeProperty.Entry("foo", "" + i)))); return null; } catch (Exception e1) { diff --git a/test/src/test/java/hudson/slaves/NodeProvisionerTest.java b/test/src/test/java/hudson/slaves/NodeProvisionerTest.java index cccee80754..e206e656f9 100644 --- a/test/src/test/java/hudson/slaves/NodeProvisionerTest.java +++ b/test/src/test/java/hudson/slaves/NodeProvisionerTest.java @@ -27,9 +27,9 @@ package hudson.slaves; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.anyOf; import static org.hamcrest.Matchers.equalTo; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assume.assumeFalse; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assumptions.assumeFalse; import hudson.BulkChange; import hudson.Functions; @@ -66,23 +66,24 @@ import java.util.logging.ConsoleHandler; import java.util.logging.Handler; import java.util.logging.Level; import java.util.logging.Logger; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.jvnet.hudson.test.Issue; import org.jvnet.hudson.test.JenkinsRule; -import org.jvnet.hudson.test.RealJenkinsRule; import org.jvnet.hudson.test.SleepBuilder; +import org.jvnet.hudson.test.junit.jupiter.RealJenkinsExtension; /** * @author Kohsuke Kawaguchi */ -public class NodeProvisionerTest { +class NodeProvisionerTest { - @Rule public RealJenkinsRule rr = new RealJenkinsRule(); + @RegisterExtension + private final RealJenkinsExtension rr = new RealJenkinsExtension(); - @Before - public void setUp() { + @BeforeEach + void setUp() { // run 10x the regular speed to speed up the test rr.javaOptions( "-Dhudson.model.LoadStatistics.clock=" + TimeUnit.SECONDS.toMillis(1), @@ -128,8 +129,9 @@ public class NodeProvisionerTest { * Scenario: schedule a build and see if one agent is provisioned. */ // TODO fragile - @Test public void autoProvision() throws Throwable { - assumeFalse("TODO: Windows container agents do not have enough resources to run this test", Functions.isWindows() && System.getenv("CI") != null); + @Test + void autoProvision() throws Throwable { + assumeFalse(Functions.isWindows() && System.getenv("CI") != null, "TODO: Windows container agents do not have enough resources to run this test"); rr.then(NodeProvisionerTest::_autoProvision); } @@ -151,8 +153,9 @@ public class NodeProvisionerTest { * Scenario: we got a lot of jobs all of the sudden, and we need to fire up a few nodes. */ // TODO fragile - @Test public void loadSpike() throws Throwable { - assumeFalse("TODO: Windows container agents do not have enough resources to run this test", Functions.isWindows() && System.getenv("CI") != null); + @Test + void loadSpike() throws Throwable { + assumeFalse(Functions.isWindows() && System.getenv("CI") != null, "TODO: Windows container agents do not have enough resources to run this test"); rr.then(NodeProvisionerTest::_loadSpike); } @@ -173,8 +176,9 @@ public class NodeProvisionerTest { * Scenario: make sure we take advantage of statically configured agents. */ // TODO fragile - @Test public void baselineSlaveUsage() throws Throwable { - assumeFalse("TODO: Windows container agents do not have enough resources to run this test", Functions.isWindows() && System.getenv("CI") != null); + @Test + void baselineSlaveUsage() throws Throwable { + assumeFalse(Functions.isWindows() && System.getenv("CI") != null, "TODO: Windows container agents do not have enough resources to run this test"); rr.then(NodeProvisionerTest::_baselineSlaveUsage); } @@ -197,8 +201,9 @@ public class NodeProvisionerTest { * Scenario: loads on one label shouldn't translate to load on another label. */ // TODO fragile - @Test public void labels() throws Throwable { - assumeFalse("TODO: Windows container agents do not have enough resources to run this test", Functions.isWindows() && System.getenv("CI") != null); + @Test + void labels() throws Throwable { + assumeFalse(Functions.isWindows() && System.getenv("CI") != null, "TODO: Windows container agents do not have enough resources to run this test"); rr.then(NodeProvisionerTest::_labels); } @@ -235,8 +240,8 @@ public class NodeProvisionerTest { @Issue("JENKINS-7291") @Test - public void flyweightTasksWithoutMasterExecutors() throws Throwable { - assumeFalse("TODO: Windows container agents do not have enough resources to run this test", Functions.isWindows() && System.getenv("CI") != null); + void flyweightTasksWithoutMasterExecutors() throws Throwable { + assumeFalse(Functions.isWindows() && System.getenv("CI") != null, "TODO: Windows container agents do not have enough resources to run this test"); rr.then(NodeProvisionerTest::_flyweightTasksWithoutMasterExecutors); } @@ -267,8 +272,8 @@ public class NodeProvisionerTest { */ @Issue("JENKINS-30084") @Test - public void shouldRunFlyweightTaskOnProvisionedNodeWhenNodeRestricted() throws Throwable { - assumeFalse("TODO: Windows container agents do not have enough resources to run this test", Functions.isWindows() && System.getenv("CI") != null); + void shouldRunFlyweightTaskOnProvisionedNodeWhenNodeRestricted() throws Throwable { + assumeFalse(Functions.isWindows() && System.getenv("CI") != null, "TODO: Windows container agents do not have enough resources to run this test"); rr.then(NodeProvisionerTest::_shouldRunFlyweightTaskOnProvisionedNodeWhenNodeRestricted); } @@ -286,8 +291,8 @@ public class NodeProvisionerTest { @Issue("JENKINS-67635") @Test - public void testJobWithCloudLabelExpressionProvisionsOnlyOneAgent() throws Throwable { - assumeFalse("TODO: Windows container agents do not have enough resources to run this test", Functions.isWindows() && System.getenv("CI") != null); + void testJobWithCloudLabelExpressionProvisionsOnlyOneAgent() throws Throwable { + assumeFalse(Functions.isWindows() && System.getenv("CI") != null, "TODO: Windows container agents do not have enough resources to run this test"); rr.then(NodeProvisionerTest::_testJobWithCloudLabelExpressionProvisionsOnlyOneAgent); } diff --git a/test/src/test/java/hudson/tasks/BuildTriggerTest.java b/test/src/test/java/hudson/tasks/BuildTriggerTest.java index 7aab832743..860a39dd5d 100644 --- a/test/src/test/java/hudson/tasks/BuildTriggerTest.java +++ b/test/src/test/java/hudson/tasks/BuildTriggerTest.java @@ -75,7 +75,7 @@ import org.springframework.security.core.Authentication; import org.xml.sax.SAXException; @WithJenkins -public class BuildTriggerTest { +class BuildTriggerTest { private JenkinsRule j; diff --git a/test/src/test/java/hudson/util/ArgumentListBuilder2Test.java b/test/src/test/java/hudson/util/ArgumentListBuilder2Test.java index 52d2e59ada..93aea8f9c7 100644 --- a/test/src/test/java/hudson/util/ArgumentListBuilder2Test.java +++ b/test/src/test/java/hudson/util/ArgumentListBuilder2Test.java @@ -26,10 +26,8 @@ package hudson.util; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.equalTo; -import static org.junit.Assert.assertEquals; -import static org.junit.Assume.assumeThat; -import static org.junit.Assume.assumeTrue; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assumptions.assumeTrue; import hudson.Functions; import hudson.Launcher.LocalLauncher; @@ -43,31 +41,36 @@ import java.nio.charset.Charset; import java.util.logging.Level; import jenkins.util.SystemProperties; import org.apache.tools.ant.util.JavaEnvUtils; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.jvnet.hudson.test.Email; import org.jvnet.hudson.test.JenkinsRule; -import org.jvnet.hudson.test.LoggerRule; +import org.jvnet.hudson.test.LogRecorder; +import org.jvnet.hudson.test.junit.jupiter.WithJenkins; /** * @author Kohsuke Kawaguchi */ -public class ArgumentListBuilder2Test { +@WithJenkins +class ArgumentListBuilder2Test { - @Rule - public JenkinsRule j = new JenkinsRule(); - - @Rule - public LoggerRule logging = new LoggerRule(). + private final LogRecorder logging = new LogRecorder(). record(StreamTaskListener.class, Level.FINE). record(SystemProperties.class, Level.FINE); + private JenkinsRule j; + + @BeforeEach + void setUp(JenkinsRule rule) { + j = rule; + } + /** * Makes sure {@link RemoteLauncher} properly masks arguments. */ @Test @Email("http://n4.nabble.com/Password-masking-when-running-commands-on-a-slave-tp1753033p1753033.html") - public void slaveMask() throws Exception { + void slaveMask() throws Exception { ArgumentListBuilder args = new ArgumentListBuilder(); args.add("java"); args.addMasked("-version"); @@ -81,7 +84,7 @@ public class ArgumentListBuilder2Test { } @Test - public void ensureArgumentsArePassedViaCmdExeUnmodified() throws Exception { + void ensureArgumentsArePassedViaCmdExeUnmodified() throws Exception { assumeTrue(Functions.isWindows()); String[] specials = new String[] { @@ -147,7 +150,7 @@ public class ArgumentListBuilder2Test { int code = p.join(); listener.close(); - assumeThat("Failed to run " + args, code, equalTo(0)); + assumeTrue(code == 0, "Failed to run " + args); return out.toString(Charset.defaultCharset()); } } diff --git a/test/src/test/java/hudson/util/DoubleLaunchCheckerTest.java b/test/src/test/java/hudson/util/DoubleLaunchCheckerTest.java index cb6772a4d6..98bb48e6f8 100644 --- a/test/src/test/java/hudson/util/DoubleLaunchCheckerTest.java +++ b/test/src/test/java/hudson/util/DoubleLaunchCheckerTest.java @@ -29,34 +29,34 @@ import static org.awaitility.Awaitility.await; import hudson.ExtensionList; import java.time.Duration; import java.util.logging.Level; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.jvnet.hudson.test.JenkinsRule; import org.jvnet.hudson.test.PrefixedOutputStream; -import org.jvnet.hudson.test.RealJenkinsRule; +import org.jvnet.hudson.test.junit.jupiter.RealJenkinsExtension; -public final class DoubleLaunchCheckerTest { +class DoubleLaunchCheckerTest { - @Rule - public RealJenkinsRule mainController = new RealJenkinsRule(). + @RegisterExtension + private final RealJenkinsExtension mainController = new RealJenkinsExtension(). withName("main"). withColor(PrefixedOutputStream.Color.BLUE). withLogger(DoubleLaunchChecker.class, Level.FINE); - @Rule - public RealJenkinsRule duplicateController = new RealJenkinsRule(mainController). + @RegisterExtension + private final RealJenkinsExtension duplicateController = new RealJenkinsExtension(mainController). withName("dupe"). withColor(PrefixedOutputStream.Color.RED). withLogger(DoubleLaunchChecker.class, Level.FINE); @Test - public void activated() throws Throwable { + void activated() throws Throwable { mainController.startJenkins(); duplicateController.startJenkins(); mainController.runRemotely(DoubleLaunchCheckerTest::waitForWarning); } - private static void waitForWarning(JenkinsRule r) throws Throwable { + private static void waitForWarning(JenkinsRule r) { await().atMost(Duration.ofMinutes(3)).until(ExtensionList.lookupSingleton(DoubleLaunchChecker.class)::isActivated); } diff --git a/test/src/test/java/hudson/util/XStream2AnnotationTest.java b/test/src/test/java/hudson/util/XStream2AnnotationTest.java index 2fd70c0340..369e368620 100644 --- a/test/src/test/java/hudson/util/XStream2AnnotationTest.java +++ b/test/src/test/java/hudson/util/XStream2AnnotationTest.java @@ -33,18 +33,18 @@ import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import jenkins.model.GlobalConfiguration; -import org.junit.Rule; -import org.junit.Test; -import org.jvnet.hudson.test.JenkinsSessionRule; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.jvnet.hudson.test.TestExtension; +import org.jvnet.hudson.test.junit.jupiter.JenkinsSessionExtension; -public class XStream2AnnotationTest { +class XStream2AnnotationTest { - @Rule - public JenkinsSessionRule rr = new JenkinsSessionRule(); + @RegisterExtension + public JenkinsSessionExtension rr = new JenkinsSessionExtension(); @Test - public void xStreamAlias() throws Throwable { + void xStreamAlias() throws Throwable { rr.then(r -> { AnnotatedProcessed annotatedProcessed = AnnotatedProcessed.get(); annotatedProcessed.x = 1; @@ -78,6 +78,7 @@ public class XStream2AnnotationTest { int x; + @SuppressWarnings(value = "checkstyle:redundantmodifier") public AnnotatedProcessed() { getConfigFile().getXStream().processAnnotations(AnnotatedProcessed.class); load(); @@ -97,6 +98,7 @@ public class XStream2AnnotationTest { int x; + @SuppressWarnings(value = "checkstyle:redundantmodifier") public AnnotatedUnprocessed() { load(); } @@ -118,6 +120,7 @@ public class XStream2AnnotationTest { int x; + @SuppressWarnings(value = "checkstyle:redundantmodifier") public Programmatic() { getConfigFile().getXStream().alias("myconf-programmatic", Programmatic.class); load(); diff --git a/test/src/test/java/jenkins/agents/InboundAgentTlsTest.java b/test/src/test/java/jenkins/agents/InboundAgentTlsTest.java index 39593397bb..a57dc18df4 100644 --- a/test/src/test/java/jenkins/agents/InboundAgentTlsTest.java +++ b/test/src/test/java/jenkins/agents/InboundAgentTlsTest.java @@ -1,27 +1,27 @@ package jenkins.agents; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.jvnet.hudson.test.InboundAgentRule; -import org.jvnet.hudson.test.RealJenkinsRule; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.jvnet.hudson.test.junit.jupiter.InboundAgentExtension; +import org.jvnet.hudson.test.junit.jupiter.RealJenkinsExtension; -public class InboundAgentTlsTest { +class InboundAgentTlsTest { - @Rule - public final RealJenkinsRule rjr = new RealJenkinsRule().https(); + @RegisterExtension + private final RealJenkinsExtension rjr = new RealJenkinsExtension().https(); - @Rule - public InboundAgentRule iar = new InboundAgentRule(); + @RegisterExtension + private final InboundAgentExtension iar = new InboundAgentExtension(); - @Before - public void setUp() throws Throwable { + @BeforeEach + void setUp() throws Throwable { rjr.startJenkins(); } @Test - public void webSocketNoCertificateCheck() throws Throwable { - var options = InboundAgentRule.Options + void webSocketNoCertificateCheck() throws Throwable { + var options = InboundAgentExtension.Options .newBuilder() .webSocket() .noCertificateCheck(); @@ -29,8 +29,8 @@ public class InboundAgentTlsTest { } @Test - public void webSocketWithCertByValue() throws Throwable { - var options = InboundAgentRule.Options + void webSocketWithCertByValue() throws Throwable { + var options = InboundAgentExtension.Options .newBuilder() .webSocket() .cert(rjr.getRootCAPem()); @@ -38,16 +38,16 @@ public class InboundAgentTlsTest { } @Test - public void tcpWithNoCertificateCheck() throws Throwable { - var options = InboundAgentRule.Options + void tcpWithNoCertificateCheck() throws Throwable { + var options = InboundAgentExtension.Options .newBuilder() .noCertificateCheck(); iar.createAgent(rjr, options.build()); } @Test - public void tcpWithCertByValue() throws Throwable { - var options = InboundAgentRule.Options + void tcpWithCertByValue() throws Throwable { + var options = InboundAgentExtension.Options .newBuilder() .cert(rjr.getRootCAPem()); iar.createAgent(rjr, options.build()); diff --git a/test/src/test/java/jenkins/agents/JnlpProtocol4ProxyHandlerTest.java b/test/src/test/java/jenkins/agents/JnlpProtocol4ProxyHandlerTest.java index e4c031922d..a25b53100c 100644 --- a/test/src/test/java/jenkins/agents/JnlpProtocol4ProxyHandlerTest.java +++ b/test/src/test/java/jenkins/agents/JnlpProtocol4ProxyHandlerTest.java @@ -45,29 +45,36 @@ import jenkins.security.SlaveToMasterCallable; import jenkins.slaves.JnlpSlaveAgentProtocol4; import org.jenkinsci.remoting.engine.JnlpConnectionState; import org.jenkinsci.remoting.engine.JnlpProtocol4ProxyHandler; -import org.junit.Rule; -import org.junit.Test; -import org.jvnet.hudson.test.InboundAgentRule; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.jvnet.hudson.test.JenkinsRule; import org.jvnet.hudson.test.TestExtension; +import org.jvnet.hudson.test.junit.jupiter.InboundAgentExtension; +import org.jvnet.hudson.test.junit.jupiter.WithJenkins; /** * Example server counterpart to {@link JnlpProtocol4ProxyHandler}. */ -public final class JnlpProtocol4ProxyHandlerTest { +@WithJenkins +class JnlpProtocol4ProxyHandlerTest { private static final Logger LOGGER = Logger.getLogger(JnlpProtocol4ProxyHandlerTest.class.getName()); - @Rule - public JenkinsRule r = new JenkinsRule(); + @RegisterExtension + private final InboundAgentExtension inboundAgents = new InboundAgentExtension(); - @Rule - public InboundAgentRule inboundAgents = new InboundAgentRule(); + private JenkinsRule r; + + @BeforeEach + void setUp(JenkinsRule rule) { + r = rule; + } @Test - public void smokes() throws Exception { + void smokes() throws Exception { // withLogger(JnlpProtocol4ProxyHandler.class, Level.FINE) pointless since log dumper is set up after these messages are printed - Slave s = inboundAgents.createAgent(r, InboundAgentRule.Options.newBuilder().secret().build()); + Slave s = inboundAgents.createAgent(r, InboundAgentExtension.Options.newBuilder().build()); try { assertThat(s.getChannel().call(new DummyTask()), is("response")); s.toComputer().getLogText().writeLogTo(0, System.out); diff --git a/test/src/test/java/jenkins/agents/WebSocketAgentsTest.java b/test/src/test/java/jenkins/agents/WebSocketAgentsTest.java index dbc6730f5e..e8f8d3a57b 100644 --- a/test/src/test/java/jenkins/agents/WebSocketAgentsTest.java +++ b/test/src/test/java/jenkins/agents/WebSocketAgentsTest.java @@ -24,8 +24,8 @@ package jenkins.agents; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; import hudson.Functions; import hudson.model.FreeStyleProject; @@ -39,36 +39,42 @@ import java.util.Random; import java.util.logging.Level; import java.util.logging.Logger; import jenkins.security.SlaveToMasterCallable; -import org.junit.ClassRule; -import org.junit.Rule; -import org.junit.Test; -import org.jvnet.hudson.test.BuildWatcher; -import org.jvnet.hudson.test.InboundAgentRule; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.jvnet.hudson.test.Issue; import org.jvnet.hudson.test.JenkinsRule; +import org.jvnet.hudson.test.LogRecorder; import org.jvnet.hudson.test.LoggerRule; +import org.jvnet.hudson.test.junit.jupiter.BuildWatcherExtension; +import org.jvnet.hudson.test.junit.jupiter.InboundAgentExtension; +import org.jvnet.hudson.test.junit.jupiter.WithJenkins; @Issue("JEP-222") +@WithJenkins public class WebSocketAgentsTest { private static final Logger LOGGER = Logger.getLogger(WebSocketAgentsTest.class.getName()); - @ClassRule - public static BuildWatcher buildWatcher = new BuildWatcher(); + @RegisterExtension + private static final BuildWatcherExtension buildWatcher = new BuildWatcherExtension(); - @Rule - public JenkinsRule r = new JenkinsRule(); + @RegisterExtension + private final InboundAgentExtension inboundAgents = new InboundAgentExtension(); - @Rule - public InboundAgentRule inboundAgents = new InboundAgentRule(); - - @Rule - public LoggerRule logging = new LoggerRule(). + private final LogRecorder logging = new LogRecorder(). record(Slave.class, Level.FINE). record(SlaveComputer.class, Level.FINEST). record(WebSocketAgents.class, Level.FINEST). record(Engine.class, Level.FINEST); + private JenkinsRule r; + + @BeforeEach + void setUp(JenkinsRule rule) { + r = rule; + } + /** * Verify basic functionality of an agent in {@code -webSocket} mode. * Requires {@code remoting} to have been {@code mvn install}ed. @@ -77,8 +83,8 @@ public class WebSocketAgentsTest { * @see hudson.remoting.Launcher */ @Test - public void smokes() throws Exception { - Slave s = inboundAgents.createAgent(r, InboundAgentRule.Options.newBuilder().secret().webSocket().build()); + void smokes() throws Exception { + Slave s = inboundAgents.createAgent(r, InboundAgentExtension.Options.newBuilder().webSocket().build()); try { assertEquals("response", s.getChannel().call(new DummyTask())); assertNotNull(s.getChannel().call(new FatTask())); diff --git a/test/src/test/java/jenkins/install/SetupWizardRestartTest.java b/test/src/test/java/jenkins/install/SetupWizardRestartTest.java index edbc196d19..04a8c54f64 100644 --- a/test/src/test/java/jenkins/install/SetupWizardRestartTest.java +++ b/test/src/test/java/jenkins/install/SetupWizardRestartTest.java @@ -1,40 +1,40 @@ package jenkins.install; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; import hudson.Main; import java.nio.charset.StandardCharsets; import java.nio.file.Files; -import org.junit.Rule; -import org.junit.Test; -import org.junit.experimental.categories.Category; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.jvnet.hudson.test.Issue; -import org.jvnet.hudson.test.JenkinsSessionRule; -import org.jvnet.hudson.test.SmokeTest; +import org.jvnet.hudson.test.junit.jupiter.JenkinsSessionExtension; -@Category(SmokeTest.class) -public class SetupWizardRestartTest { - @Rule - public JenkinsSessionRule sessions = new JenkinsSessionRule(); +@Tag("SmokeTest") +class SetupWizardRestartTest { + + @RegisterExtension + private final JenkinsSessionExtension sessions = new JenkinsSessionExtension(); @Issue("JENKINS-47439") @Test - public void restartKeepsSetupWizardState() throws Throwable { + void restartKeepsSetupWizardState() throws Throwable { sessions.then(j -> { // Modify state so that we get into the same conditions as a real start Main.isUnitTest = false; Files.writeString(InstallUtil.getLastExecVersionFile().toPath(), "", StandardCharsets.US_ASCII); // Re-evaluate current state based on the new context InstallUtil.proceedToNextStateFrom(InstallState.UNKNOWN); - assertEquals("Unexpected install state", InstallState.NEW, j.jenkins.getInstallState()); - assertTrue("Expecting setup wizard filter to be up", j.jenkins.getSetupWizard().hasSetupWizardFilter()); + assertEquals(InstallState.NEW, j.jenkins.getInstallState(), "Unexpected install state"); + assertTrue(j.jenkins.getSetupWizard().hasSetupWizardFilter(), "Expecting setup wizard filter to be up"); InstallUtil.saveLastExecVersion(); }); // Check that the state is retained after a restart sessions.then(j -> { - assertEquals("Unexpected install state", InstallState.NEW, j.jenkins.getInstallState()); - assertTrue("Expecting setup wizard filter to be up after restart", j.jenkins.getSetupWizard().hasSetupWizardFilter()); + assertEquals(InstallState.NEW, j.jenkins.getInstallState(), "Unexpected install state"); + assertTrue(j.jenkins.getSetupWizard().hasSetupWizardFilter(), "Expecting setup wizard filter to be up after restart"); }); } diff --git a/test/src/test/java/jenkins/model/BuiltInNodeMigrationRestartTest.java b/test/src/test/java/jenkins/model/BuiltInNodeMigrationRestartTest.java index 6a51a0d107..a4891b42ff 100644 --- a/test/src/test/java/jenkins/model/BuiltInNodeMigrationRestartTest.java +++ b/test/src/test/java/jenkins/model/BuiltInNodeMigrationRestartTest.java @@ -2,6 +2,8 @@ package jenkins.model; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.RetentionPolicy.RUNTIME; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; import java.io.File; import java.lang.annotation.Retention; @@ -11,72 +13,72 @@ import java.util.Objects; import java.util.logging.Level; import java.util.logging.Logger; import org.apache.commons.io.FileUtils; -import org.junit.Assert; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.junit.runner.Description; import org.jvnet.hudson.test.HudsonHomeLoader; import org.jvnet.hudson.test.JenkinsRecipe; import org.jvnet.hudson.test.JenkinsRule; -import org.jvnet.hudson.test.JenkinsSessionRule; +import org.jvnet.hudson.test.junit.jupiter.JenkinsSessionExtension; import org.jvnet.hudson.test.recipes.LocalData; -public class BuiltInNodeMigrationRestartTest { - @Rule - public JenkinsSessionRule r = new JenkinsSessionRule(); +class BuiltInNodeMigrationRestartTest { + + @RegisterExtension + private final JenkinsSessionExtension r = new JenkinsSessionExtension(); @Test - public void testNewInstanceWithoutConfiguration() throws Throwable { + void testNewInstanceWithoutConfiguration() throws Throwable { r.then(j -> { - Assert.assertTrue(j.jenkins.getRenameMigrationDone()); - Assert.assertFalse(j.jenkins.nodeRenameMigrationNeeded); - Assert.assertFalse(Objects.requireNonNull(j.jenkins.getAdministrativeMonitor(BuiltInNodeMigration.class.getName())).isActivated()); + assertTrue(j.jenkins.getRenameMigrationDone()); + assertFalse(j.jenkins.nodeRenameMigrationNeeded); + assertFalse(Objects.requireNonNull(j.jenkins.getAdministrativeMonitor(BuiltInNodeMigration.class.getName())).isActivated()); }); r.then(j -> { - Assert.assertTrue(j.jenkins.getRenameMigrationDone()); - Assert.assertFalse(j.jenkins.nodeRenameMigrationNeeded); - Assert.assertFalse(Objects.requireNonNull(j.jenkins.getAdministrativeMonitor(BuiltInNodeMigration.class.getName())).isActivated()); + assertTrue(j.jenkins.getRenameMigrationDone()); + assertFalse(j.jenkins.nodeRenameMigrationNeeded); + assertFalse(Objects.requireNonNull(j.jenkins.getAdministrativeMonitor(BuiltInNodeMigration.class.getName())).isActivated()); }); } @Test @LocalDataOnce - public void migratedInstanceStartsWithNewTerminology() throws Throwable { + void migratedInstanceStartsWithNewTerminology() throws Throwable { r.then(j -> { - Assert.assertTrue(j.jenkins.getRenameMigrationDone()); - Assert.assertFalse(j.jenkins.nodeRenameMigrationNeeded); - Assert.assertFalse(Objects.requireNonNull(j.jenkins.getAdministrativeMonitor(BuiltInNodeMigration.class.getName())).isActivated()); + assertTrue(j.jenkins.getRenameMigrationDone()); + assertFalse(j.jenkins.nodeRenameMigrationNeeded); + assertFalse(Objects.requireNonNull(j.jenkins.getAdministrativeMonitor(BuiltInNodeMigration.class.getName())).isActivated()); }); r.then(j -> { - Assert.assertTrue(j.jenkins.getRenameMigrationDone()); - Assert.assertFalse(j.jenkins.nodeRenameMigrationNeeded); - Assert.assertFalse(Objects.requireNonNull(j.jenkins.getAdministrativeMonitor(BuiltInNodeMigration.class.getName())).isActivated()); + assertTrue(j.jenkins.getRenameMigrationDone()); + assertFalse(j.jenkins.nodeRenameMigrationNeeded); + assertFalse(Objects.requireNonNull(j.jenkins.getAdministrativeMonitor(BuiltInNodeMigration.class.getName())).isActivated()); }); } @Test @LocalDataOnce - public void oldDataStartsWithOldTerminology() throws Throwable { + void oldDataStartsWithOldTerminology() throws Throwable { r.then(j -> { - Assert.assertFalse(j.jenkins.getRenameMigrationDone()); - Assert.assertTrue(j.jenkins.nodeRenameMigrationNeeded); - Assert.assertTrue(Objects.requireNonNull(j.jenkins.getAdministrativeMonitor(BuiltInNodeMigration.class.getName())).isActivated()); + assertFalse(j.jenkins.getRenameMigrationDone()); + assertTrue(j.jenkins.nodeRenameMigrationNeeded); + assertTrue(Objects.requireNonNull(j.jenkins.getAdministrativeMonitor(BuiltInNodeMigration.class.getName())).isActivated()); }); r.then(j -> { - Assert.assertFalse(j.jenkins.getRenameMigrationDone()); - Assert.assertTrue(j.jenkins.nodeRenameMigrationNeeded); - Assert.assertTrue(Objects.requireNonNull(j.jenkins.getAdministrativeMonitor(BuiltInNodeMigration.class.getName())).isActivated()); + assertFalse(j.jenkins.getRenameMigrationDone()); + assertTrue(j.jenkins.nodeRenameMigrationNeeded); + assertTrue(Objects.requireNonNull(j.jenkins.getAdministrativeMonitor(BuiltInNodeMigration.class.getName())).isActivated()); j.jenkins.performRenameMigration(); - Assert.assertTrue(j.jenkins.getRenameMigrationDone()); - Assert.assertFalse(j.jenkins.nodeRenameMigrationNeeded); - Assert.assertFalse(Objects.requireNonNull(j.jenkins.getAdministrativeMonitor(BuiltInNodeMigration.class.getName())).isActivated()); + assertTrue(j.jenkins.getRenameMigrationDone()); + assertFalse(j.jenkins.nodeRenameMigrationNeeded); + assertFalse(Objects.requireNonNull(j.jenkins.getAdministrativeMonitor(BuiltInNodeMigration.class.getName())).isActivated()); }); r.then(j -> { - Assert.assertTrue(j.jenkins.getRenameMigrationDone()); - Assert.assertFalse(j.jenkins.nodeRenameMigrationNeeded); - Assert.assertFalse(Objects.requireNonNull(j.jenkins.getAdministrativeMonitor(BuiltInNodeMigration.class.getName())).isActivated()); + assertTrue(j.jenkins.getRenameMigrationDone()); + assertFalse(j.jenkins.nodeRenameMigrationNeeded); + assertFalse(Objects.requireNonNull(j.jenkins.getAdministrativeMonitor(BuiltInNodeMigration.class.getName())).isActivated()); }); } @@ -94,7 +96,7 @@ public class BuiltInNodeMigrationRestartTest { @Override public void setup(JenkinsRule jenkinsRule, LocalDataOnce recipe) throws Exception { Description desc = jenkinsRule.getTestDescription(); - method = desc.getTestClass().getMethod((desc.getMethodName())); + method = desc.getTestClass().getDeclaredMethod((desc.getMethodName())); } @Override diff --git a/test/src/test/java/jenkins/model/JenkinsBuildsAndWorkspacesDirectoriesTest.java b/test/src/test/java/jenkins/model/JenkinsBuildsAndWorkspacesDirectoriesTest.java index 0efda703a4..712527b0b6 100644 --- a/test/src/test/java/jenkins/model/JenkinsBuildsAndWorkspacesDirectoriesTest.java +++ b/test/src/test/java/jenkins/model/JenkinsBuildsAndWorkspacesDirectoriesTest.java @@ -2,17 +2,19 @@ package jenkins.model; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertThrows; -import static org.junit.Assert.assertTrue; -import static org.junit.Assume.assumeFalse; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; +import static org.junit.jupiter.api.Assumptions.assumeFalse; import hudson.Functions; import hudson.init.InitMilestone; import hudson.model.FreeStyleBuild; import hudson.model.FreeStyleProject; import java.io.File; +import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; @@ -21,47 +23,46 @@ import java.util.Arrays; import java.util.List; import java.util.logging.Level; import java.util.stream.Stream; -import org.junit.After; -import org.junit.Before; -import org.junit.ClassRule; -import org.junit.Ignore; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TemporaryFolder; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.junit.jupiter.api.io.TempDir; +import org.jvnet.hudson.reactor.ReactorException; import org.jvnet.hudson.test.Issue; -import org.jvnet.hudson.test.LoggerRule; +import org.jvnet.hudson.test.LogRecorder; import org.jvnet.hudson.test.MockFolder; -import org.jvnet.hudson.test.RestartableJenkinsRule; +import org.jvnet.hudson.test.junit.jupiter.JenkinsSessionExtension; import org.jvnet.hudson.test.recipes.LocalData; /** * Since JENKINS-50164, Jenkins#workspacesDir and Jenkins#buildsDir had their associated UI deleted. * So instead of configuring through the UI, we now have to use sysprops for this. *

- * So this test class uses a {@link RestartableJenkinsRule} to check the behaviour of this sysprop being + * So this test class uses a {@link JenkinsSessionExtension} to check the behaviour of this sysprop being * present or not between two restarts. */ -public class JenkinsBuildsAndWorkspacesDirectoriesTest { +class JenkinsBuildsAndWorkspacesDirectoriesTest { private static final String LOG_WHEN_CHANGING_BUILDS_DIR = "Changing builds directories from "; private static final String LOG_WHEN_CHANGING_WORKSPACES_DIR = "Changing workspaces directories from "; - @Rule - public RestartableJenkinsRule story = new RestartableJenkinsRule(); + @RegisterExtension + private final JenkinsSessionExtension story = new JenkinsSessionExtension(); - @Rule - public LoggerRule loggerRule = new LoggerRule(); + private final LogRecorder loggerRule = new LogRecorder(); - @ClassRule - public static TemporaryFolder tmp = new TemporaryFolder(); + @TempDir + private static File tmp; - @Before - public void before() { + @BeforeEach + void before() { clearSystemProperties(); } - @After - public void after() { + @AfterEach + void after() { clearSystemProperties(); } @@ -72,7 +73,7 @@ public class JenkinsBuildsAndWorkspacesDirectoriesTest { @Issue("JENKINS-53284") @Test - public void changeWorkspacesDirLog() throws Exception { + void changeWorkspacesDirLog() throws Throwable { loggerRule.record(Jenkins.class, Level.WARNING) .record(Jenkins.class, Level.INFO).capture(1000); @@ -92,7 +93,7 @@ public class JenkinsBuildsAndWorkspacesDirectoriesTest { @Issue("JENKINS-50164") @Test - public void badValueForBuildsDir() { + void badValueForBuildsDir() throws Throwable { story.then(rule -> { final List badValues = new ArrayList<>(Arrays.asList( "blah", @@ -108,14 +109,14 @@ public class JenkinsBuildsAndWorkspacesDirectoriesTest { } // else perhaps running as root for (String badValue : badValues) { - assertThrows(badValue + " should have been rejected", InvalidBuildsDir.class, () -> Jenkins.checkRawBuildsDir(badValue)); + assertThrows(InvalidBuildsDir.class, () -> Jenkins.checkRawBuildsDir(badValue), badValue + " should have been rejected"); } }); } @Issue("JENKINS-50164") @Test - public void goodValueForBuildsDir() { + void goodValueForBuildsDir() throws Throwable { story.then(rule -> { final List badValues = Arrays.asList( "$JENKINS_HOME/foo/$ITEM_FULL_NAME", @@ -129,31 +130,29 @@ public class JenkinsBuildsAndWorkspacesDirectoriesTest { @Issue("JENKINS-50164") @Test - public void jenkinsDoesNotStartWithBadSysProp() { - + void jenkinsDoesNotStartWithBadSysProp() throws Throwable { loggerRule.record(Jenkins.class, Level.WARNING) .record(Jenkins.class, Level.INFO) .capture(100); story.then(rule -> { - assertTrue(story.j.getInstance().isDefaultBuildDir()); + assertTrue(rule.getInstance().isDefaultBuildDir()); setBuildsDirProperty("/bluh"); }); - story.thenDoesNotStart(); + assertThrows(ReactorException.class, () -> story.then(step -> fail("should have failed before reaching here."))); } @Issue("JENKINS-50164") @Test - public void jenkinsDoesNotStartWithScrewedUpConfigXml() { - + void jenkinsDoesNotStartWithScrewedUpConfigXml() throws Throwable { loggerRule.record(Jenkins.class, Level.WARNING) .record(Jenkins.class, Level.INFO) .capture(100); story.then(rule -> { - assertTrue(story.j.getInstance().isDefaultBuildDir()); + assertTrue(rule.getInstance().isDefaultBuildDir()); // Now screw up the value by writing into the file directly, like one could do using external XML manipulation tools final Path configFile = rule.jenkins.getRootDir().toPath().resolve("config.xml"); @@ -162,12 +161,12 @@ public class JenkinsBuildsAndWorkspacesDirectoriesTest { Files.writeString(configFile, screwedUp, StandardCharsets.UTF_8); }); - story.thenDoesNotStart(); + assertThrows(ReactorException.class, () -> story.then(step -> fail("should have failed before reaching here."))); } @Issue("JENKINS-50164") @Test - public void buildsDir() throws Exception { + void buildsDir() throws Throwable { loggerRule.record(Jenkins.class, Level.WARNING) .record(Jenkins.class, Level.INFO) .capture(100); @@ -175,14 +174,14 @@ public class JenkinsBuildsAndWorkspacesDirectoriesTest { story.then(step -> assertFalse(logWasFound("Using non default builds directories"))); story.then(steps -> { - assertTrue(story.j.getInstance().isDefaultBuildDir()); + assertTrue(steps.getInstance().isDefaultBuildDir()); setBuildsDirProperty("$JENKINS_HOME/plouf/$ITEM_FULL_NAME/bluh"); assertFalse(JenkinsBuildsAndWorkspacesDirectoriesTest.this.logWasFound(LOG_WHEN_CHANGING_BUILDS_DIR)); }); story.then(step -> { - assertFalse(story.j.getInstance().isDefaultBuildDir()); - assertEquals("$JENKINS_HOME/plouf/$ITEM_FULL_NAME/bluh", story.j.getInstance().getRawBuildsDir()); + assertFalse(step.getInstance().isDefaultBuildDir()); + assertEquals("$JENKINS_HOME/plouf/$ITEM_FULL_NAME/bluh", step.getInstance().getRawBuildsDir()); assertTrue(logWasFound("Changing builds directories from ")); } ); @@ -193,7 +192,7 @@ public class JenkinsBuildsAndWorkspacesDirectoriesTest { @Issue("JENKINS-50164") @Test - public void workspacesDir() throws Exception { + void workspacesDir() throws Throwable { loggerRule.record(Jenkins.class, Level.WARNING) .record(Jenkins.class, Level.INFO) .capture(1000); @@ -201,33 +200,32 @@ public class JenkinsBuildsAndWorkspacesDirectoriesTest { story.then(step -> assertFalse(logWasFound("Using non default workspaces directories"))); story.then(step -> { - assertTrue(story.j.getInstance().isDefaultWorkspaceDir()); + assertTrue(step.getInstance().isDefaultWorkspaceDir()); final String workspacesDir = "bluh"; setWorkspacesDirProperty(workspacesDir); assertFalse(logWasFound("Changing workspaces directories from ")); }); story.then(step -> { - assertFalse(story.j.getInstance().isDefaultWorkspaceDir()); - assertEquals("bluh", story.j.getInstance().getRawWorkspaceDir()); + assertFalse(step.getInstance().isDefaultWorkspaceDir()); + assertEquals("bluh", step.getInstance().getRawWorkspaceDir()); assertTrue(logWasFound("Changing workspaces directories from ")); }); story.then(step -> { - assertFalse(story.j.getInstance().isDefaultWorkspaceDir()); + assertFalse(step.getInstance().isDefaultWorkspaceDir()); assertTrue(logWasFound("Using non default workspaces directories")); } ); } - @Ignore("TODO calling restart seems to break Surefire") + @Disabled("TODO calling restart seems to break Surefire") @Issue("JENKINS-50164") @LocalData @Test - public void fromPreviousCustomSetup() { - - assumeFalse("Default Windows lifecycle does not support restart.", Functions.isWindows()); + void fromPreviousCustomSetup() throws Throwable { + assumeFalse(Functions.isWindows(), "Default Windows lifecycle does not support restart."); // check starting point and change config for next run final String newBuildsDirValueBySysprop = "/tmp/${ITEM_ROOTDIR}/bluh"; @@ -283,20 +281,19 @@ public class JenkinsBuildsAndWorkspacesDirectoriesTest { @Test @Issue("JENKINS-17138") - public void externalBuildDirectoryRenameDelete() throws Exception { - + void externalBuildDirectoryRenameDelete() throws Throwable { // Hack to get String builds usable in lambda below final List builds = new ArrayList<>(); story.then(steps -> { - builds.add(tmp.newFolder().toString()); - assertTrue(story.j.getInstance().isDefaultBuildDir()); + builds.add(newFolder(tmp, "junit").toString()); + assertTrue(steps.getInstance().isDefaultBuildDir()); setBuildsDirProperty(builds.get(0) + "/${ITEM_FULL_NAME}"); }); story.then(steps -> { - assertEquals(builds.get(0) + "/${ITEM_FULL_NAME}", story.j.jenkins.getRawBuildsDir()); - FreeStyleProject p = story.j.jenkins.createProject(MockFolder.class, "d").createProject(FreeStyleProject.class, "prj"); + assertEquals(builds.get(0) + "/${ITEM_FULL_NAME}", steps.jenkins.getRawBuildsDir()); + FreeStyleProject p = steps.jenkins.createProject(MockFolder.class, "d").createProject(FreeStyleProject.class, "prj"); FreeStyleBuild b = p.scheduleBuild2(0).get(); File oldBuildDir = new File(builds.get(0), "d/prj"); assertEquals(new File(oldBuildDir, b.getId()), b.getRootDir()); @@ -310,4 +307,13 @@ public class JenkinsBuildsAndWorkspacesDirectoriesTest { }); } + private static File newFolder(File root, String... subDirs) throws IOException { + String subFolder = String.join("/", subDirs); + File result = new File(root, subFolder); + if (!result.mkdirs()) { + throw new IOException("Couldn't create folders " + root); + } + return result; + } + } diff --git a/test/src/test/java/jenkins/model/JenkinsLogRecordsTest.java b/test/src/test/java/jenkins/model/JenkinsLogRecordsTest.java index 2d81296ac8..3a5cf981e7 100644 --- a/test/src/test/java/jenkins/model/JenkinsLogRecordsTest.java +++ b/test/src/test/java/jenkins/model/JenkinsLogRecordsTest.java @@ -13,23 +13,23 @@ import java.util.logging.LogRecord; import java.util.logging.Logger; import java.util.stream.Collectors; import jenkins.util.java.JavaUtils; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.jvnet.hudson.test.JenkinsRule; import org.jvnet.hudson.test.MemoryAssert; -import org.jvnet.hudson.test.RealJenkinsRule; +import org.jvnet.hudson.test.junit.jupiter.RealJenkinsExtension; -public class JenkinsLogRecordsTest { +class JenkinsLogRecordsTest { - @Rule - public RealJenkinsRule rr = new RealJenkinsRule(); + @RegisterExtension + private final RealJenkinsExtension rr = new RealJenkinsExtension(); @Test - public void logRecordsArePresentOnController() throws Throwable { + void logRecordsArePresentOnController() throws Throwable { rr.then(JenkinsLogRecordsTest::_logRecordsArePresentOnController); } - private static void _logRecordsArePresentOnController(JenkinsRule r) throws Throwable { + private static void _logRecordsArePresentOnController(JenkinsRule r) { List logRecords = Jenkins.logRecords; assertThat(logRecords, not(empty())); assertThat("Records are displayed in reverse order", diff --git a/test/src/test/java/jenkins/model/JenkinsManagePermissionTest.java b/test/src/test/java/jenkins/model/JenkinsManagePermissionTest.java index d84515f858..4ace5c2781 100644 --- a/test/src/test/java/jenkins/model/JenkinsManagePermissionTest.java +++ b/test/src/test/java/jenkins/model/JenkinsManagePermissionTest.java @@ -8,8 +8,8 @@ import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.not; import static org.hamcrest.Matchers.notNullValue; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; import hudson.PluginWrapper; import hudson.cli.CLICommandInvoker; @@ -29,13 +29,14 @@ import org.hamcrest.Matcher; import org.htmlunit.WebResponse; import org.htmlunit.html.HtmlForm; import org.htmlunit.html.HtmlPage; -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.jvnet.hudson.test.Issue; import org.jvnet.hudson.test.JenkinsRule; import org.jvnet.hudson.test.MockAuthorizationStrategy; +import org.jvnet.hudson.test.junit.jupiter.WithJenkins; import org.jvnet.hudson.test.recipes.WithPlugin; /** @@ -43,29 +44,32 @@ import org.jvnet.hudson.test.recipes.WithPlugin; * with this property activated. */ // TODO move tests to indicated test classes when we no longer need to set the system property -public class JenkinsManagePermissionTest { +@WithJenkins +class JenkinsManagePermissionTest { - @Rule - public JenkinsRule j = new JenkinsRule(); + private JenkinsRule j; - @BeforeClass - public static void enableManagePermission() { + @BeforeAll + static void enableManagePermission() { System.setProperty("jenkins.security.ManagePermission", "true"); } - @AfterClass - public static void disableManagePermission() { - System.clearProperty("jenkins.security.ManagePermission"); + @BeforeEach + void setUp(JenkinsRule rule) { + j = rule; } + @AfterAll + static void disableManagePermission() { + System.clearProperty("jenkins.security.ManagePermission"); + } // ----------------------------- // DisablePluginCommandTest @Issue("JENKINS-60266") @Test - @WithPlugin({ "depender-0.0.2.hpi", "dependee-0.0.2.hpi"}) - public void managerCannotDisablePlugin() { - + @WithPlugin({"depender-0.0.2.hpi", "dependee-0.0.2.hpi"}) + void managerCannotDisablePlugin() { //GIVEN a user with Jenkins.MANAGE permission j.jenkins.setSecurityRealm(j.createDummySecurityRealm()); j.jenkins.setAuthorizationStrategy(new MockAuthorizationStrategy() @@ -88,7 +92,6 @@ public class JenkinsManagePermissionTest { return new CLICommandInvoker(j, new DisablePluginCommand()).asUser(user).invokeWithArgs(args); } - private void assertPluginEnabled(String name) { PluginWrapper plugin = j.getPluginManager().getPlugin(name); assertThat(plugin, is(notNullValue())); @@ -102,7 +105,7 @@ public class JenkinsManagePermissionTest { //ComputerTest @Issue("JENKINS-60266") @Test - public void dumpExportTableForbiddenWithoutAdminPermission() throws Exception { + void dumpExportTableForbiddenWithoutAdminPermission() throws Exception { final String READER = "reader"; final String MANAGER = "manager"; j.jenkins.setSecurityRealm(j.createDummySecurityRealm()); @@ -122,7 +125,7 @@ public class JenkinsManagePermissionTest { // HudsonTest @Issue("JENKINS-60266") @Test - public void someGlobalConfigurationIsNotDisplayedWithManagePermission() throws Exception { + void someGlobalConfigurationIsNotDisplayedWithManagePermission() throws Exception { //GIVEN a user with Jenkins.MANAGE permission j.jenkins.setSecurityRealm(j.createDummySecurityRealm()); j.jenkins.setAuthorizationStrategy(new MockAuthorizationStrategy() @@ -146,7 +149,7 @@ public class JenkinsManagePermissionTest { @Issue("JENKINS-60266") @Test - public void someGlobalConfigCanNotBeModifiedWithManagePermission() throws Exception { + void someGlobalConfigCanNotBeModifiedWithManagePermission() throws Exception { j.jenkins.addView(new MyView("testView", j.jenkins)); //GIVEN the Global Configuration Form, with some changes unsaved @@ -164,14 +167,14 @@ public class JenkinsManagePermissionTest { .grant(Jenkins.MANAGE, Jenkins.READ).everywhere().toEveryone()); j.submit(form); // THEN the changes on fields forbidden to a Jenkins.MANAGE permission are not saved - assertEquals("shouldn't be allowed to change the number of executors", currentNumberExecutors, j.getInstance().getNumExecutors()); - assertEquals("shouldn't be allowed to change the shell executable", shell, getShell()); - assertEquals("shouldn't be allowed to change the primary view", view, j.getInstance().getPrimaryView()); + assertEquals(currentNumberExecutors, j.getInstance().getNumExecutors(), "shouldn't be allowed to change the number of executors"); + assertEquals(shell, getShell(), "shouldn't be allowed to change the shell executable"); + assertEquals(view, j.getInstance().getPrimaryView(), "shouldn't be allowed to change the primary view"); } @Issue("JENKINS-60266") @Test - public void globalConfigAllowedWithManagePermission() throws Exception { + void globalConfigAllowedWithManagePermission() throws Exception { j.jenkins.setSecurityRealm(j.createDummySecurityRealm()); j.jenkins.setAuthorizationStrategy(new MockAuthorizationStrategy() .grant(Jenkins.MANAGE, Jenkins.READ).everywhere().toEveryone()); @@ -184,7 +187,7 @@ public class JenkinsManagePermissionTest { @Issue("JENKINS-61457") @Test - public void managePermissionCanChangeUsageStatistics() throws Exception { + void managePermissionCanChangeUsageStatistics() throws Exception { j.jenkins.setSecurityRealm(j.createDummySecurityRealm()); j.jenkins.setAuthorizationStrategy(new MockAuthorizationStrategy() .grant(Jenkins.MANAGE, Jenkins.READ).everywhere().toEveryone()); @@ -233,8 +236,7 @@ public class JenkinsManagePermissionTest { @Issue("JENKINS-63795") @Test - public void managePermissionShouldBeAllowedToRestart() throws IOException { - + void managePermissionShouldBeAllowedToRestart() throws IOException { //GIVEN a Jenkins with 3 users : ADMINISTER, MANAGE and READ HudsonPrivateSecurityRealm realm = new HudsonPrivateSecurityRealm(false, false, null); User adminUser = realm.createAccount("Administer", "G0d"); diff --git a/test/src/test/java/jenkins/model/JenkinsTest.java b/test/src/test/java/jenkins/model/JenkinsTest.java index f4a5b37616..012e8a4800 100644 --- a/test/src/test/java/jenkins/model/JenkinsTest.java +++ b/test/src/test/java/jenkins/model/JenkinsTest.java @@ -35,13 +35,13 @@ import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.isA; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertThrows; -import static org.junit.Assert.assertTrue; -import static org.junit.Assume.assumeFalse; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assumptions.assumeFalse; import hudson.ExtensionList; import hudson.Functions; @@ -101,17 +101,17 @@ import org.htmlunit.WebRequest; import org.htmlunit.WebResponse; import org.htmlunit.html.HtmlForm; import org.htmlunit.html.HtmlPage; -import org.junit.Rule; -import org.junit.Test; -import org.junit.experimental.categories.Category; -import org.junit.rules.TemporaryFolder; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; import org.jvnet.hudson.reactor.ReactorException; import org.jvnet.hudson.test.Issue; import org.jvnet.hudson.test.JenkinsRule; import org.jvnet.hudson.test.JenkinsRule.WebClient; import org.jvnet.hudson.test.MockAuthorizationStrategy; -import org.jvnet.hudson.test.SmokeTest; import org.jvnet.hudson.test.TestExtension; +import org.jvnet.hudson.test.junit.jupiter.WithJenkins; import org.jvnet.hudson.test.recipes.WithPlugin; import org.kohsuke.stapler.HttpResponse; import org.mockito.ArgumentCaptor; @@ -123,17 +123,23 @@ import org.mockito.Mockito; * @see Jenkins * @see JenkinsRule */ -@Category(SmokeTest.class) +@Tag("SmokeTest") +@WithJenkins public class JenkinsTest { - @Rule public JenkinsRule j = new JenkinsRule(); + @TempDir + private File tmp; - @Rule - public TemporaryFolder tmp = new TemporaryFolder(); + private JenkinsRule j; + + @BeforeEach + void setUp(JenkinsRule rule) { + j = rule; + } @Test @Issue("SECURITY-3498") - public void testPaneToggleCollapse() throws Exception { + void testPaneToggleCollapse() { try (WebClient wc = j.createWebClient()) { final FailingHttpStatusCodeException ex = assertThrows(FailingHttpStatusCodeException.class, () -> wc.goTo("toggleCollapse?paneId=foo")); // @POST responds 404 when the verb is wrong; @RequirePOST would respond 405. @@ -143,12 +149,12 @@ public class JenkinsTest { @Test @Issue("SECURITY-3073") - public void verifyUploadedFingerprintFilePermission() throws Exception { + void verifyUploadedFingerprintFilePermission() throws Exception { assumeFalse(Functions.isWindows()); HtmlPage page = j.createWebClient().goTo("fingerprintCheck"); HtmlForm form = page.getForms().get(0); - File dir = tmp.newFolder(); + File dir = newFolder(tmp, "junit"); File plugin = new File(dir, "htmlpublisher.jpi"); // We're using a plugin to have a file above DiskFileItemFactory.DEFAULT_SIZE_THRESHOLD FileUtils.copyURLToFile(Objects.requireNonNull(getClass().getClassLoader().getResource("plugins/htmlpublisher.jpi")), plugin); @@ -179,12 +185,12 @@ public class JenkinsTest { @Issue("SECURITY-406") @Test - public void testUserCreationFromUrlForAdmins() throws Exception { + void testUserCreationFromUrlForAdmins() throws Exception { WebClient wc = j.createWebClient(); - assertNull("User not supposed to exist", User.getById("nonexistent", false)); + assertNull(User.getById("nonexistent", false), "User not supposed to exist"); wc.assertFails("user/nonexistent", 404); - assertNull("User not supposed to exist", User.getById("nonexistent", false)); + assertNull(User.getById("nonexistent", false), "User not supposed to exist"); try { User.ALLOW_USER_CREATION_VIA_URL = true; @@ -192,7 +198,7 @@ public class JenkinsTest { // expected to work wc.goTo("user/nonexistent2"); - assertNotNull("User supposed to exist", User.getById("nonexistent2", false)); + assertNotNull(User.getById("nonexistent2", false), "User supposed to exist"); } finally { User.ALLOW_USER_CREATION_VIA_URL = false; @@ -200,7 +206,7 @@ public class JenkinsTest { } @Test - public void testIsDisplayNameUniqueTrue() throws Exception { + void testIsDisplayNameUniqueTrue() throws Exception { final String curJobName = "curJobName"; final String jobName = "jobName"; FreeStyleProject curProject = j.createFreeStyleProject(curJobName); @@ -215,7 +221,7 @@ public class JenkinsTest { } @Test - public void testIsDisplayNameUniqueFalse() throws Exception { + void testIsDisplayNameUniqueFalse() throws Exception { final String curJobName = "curJobName"; final String jobName = "jobName"; final String displayName = "displayName"; @@ -231,7 +237,7 @@ public class JenkinsTest { } @Test - public void testIsDisplayNameUniqueSameAsCurrentJob() throws Exception { + void testIsDisplayNameUniqueSameAsCurrentJob() throws Exception { final String curJobName = "curJobName"; final String displayName = "currentProjectDisplayName"; @@ -244,7 +250,7 @@ public class JenkinsTest { } @Test - public void testIsNameUniqueTrue() throws Exception { + void testIsNameUniqueTrue() throws Exception { final String curJobName = "curJobName"; final String jobName = "jobName"; j.createFreeStyleProject(curJobName); @@ -255,7 +261,7 @@ public class JenkinsTest { } @Test - public void testIsNameUniqueFalse() throws Exception { + void testIsNameUniqueFalse() throws Exception { final String curJobName = "curJobName"; final String jobName = "jobName"; j.createFreeStyleProject(curJobName); @@ -266,7 +272,7 @@ public class JenkinsTest { } @Test - public void testIsNameUniqueSameAsCurrentJob() throws Exception { + void testIsNameUniqueSameAsCurrentJob() throws Exception { final String curJobName = "curJobName"; final String jobName = "jobName"; j.createFreeStyleProject(curJobName); @@ -278,7 +284,7 @@ public class JenkinsTest { } @Test - public void testDoCheckDisplayNameUnique() throws Exception { + void testDoCheckDisplayNameUnique() throws Exception { final String curJobName = "curJobName"; final String jobName = "jobName"; FreeStyleProject curProject = j.createFreeStyleProject(curJobName); @@ -293,7 +299,7 @@ public class JenkinsTest { } @Test - public void testDoCheckDisplayNameSameAsDisplayName() throws Exception { + void testDoCheckDisplayNameSameAsDisplayName() throws Exception { final String curJobName = "curJobName"; final String jobName = "jobName"; final String displayName = "displayName"; @@ -309,7 +315,7 @@ public class JenkinsTest { } @Test - public void testDoCheckDisplayNameSameAsJobName() throws Exception { + void testDoCheckDisplayNameSameAsJobName() throws Exception { final String curJobName = "curJobName"; final String jobName = "jobName"; final String displayName = "displayName"; @@ -325,7 +331,7 @@ public class JenkinsTest { } @Test - public void testDoCheckViewName_GoodName() throws Exception { + void testDoCheckViewName_GoodName() { String[] viewNames = new String[] { "", "Jenkins", @@ -339,7 +345,7 @@ public class JenkinsTest { } @Test - public void testDoCheckViewName_NotGoodName() throws Exception { + void testDoCheckViewName_NotGoodName() { String[] viewNames = new String[] { "Jenkins?", "Jenkins*", @@ -365,8 +371,9 @@ public class JenkinsTest { /** * Makes sure access to "/foobar" for UnprotectedRootAction gets through. */ - @Test @Issue("JENKINS-14113") - public void testUnprotectedRootAction() throws Exception { + @Test + @Issue("JENKINS-14113") + void testUnprotectedRootAction() throws Exception { j.jenkins.setSecurityRealm(j.createDummySecurityRealm()); j.jenkins.setAuthorizationStrategy(new FullControlOnceLoggedInAuthorizationStrategy()); WebClient wc = j.createWebClient(); @@ -381,7 +388,7 @@ public class JenkinsTest { } @Test - public void testDoScript() throws Exception { + void testDoScript() throws Exception { j.jenkins.setSecurityRealm(j.createDummySecurityRealm()); j.jenkins.setAuthorizationStrategy(new MockAuthorizationStrategy(). grant(Jenkins.ADMINISTER).everywhere().to("alice"). @@ -411,7 +418,7 @@ public class JenkinsTest { @Test @Issue("JENKINS-58548") - public void testDoScriptTextDoesNotOutputExtraWhitespace() throws Exception { + void testDoScriptTextDoesNotOutputExtraWhitespace() throws Exception { j.jenkins.setSecurityRealm(j.createDummySecurityRealm()); WebClient wc = j.createWebClient().login("admin"); TextPage page = wc.getPage(new WebRequest(wc.createCrumbedUrl("scriptText?script=print 'hello'"), HttpMethod.POST)); @@ -419,7 +426,7 @@ public class JenkinsTest { } @Test - public void testDoEval() throws Exception { + void testDoEval() throws Exception { j.jenkins.setSecurityRealm(j.createDummySecurityRealm()); j.jenkins.setAuthorizationStrategy(new MockAuthorizationStrategy(). grant(Jenkins.ADMINISTER).everywhere().to("alice"). @@ -435,15 +442,15 @@ public class JenkinsTest { wc.withBasicApiToken(User.getById("bob", true)); Page page = eval(wc); - assertEquals("bob has only READ", - HttpURLConnection.HTTP_FORBIDDEN, - page.getWebResponse().getStatusCode()); + assertEquals(HttpURLConnection.HTTP_FORBIDDEN, + page.getWebResponse().getStatusCode(), + "bob has only READ"); wc.withBasicApiToken(User.getById("charlie", true)); page = eval(wc); - assertEquals("charlie has ADMINISTER and READ", - HttpURLConnection.HTTP_OK, - page.getWebResponse().getStatusCode()); + assertEquals(HttpURLConnection.HTTP_OK, + page.getWebResponse().getStatusCode(), + "charlie has ADMINISTER and READ"); } private Page eval(WebClient wc) throws Exception { @@ -491,8 +498,9 @@ public class JenkinsTest { } } - @Test @Issue("JENKINS-20866") - public void testErrorPageShouldBeAnonymousAccessible() throws Exception { + @Test + @Issue("JENKINS-20866") + void testErrorPageShouldBeAnonymousAccessible() throws Exception { HudsonPrivateSecurityRealm s = new HudsonPrivateSecurityRealm(false, false, null); User alice = s.createAccount("alice", "alice"); j.jenkins.setSecurityRealm(s); @@ -507,7 +515,7 @@ public class JenkinsTest { .withThrowExceptionOnFailingStatusCode(false); HtmlPage p = wc.goTo("error/reportError"); - assertEquals(p.asNormalizedText(), HttpURLConnection.HTTP_BAD_REQUEST, p.getWebResponse().getStatusCode()); // not 403 forbidden + assertEquals(HttpURLConnection.HTTP_BAD_REQUEST, p.getWebResponse().getStatusCode(), p.asNormalizedText()); // not 403 forbidden assertTrue(p.getWebResponse().getContentAsString().contains("My car is black")); } @@ -534,8 +542,9 @@ public class JenkinsTest { } } - @Test @Issue("JENKINS-23551") - public void testComputerListenerNotifiedOnRestart() { + @Test + @Issue("JENKINS-23551") + void testComputerListenerNotifiedOnRestart() { // Simulate restart calling listeners for (RestartListener listener : RestartListener.all()) listener.onRestart(); @@ -549,7 +558,7 @@ public class JenkinsTest { public static final ComputerListener listenerMock = Mockito.mock(ComputerListener.class); @Test - public void runScriptOnOfflineComputer() throws Exception { + void runScriptOnOfflineComputer() throws Exception { DumbSlave slave = j.createSlave(true); j.disconnectSlave(slave); @@ -568,7 +577,7 @@ public class JenkinsTest { @Test @Issue("JENKINS-38487") - public void startupShouldNotFailOnIOExceptionOnlineListener() { + void startupShouldNotFailOnIOExceptionOnlineListener() { // We do nothing, IOExceptionOnOnlineListener & JenkinsRule should cause the // boot failure if the issue is not fixed. @@ -589,7 +598,7 @@ public class JenkinsTest { @Test @Issue("JENKINS-57111") - public void startupShouldNotFailOnRuntimeExceptionOnlineListener() { + void startupShouldNotFailOnRuntimeExceptionOnlineListener() { // We do nothing, RuntimeExceptionOnOnlineListener & JenkinsRule should cause the // boot failure if the issue is not fixed. assertEquals(1, RuntimeExceptionOnOnlineListener.onOnlineCount); @@ -608,7 +617,7 @@ public class JenkinsTest { } @Test - public void getComputers() throws Exception { + void getComputers() throws Exception { List agents = new ArrayList<>(); for (String n : List.of("zestful", "bilking", "grouchiest")) { agents.add(j.createSlave(n, null, null)); @@ -622,7 +631,7 @@ public class JenkinsTest { @Issue("JENKINS-42577") @Test - public void versionIsSavedInSave() throws Exception { + void versionIsSavedInSave() throws Exception { Jenkins.VERSION = "1.0"; j.jenkins.save(); VersionNumber storedVersion = Jenkins.getStoredVersion(); @@ -635,27 +644,28 @@ public class JenkinsTest { assertNull(nullVersion); } + // Sources: https://github.com/Vlatombe/jenkins-47406 @Issue("JENKINS-47406") @Test - @WithPlugin("jenkins-47406.hpi") // Sources: https://github.com/Vlatombe/jenkins-47406 - public void jobCreatedByInitializerIsRetained() { - assertNotNull("JENKINS-47406 should exist", j.jenkins.getItem("JENKINS-47406")); + @WithPlugin("jenkins-47406.hpi") + void jobCreatedByInitializerIsRetained() { + assertNotNull(j.jenkins.getItem("JENKINS-47406"), "JENKINS-47406 should exist"); } @Issue("SECURITY-2047") @Test - public void testLogin123() throws Exception { + void testLogin123() { j.jenkins.setSecurityRealm(j.createDummySecurityRealm()); j.jenkins.setAuthorizationStrategy(new MockAuthorizationStrategy()); WebClient wc = j.createWebClient(); - FailingHttpStatusCodeException e = assertThrows("Page should be protected.", FailingHttpStatusCodeException.class, () -> wc.goTo("login123")); + FailingHttpStatusCodeException e = assertThrows(FailingHttpStatusCodeException.class, () -> wc.goTo("login123"), "Page should be protected."); assertThat(e.getStatusCode(), is(403)); } @Issue("SECURITY-2047") @Test - public void testLogin123WithRead() throws Exception { + void testLogin123WithRead() throws Exception { j.jenkins.setSecurityRealm(j.createDummySecurityRealm()); j.jenkins.setAuthorizationStrategy(new MockAuthorizationStrategy(). grant(Jenkins.READ).everywhere().to("bob")); @@ -668,7 +678,7 @@ public class JenkinsTest { } @Test - public void testLogin() throws Exception { + void testLogin() throws Exception { j.jenkins.setSecurityRealm(j.createDummySecurityRealm()); j.jenkins.setAuthorizationStrategy(new MockAuthorizationStrategy(). grant(Jenkins.READ).everywhere().to("bob")); @@ -681,7 +691,7 @@ public class JenkinsTest { @Issue("JENKINS-68055") @Test - public void testTrimLabelsRetainsLabelExpressions() throws Exception { + void testTrimLabelsRetainsLabelExpressions() throws Exception { Node n = j.createOnlineSlave(); n.setLabelString("test expression"); @@ -695,11 +705,11 @@ public class JenkinsTest { } @Test - public void reloadShouldNotSaveConfig() throws Exception { + void reloadShouldNotSaveConfig() throws Exception { SaveableListenerImpl saveListener = ExtensionList.lookupSingleton(SaveableListenerImpl.class); saveListener.reset(); j.jenkins.reload(); - assertFalse("Jenkins object should not have been saved.", saveListener.wasCalled()); + assertFalse(saveListener.wasCalled(), "Jenkins object should not have been saved."); } @TestExtension("reloadShouldNotSaveConfig") @@ -741,7 +751,7 @@ public class JenkinsTest { } @Test - public void checkInitialView() { + void checkInitialView() { assertTrue(CheckInitialViewExtension.hasPrimaryView); } @@ -772,7 +782,7 @@ public class JenkinsTest { } @Test - public void reloadViews() throws Exception { + void reloadViews() throws Exception { assertThat(j.jenkins.getPrimaryView(), isA(AllView.class)); assertThat(j.jenkins.getViews(), contains(isA(AllView.class))); Files.writeString(j.jenkins.getConfigFile().getFile().toPath(), " { assertThat(r.jenkins.getNodes(), hasSize(0)); var node = new DummyAgent("my-node", "temp", r.createComputerLauncher(null)); diff --git a/test/src/test/java/jenkins/security/BasicHeaderApiTokenAuthenticatorTest.java b/test/src/test/java/jenkins/security/BasicHeaderApiTokenAuthenticatorTest.java index 940715b0fe..0621875953 100644 --- a/test/src/test/java/jenkins/security/BasicHeaderApiTokenAuthenticatorTest.java +++ b/test/src/test/java/jenkins/security/BasicHeaderApiTokenAuthenticatorTest.java @@ -28,8 +28,8 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.is; import static org.hamcrest.xml.HasXPath.hasXPath; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; import hudson.ExtensionComponent; import hudson.model.User; @@ -45,21 +45,22 @@ import org.htmlunit.WebRequest; import org.htmlunit.html.HtmlPage; import org.htmlunit.html.HtmlTextInput; import org.htmlunit.xml.XmlPage; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.jvnet.hudson.test.Issue; import org.jvnet.hudson.test.JenkinsRule; -import org.jvnet.hudson.test.JenkinsSessionRule; import org.jvnet.hudson.test.MockAuthorizationStrategy; import org.jvnet.hudson.test.TestExtension; +import org.jvnet.hudson.test.junit.jupiter.JenkinsSessionExtension; -public class BasicHeaderApiTokenAuthenticatorTest { - @Rule - public JenkinsSessionRule sessions = new JenkinsSessionRule(); +class BasicHeaderApiTokenAuthenticatorTest { + + @RegisterExtension + private final JenkinsSessionExtension sessions = new JenkinsSessionExtension(); @Test @Issue("SECURITY-896") - public void legacyToken_regularCase() throws Throwable { + void legacyToken_regularCase() throws Throwable { AtomicReference token = new AtomicReference<>(); sessions.then(j -> { enableLegacyTokenGenerationOnUserCreation(); @@ -109,7 +110,7 @@ public class BasicHeaderApiTokenAuthenticatorTest { */ @Test @Issue("SECURITY-896") - public void legacyToken_withoutLastGrantedAuthorities() throws Throwable { + void legacyToken_withoutLastGrantedAuthorities() throws Throwable { AtomicReference token = new AtomicReference<>(); sessions.then(j -> { enableLegacyTokenGenerationOnUserCreation(); diff --git a/test/src/test/java/jenkins/security/CustomClassFilterTest.java b/test/src/test/java/jenkins/security/CustomClassFilterTest.java index 4999288071..004cb6bd0b 100644 --- a/test/src/test/java/jenkins/security/CustomClassFilterTest.java +++ b/test/src/test/java/jenkins/security/CustomClassFilterTest.java @@ -24,10 +24,13 @@ package jenkins.security; +import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; +import static org.junit.jupiter.api.Assertions.assertAll; import hudson.remoting.ClassFilter; import java.io.File; +import java.io.IOException; import java.util.logging.Level; import javax.script.ScriptEngineManager; import javax.script.ScriptException; @@ -36,61 +39,75 @@ import jenkins.util.BuildListenerAdapter; import jenkins.util.TreeString; import jenkins.util.TreeStringBuilder; import org.apache.commons.io.FileUtils; -import org.junit.Rule; -import org.junit.Test; -import org.junit.experimental.categories.Category; -import org.junit.rules.ErrorCollector; -import org.junit.rules.TemporaryFolder; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.CleanupMode; +import org.junit.jupiter.api.io.TempDir; import org.jvnet.hudson.test.JenkinsRule; -import org.jvnet.hudson.test.LoggerRule; -import org.jvnet.hudson.test.SmokeTest; +import org.jvnet.hudson.test.LogRecorder; +import org.jvnet.hudson.test.junit.jupiter.WithJenkins; import org.jvnet.hudson.test.recipes.WithPlugin; -@Category(SmokeTest.class) -public class CustomClassFilterTest { +@Tag("SmokeTest") +@WithJenkins +class CustomClassFilterTest { static { System.setProperty("hudson.remoting.ClassFilter", "javax.script.SimpleBindings,!jenkins.util.TreeString"); } - @Rule - public JenkinsRule r = new JenkinsRule(); + private final LogRecorder logging = new LogRecorder().record("jenkins.security", Level.FINER); - @Rule - public ErrorCollector errors = new ErrorCollector(); + @TempDir(cleanup = CleanupMode.NEVER) + private File tmp; - @Rule - public LoggerRule logging = new LoggerRule().record("jenkins.security", Level.FINER); + private JenkinsRule r; + + @BeforeEach + void setUp(JenkinsRule rule) { + r = rule; + } - @Rule - public TemporaryFolder tmp = new TemporaryFolder(); @WithPlugin("custom-class-filter.jpi") @Test - public void smokes() throws Exception { - assertBlacklisted("enabled via system property", SimpleBindings.class, false); - assertBlacklisted("enabled via plugin", ScriptException.class, false); - assertBlacklisted("disabled by ClassFilter.STANDARD", ScriptEngineManager.class, true); - assertBlacklisted("part of Jenkins core, so why not?", BuildListenerAdapter.class, false); - // As an aside, the following appear totally unused anyway! - assertBlacklisted("disabled via system property", TreeString.class, true); - assertBlacklisted("disabled via plugin", TreeStringBuilder.class, true); + void smokes() { + assertAll( + () -> assertBlacklisted("enabled via system property", SimpleBindings.class, false), + () -> assertBlacklisted("enabled via plugin", ScriptException.class, false), + () -> assertBlacklisted("disabled by ClassFilter.STANDARD", ScriptEngineManager.class, true), + () -> assertBlacklisted("part of Jenkins core, so why not?", BuildListenerAdapter.class, false), + // As an aside, the following appear totally unused anyway! + () -> assertBlacklisted("disabled via system property", TreeString.class, true), + () -> assertBlacklisted("disabled via plugin", TreeStringBuilder.class, true) + ); } @Test - public void dynamicLoad() throws Exception { - assertBlacklisted("not yet enabled via plugin", ScriptException.class, true); - assertBlacklisted("not yet disabled via plugin", TreeStringBuilder.class, false); - File jpi = tmp.newFile("custom-class-filter.jpi"); - FileUtils.copyURLToFile(CustomClassFilterTest.class.getResource("/plugins/custom-class-filter.jpi"), jpi); - r.jenkins.pluginManager.dynamicLoad(jpi); - assertBlacklisted("enabled via plugin", ScriptException.class, false); - assertBlacklisted("disabled via plugin", TreeStringBuilder.class, true); + void dynamicLoad() { + assertAll( + () -> assertBlacklisted("not yet enabled via plugin", ScriptException.class, true), + () -> assertBlacklisted("not yet disabled via plugin", TreeStringBuilder.class, false), + () -> { + File jpi = newFile(tmp, "custom-class-filter.jpi"); + FileUtils.copyURLToFile(CustomClassFilterTest.class.getResource("/plugins/custom-class-filter.jpi"), jpi); + r.jenkins.pluginManager.dynamicLoad(jpi); + }, + () -> assertBlacklisted("enabled via plugin", ScriptException.class, false), + () -> assertBlacklisted("disabled via plugin", TreeStringBuilder.class, true) + ); } private void assertBlacklisted(String message, Class c, boolean blacklisted) { String name = c.getName(); - errors.checkThat(name + ": " + message, ClassFilter.DEFAULT.isBlacklisted(c) || ClassFilter.DEFAULT.isBlacklisted(name), is(blacklisted)); + assertThat(name + ": " + message, ClassFilter.DEFAULT.isBlacklisted(c) || ClassFilter.DEFAULT.isBlacklisted(name), is(blacklisted)); + } + + private static File newFile(File parent, String child) throws IOException { + File result = new File(parent, child); + result.createNewFile(); + return result; } } diff --git a/test/src/test/java/jenkins/security/JettySameSiteCookieSetupTest.java b/test/src/test/java/jenkins/security/JettySameSiteCookieSetupTest.java index 6557569312..df5fc5bf54 100644 --- a/test/src/test/java/jenkins/security/JettySameSiteCookieSetupTest.java +++ b/test/src/test/java/jenkins/security/JettySameSiteCookieSetupTest.java @@ -7,16 +7,22 @@ import java.util.HashMap; import java.util.Map; import java.util.Set; import jenkins.model.Jenkins; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -import org.jvnet.hudson.test.FlagRule; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.junit.jupiter.params.Parameter; +import org.junit.jupiter.params.ParameterizedClass; +import org.junit.jupiter.params.provider.MethodSource; import org.jvnet.hudson.test.JenkinsRule; import org.jvnet.hudson.test.MockAuthorizationStrategy; +import org.jvnet.hudson.test.junit.jupiter.JenkinsSessionExtension; +import org.jvnet.hudson.test.junit.jupiter.WithJenkins; -@RunWith(Parameterized.class) -public class JettySameSiteCookieSetupTest { +@WithJenkins +@ParameterizedClass +@MethodSource("sameSite") +class JettySameSiteCookieSetupTest { private static final Map FLAG_TO_SAMESITE_COOKIE = new HashMap<>() {{ put("", null); @@ -25,35 +31,49 @@ public class JettySameSiteCookieSetupTest { put(null, "lax"); }}; - @Rule - public JenkinsRule j = new JenkinsRule(); + @RegisterExtension + private final JenkinsSessionExtension session = new JenkinsSessionExtension(); - @Rule - public FlagRule sameSiteCookie; + private String sameSiteCookie; - private final String sameSiteValue; + @Parameter + private String sameSiteValue; - public JettySameSiteCookieSetupTest(String sameSiteValue) { - this.sameSiteValue = sameSiteValue; - sameSiteCookie = FlagRule.systemProperty(JettySameSiteCookieSetup.class.getName() + ".sameSiteDefault", sameSiteValue); - } - - @Parameterized.Parameters - public static Set sameSite() { + static Set sameSite() { return FLAG_TO_SAMESITE_COOKIE.keySet(); } - @Test - public void testJettyFlagSetsSameSiteCookieProperty() throws Exception { - String expected = FLAG_TO_SAMESITE_COOKIE.get(this.sameSiteValue); - j.jenkins.setSecurityRealm(j.createDummySecurityRealm()); - j.jenkins.setAuthorizationStrategy(new MockAuthorizationStrategy().grant(Jenkins.ADMINISTER).everywhere().to("admin")); - - try (JenkinsRule.WebClient wc = j.createWebClient()) { - wc.login("admin", "admin", true); - - assertThat(wc.getCookieManager().getCookie("JSESSIONID").getSameSite(), is(expected)); - assertThat(wc.getCookieManager().getCookie("remember-me").getSameSite(), is(expected)); + @BeforeEach + void setUp() { + if (sameSiteValue != null) { + sameSiteCookie = System.setProperty(JettySameSiteCookieSetup.class.getName() + ".sameSiteDefault", sameSiteValue); + } else { + sameSiteCookie = System.clearProperty(JettySameSiteCookieSetup.class.getName() + ".sameSiteDefault"); } } + + @AfterEach + void tearDown() { + if (sameSiteCookie != null) { + System.setProperty(JettySameSiteCookieSetup.class.getName() + ".sameSiteDefault", sameSiteCookie); + } else { + System.clearProperty(JettySameSiteCookieSetup.class.getName() + ".sameSiteDefault"); + } + } + + @Test + void testJettyFlagSetsSameSiteCookieProperty() throws Throwable { + String expected = FLAG_TO_SAMESITE_COOKIE.get(sameSiteValue); + session.then(j -> { + j.jenkins.setSecurityRealm(j.createDummySecurityRealm()); + j.jenkins.setAuthorizationStrategy(new MockAuthorizationStrategy().grant(Jenkins.ADMINISTER).everywhere().to("admin")); + + try (JenkinsRule.WebClient wc = j.createWebClient()) { + wc.login("admin", "admin", true); + + assertThat(wc.getCookieManager().getCookie("JSESSIONID").getSameSite(), is(expected)); + assertThat(wc.getCookieManager().getCookie("remember-me").getSameSite(), is(expected)); + } + }); + } } diff --git a/test/src/test/java/jenkins/security/Security218Test.java b/test/src/test/java/jenkins/security/Security218Test.java index 9c5efd1552..584f33183b 100644 --- a/test/src/test/java/jenkins/security/Security218Test.java +++ b/test/src/test/java/jenkins/security/Security218Test.java @@ -2,33 +2,39 @@ package jenkins.security; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; -import static org.junit.Assert.assertThrows; +import static org.junit.jupiter.api.Assertions.assertThrows; import hudson.slaves.DumbSlave; import java.io.IOException; -import java.io.Serializable; import java.util.logging.Level; import org.codehaus.groovy.runtime.MethodClosure; -import org.junit.Rule; -import org.junit.Test; -import org.jvnet.hudson.test.InboundAgentRule; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.jvnet.hudson.test.Issue; import org.jvnet.hudson.test.JenkinsRule; -import org.jvnet.hudson.test.LoggerRule; +import org.jvnet.hudson.test.LogRecorder; +import org.jvnet.hudson.test.junit.jupiter.InboundAgentExtension; +import org.jvnet.hudson.test.junit.jupiter.WithJenkins; /** * @author Kohsuke Kawaguchi */ @Issue("SECURITY-218") -public class Security218Test implements Serializable { - @Rule - public transient JenkinsRule j = new JenkinsRule(); +@WithJenkins +class Security218Test { - @Rule - public transient InboundAgentRule inboundAgents = new InboundAgentRule(); + @RegisterExtension + private final InboundAgentExtension inboundAgents = new InboundAgentExtension(); - @Rule - public LoggerRule logging = new LoggerRule().record(ClassFilterImpl.class, Level.FINE); + private final LogRecorder logging = new LogRecorder().record(ClassFilterImpl.class, Level.FINE); + + private JenkinsRule j; + + @BeforeEach + void setUp(JenkinsRule rule) { + j = rule; + } /** * Makes sure SECURITY-218 fix also applies to agents. @@ -36,7 +42,7 @@ public class Security218Test implements Serializable { * This test is for regular static agent */ @Test - public void dumbSlave() throws Exception { + void dumbSlave() throws Exception { check(j.createOnlineSlave()); } @@ -46,8 +52,8 @@ public class Security218Test implements Serializable { * This test is for JNLP agent */ @Test - public void jnlpSlave() throws Exception { - DumbSlave a = (DumbSlave) inboundAgents.createAgent(j, InboundAgentRule.Options.newBuilder().secret().build()); + void jnlpSlave() throws Exception { + DumbSlave a = (DumbSlave) inboundAgents.createAgent(j, InboundAgentExtension.Options.newBuilder().build()); try { j.createWebClient().goTo("computer/" + a.getNodeName() + "/jenkins-agent.jnlp?encrypt=true", "application/octet-stream"); check(a); @@ -63,9 +69,9 @@ public class Security218Test implements Serializable { @SuppressWarnings("ConstantConditions") private void check(DumbSlave s) { IOException e = assertThrows( - "Expected the connection to die", IOException.class, - () -> s.getComputer().getChannel().call(new EvilReturnValue())); + () -> s.getComputer().getChannel().call(new EvilReturnValue()), + "Expected the connection to die"); assertThat(e.getMessage(), containsString(MethodClosure.class.getName())); } diff --git a/test/src/test/java/jenkins/security/Security3430Test.java b/test/src/test/java/jenkins/security/Security3430Test.java index 6eed13cb92..363ad0476e 100644 --- a/test/src/test/java/jenkins/security/Security3430Test.java +++ b/test/src/test/java/jenkins/security/Security3430Test.java @@ -7,10 +7,10 @@ import static org.hamcrest.Matchers.hasItem; import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.not; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertThrows; -import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; import hudson.ExtensionList; import hudson.model.Computer; @@ -38,37 +38,38 @@ import org.apache.commons.io.IOUtils; import org.hamcrest.Description; import org.hamcrest.Matcher; import org.hamcrest.TypeSafeMatcher; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TemporaryFolder; -import org.jvnet.hudson.test.InboundAgentRule; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.junit.jupiter.api.io.TempDir; import org.jvnet.hudson.test.JenkinsRule; -import org.jvnet.hudson.test.RealJenkinsRule; +import org.jvnet.hudson.test.junit.jupiter.InboundAgentExtension; +import org.jvnet.hudson.test.junit.jupiter.RealJenkinsExtension; import org.kohsuke.args4j.Argument; import org.kohsuke.stapler.Stapler; -public class Security3430Test { - @Rule - public RealJenkinsRule jj = new RealJenkinsRule().withLogger(JarURLValidatorImpl.class, Level.FINEST); +class Security3430Test { - @Rule - public InboundAgentRule agents = new InboundAgentRule(); + @RegisterExtension + private final RealJenkinsExtension jj = new RealJenkinsExtension().withLogger(JarURLValidatorImpl.class, Level.FINEST); - @Rule - public TemporaryFolder tmp = new TemporaryFolder(); + @RegisterExtension + private final InboundAgentExtension agents = new InboundAgentExtension(); + + @TempDir + private File tmp; @Test - public void runWithOldestSupportedAgentJar() throws Throwable { + void runWithOldestSupportedAgentJar() throws Throwable { runWithRemoting(RemotingVersionInfo.getMinimumSupportedVersion().toString(), "/old-remoting/remoting-minimum-supported.jar", true); } @Test - public void runWithPreviousAgentJar() throws Throwable { + void runWithPreviousAgentJar() throws Throwable { runWithRemoting("3256.v88a_f6e922152", "/old-remoting/remoting-before-SECURITY-3430-fix.jar", true); } @Test - public void runWithCurrentAgentJar() throws Throwable { + void runWithCurrentAgentJar() throws Throwable { runWithRemoting(Launcher.VERSION, null, false); } @@ -93,19 +94,19 @@ public class Security3430Test { private void createAgent(String name, String remotingResourcePath) throws Throwable { if (remotingResourcePath != null) { - var jar = tmp.newFile(name + ".jar"); + var jar = newFile(tmp, name + ".jar"); FileUtils.copyURLToFile(Security3430Test.class.getResource(remotingResourcePath), jar); // TODO awkward, especially as InboundAgentRule.getAgentArguments is private; // would be helpful to have an option for a specific agent JAR: - var opts = InboundAgentRule.Options.newBuilder().name(name).skipStart().build(); + var opts = InboundAgentExtension.Options.newBuilder().name(name).skipStart().build(); agents.createAgent(jj, opts); - agents.start(new InboundAgentRule.AgentArguments(jar, jj.getUrl().toString(), name, jj.runRemotely(Security3430Test::getJnlpMac, name), 1, List.of()), opts); + agents.start(new InboundAgentExtension.AgentArguments(jar, jj.getUrl().toString(), name, jj.runRemotely(Security3430Test::getJnlpMac, name), 1, List.of()), opts); } else { - agents.createAgent(jj, InboundAgentRule.Options.newBuilder().name(name).build()); + agents.createAgent(jj, InboundAgentExtension.Options.newBuilder().name(name).build()); } } - private static String getJnlpMac(JenkinsRule r, String name) throws Throwable { + private static String getJnlpMac(JenkinsRule r, String name) { return ((SlaveComputer) r.jenkins.getComputer(name)).getJnlpMac(); } @@ -314,4 +315,10 @@ public class Security3430Test { mismatchDescription.appendText(item.getMessage()); } } + + private static File newFile(File parent, String child) throws IOException { + File result = new File(parent, child); + result.createNewFile(); + return result; + } } diff --git a/test/src/test/java/jenkins/security/Security637Test.java b/test/src/test/java/jenkins/security/Security637Test.java index 71550b6423..1a170e62d9 100644 --- a/test/src/test/java/jenkins/security/Security637Test.java +++ b/test/src/test/java/jenkins/security/Security637Test.java @@ -28,9 +28,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.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assume.assumeNoException; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assumptions.assumeTrue; import hudson.EnvVars; import hudson.Launcher; @@ -48,21 +48,21 @@ import java.net.URLStreamHandler; import java.util.Collections; import java.util.HashSet; import java.util.Set; -import org.junit.Ignore; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.jvnet.hudson.test.Issue; -import org.jvnet.hudson.test.JenkinsSessionRule; import org.jvnet.hudson.test.TestExtension; +import org.jvnet.hudson.test.junit.jupiter.JenkinsSessionExtension; -public class Security637Test { +class Security637Test { - @Rule - public JenkinsSessionRule sessions = new JenkinsSessionRule(); + @RegisterExtension + private final JenkinsSessionExtension sessions = new JenkinsSessionExtension(); @Test @Issue("SECURITY-637") - public void urlSafeDeserialization_handler_inSameJVMRemotingContext() throws Throwable { + void urlSafeDeserialization_handler_inSameJVMRemotingContext() throws Throwable { sessions.then(j -> { DumbSlave slave = j.createOnlineSlave(null, new EnvVars("JAVA_TOOL_OPTIONS", "--add-opens=java.base/java.net=ALL-UNNAMED")); String unsafeHandlerClassName = slave.getChannel().call(new URLHandlerCallable(new URL("https://www.google.com/"))); @@ -89,23 +89,22 @@ public class Security637Test { } } - @Ignore("TODO these map to different IPs now") + @Disabled("TODO these map to different IPs now") @Test @Issue("SECURITY-637") - public void urlDnsEquivalence() throws Throwable { - sessions.then(j -> { + void urlDnsEquivalence() throws Throwable { + sessions.then(j -> // due to the DNS resolution they are equal assertEquals( new URI("https://jenkins.io").toURL(), new URI("https://www.jenkins.io").toURL() - ); - }); + )); } - @Ignore("TODO these map to different IPs now") + @Disabled("TODO these map to different IPs now") @Test @Issue("SECURITY-637") - public void urlSafeDeserialization_urlBuiltInAgent_inSameJVMRemotingContext() throws Throwable { + void urlSafeDeserialization_urlBuiltInAgent_inSameJVMRemotingContext() throws Throwable { sessions.then(j -> { DumbSlave slave = j.createOnlineSlave(); @@ -132,10 +131,10 @@ public class Security637Test { } } - @Ignore("TODO these map to different IPs now") + @Disabled("TODO these map to different IPs now") @Test @Issue("SECURITY-637") - public void urlSafeDeserialization_urlBuiltInMaster_inSameJVMRemotingContext() throws Throwable { + void urlSafeDeserialization_urlBuiltInMaster_inSameJVMRemotingContext() throws Throwable { sessions.then(j -> { DumbSlave slave = j.createOnlineSlave(); @@ -171,7 +170,7 @@ public class Security637Test { @Test @Issue("SECURITY-637") - public void urlSafeDeserialization_inXStreamContext() throws Throwable { + void urlSafeDeserialization_inXStreamContext() throws Throwable { sessions.then(j -> { FreeStyleProject project = j.createFreeStyleProject("project-with-url"); URLJobProperty URLJobProperty = new URLJobProperty( @@ -193,7 +192,7 @@ public class Security637Test { try { handlerField.setAccessible(true); } catch (RuntimeException e) { - assumeNoException(e); + assumeTrue(false, e.getMessage()); } URLJobProperty urlJobProperty = project.getProperty(URLJobProperty.class); @@ -212,6 +211,7 @@ public class Security637Test { private Set urlSet; + @SuppressWarnings(value = "checkstyle:redundantmodifier") public URLJobProperty(URL... urls) { this.urlSet = new HashSet<>(); Collections.addAll(urlSet, urls); diff --git a/test/src/test/java/jenkins/security/apitoken/ApiTokenStatsRestartTest.java b/test/src/test/java/jenkins/security/apitoken/ApiTokenStatsRestartTest.java index d76d382e10..e4dd015bbb 100644 --- a/test/src/test/java/jenkins/security/apitoken/ApiTokenStatsRestartTest.java +++ b/test/src/test/java/jenkins/security/apitoken/ApiTokenStatsRestartTest.java @@ -29,10 +29,10 @@ import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.not; import static org.hamcrest.xml.HasXPath.hasXPath; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertThrows; -import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; import hudson.model.User; import java.io.File; @@ -50,23 +50,23 @@ import org.htmlunit.html.HtmlPage; import org.htmlunit.html.HtmlSpan; import org.htmlunit.util.NameValuePair; import org.htmlunit.xml.XmlPage; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.jvnet.hudson.test.For; import org.jvnet.hudson.test.Issue; import org.jvnet.hudson.test.JenkinsRule; import org.jvnet.hudson.test.JenkinsRule.WebClient; -import org.jvnet.hudson.test.JenkinsSessionRule; +import org.jvnet.hudson.test.junit.jupiter.JenkinsSessionExtension; @For(ApiTokenStats.class) -public class ApiTokenStatsRestartTest { +class ApiTokenStatsRestartTest { - @Rule - public JenkinsSessionRule sessions = new JenkinsSessionRule(); + @RegisterExtension + private final JenkinsSessionExtension sessions = new JenkinsSessionExtension(); @Test @Issue("SECURITY-1072") - public void roundtripWithRestart() throws Throwable { + void roundtripWithRestart() throws Throwable { AtomicReference tokenValue = new AtomicReference<>(); AtomicReference tokenUuid = new AtomicReference<>(); String TOKEN_NAME = "New Token Name"; @@ -119,7 +119,7 @@ public class ApiTokenStatsRestartTest { assertThat(useCounterSpan.getTextContent(), containsString("" + NUM_CALL_WITH_TOKEN)); File apiTokenStatsFile = new File(u.getUserFolder(), "apiTokenStats.xml"); - assertTrue("apiTokenStats.xml file should exist", apiTokenStatsFile.exists()); + assertTrue(apiTokenStatsFile.exists(), "apiTokenStats.xml file should exist"); }); sessions.then(j -> { @@ -159,7 +159,7 @@ public class ApiTokenStatsRestartTest { assertThat(xmlPage, hasXPath("//authority", is("authenticated"))); } - private static void checkUserIsNotConnected(WebClient wc) throws Exception { + private static void checkUserIsNotConnected(WebClient wc) { FailingHttpStatusCodeException e = assertThrows(FailingHttpStatusCodeException.class, () -> wc.goToXml("whoAmI/api/xml")); assertEquals(401, e.getStatusCode()); } diff --git a/test/src/test/java/jenkins/security/seed/UserSeedPropertyRestartTest.java b/test/src/test/java/jenkins/security/seed/UserSeedPropertyRestartTest.java index 0d44074d67..ecd8f79062 100644 --- a/test/src/test/java/jenkins/security/seed/UserSeedPropertyRestartTest.java +++ b/test/src/test/java/jenkins/security/seed/UserSeedPropertyRestartTest.java @@ -24,31 +24,31 @@ package jenkins.security.seed; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; import hudson.model.User; import java.net.URI; import java.util.concurrent.atomic.AtomicReference; import org.htmlunit.HttpMethod; import org.htmlunit.WebRequest; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.jvnet.hudson.test.For; import org.jvnet.hudson.test.Issue; import org.jvnet.hudson.test.JenkinsRule; -import org.jvnet.hudson.test.JenkinsSessionRule; +import org.jvnet.hudson.test.junit.jupiter.JenkinsSessionExtension; @For(UserSeedProperty.class) -public class UserSeedPropertyRestartTest { +class UserSeedPropertyRestartTest { - @Rule - public JenkinsSessionRule sessions = new JenkinsSessionRule(); + @RegisterExtension + private final JenkinsSessionExtension sessions = new JenkinsSessionExtension(); @Test @Issue("SECURITY-901") - public void initialSeedIsSaved() throws Throwable { + void initialSeedIsSaved() throws Throwable { AtomicReference initialSeedRef = new AtomicReference<>(); sessions.then(j -> { @@ -68,7 +68,7 @@ public class UserSeedPropertyRestartTest { @Test @Issue("SECURITY-901") - public void renewSeedSavesTheChange() throws Throwable { + void renewSeedSavesTheChange() throws Throwable { AtomicReference initialSeedRef = new AtomicReference<>(); AtomicReference seedRef = new AtomicReference<>(); diff --git a/test/src/test/java/jenkins/security/stapler/JenkinsSupportAnnotationsTest.java b/test/src/test/java/jenkins/security/stapler/JenkinsSupportAnnotationsTest.java index 6ddee5cf60..88fb00dbfe 100644 --- a/test/src/test/java/jenkins/security/stapler/JenkinsSupportAnnotationsTest.java +++ b/test/src/test/java/jenkins/security/stapler/JenkinsSupportAnnotationsTest.java @@ -1,26 +1,32 @@ package jenkins.security.stapler; -import static org.junit.Assume.assumeFalse; +import static org.junit.jupiter.api.Assumptions.assumeFalse; import hudson.Functions; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.jvnet.hudson.test.For; import org.jvnet.hudson.test.Issue; import org.jvnet.hudson.test.JenkinsRule; +import org.jvnet.hudson.test.junit.jupiter.WithJenkins; import org.jvnet.hudson.test.recipes.WithPlugin; @Issue("SECURITY-400") @For({StaplerDispatchable.class, StaplerAccessibleType.class}) -public class JenkinsSupportAnnotationsTest { +@WithJenkins +class JenkinsSupportAnnotationsTest { - @Rule - public JenkinsRule j = new JenkinsRule(); + private JenkinsRule j; + + @BeforeEach + void setUp(JenkinsRule rule) { + j = rule; + } @Test @WithPlugin("annotations-test.hpi") - public void testPluginWithAnnotations() throws Exception { - assumeFalse("TODO: Implement this test on Windows", Functions.isWindows()); + void testPluginWithAnnotations() throws Exception { + assumeFalse(Functions.isWindows(), "TODO: Implement this test on Windows"); // test fails if TypedFilter ignores @StaplerDispatchable j.createWebClient().goTo("annotationsTest/whatever", ""); diff --git a/test/src/test/java/jenkins/slaves/restarter/JnlpSlaveRestarterInstallerTest.java b/test/src/test/java/jenkins/slaves/restarter/JnlpSlaveRestarterInstallerTest.java index e79ae95902..6936043b1c 100644 --- a/test/src/test/java/jenkins/slaves/restarter/JnlpSlaveRestarterInstallerTest.java +++ b/test/src/test/java/jenkins/slaves/restarter/JnlpSlaveRestarterInstallerTest.java @@ -24,8 +24,8 @@ package jenkins.slaves.restarter; -import static org.junit.Assert.assertEquals; -import static org.junit.Assume.assumeFalse; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assumptions.assumeFalse; import hudson.Functions; import hudson.model.Slave; @@ -33,52 +33,51 @@ import hudson.slaves.DumbSlave; import java.util.concurrent.atomic.AtomicBoolean; import java.util.logging.Level; import jenkins.security.MasterToSlaveCallable; -import org.junit.Rule; -import org.junit.Test; -import org.jvnet.hudson.test.InboundAgentRule; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.jvnet.hudson.test.Issue; -import org.jvnet.hudson.test.JenkinsSessionRule; -import org.jvnet.hudson.test.LoggerRule; +import org.jvnet.hudson.test.LogRecorder; +import org.jvnet.hudson.test.junit.jupiter.InboundAgentExtension; +import org.jvnet.hudson.test.junit.jupiter.JenkinsSessionExtension; -public class JnlpSlaveRestarterInstallerTest { +class JnlpSlaveRestarterInstallerTest { - @Rule - public JenkinsSessionRule rr = new JenkinsSessionRule(); + @RegisterExtension + private final JenkinsSessionExtension rr = new JenkinsSessionExtension(); - @Rule - public InboundAgentRule inboundAgents = new InboundAgentRule(); + @RegisterExtension + private final InboundAgentExtension inboundAgents = new InboundAgentExtension(); - @Rule - public LoggerRule logging = new LoggerRule().record(JnlpSlaveRestarterInstaller.class, Level.FINE).capture(10); + private final LogRecorder logging = new LogRecorder().record(JnlpSlaveRestarterInstaller.class, Level.FINE).capture(10); @Issue("JENKINS-19055") @Test - public void tcpReconnection() throws Throwable { + void tcpReconnection() throws Throwable { // TODO Enable when test is reliable on Windows agents of ci.jenkins.io // When builds switched from ACI containers to virtual machines, this test consistently failed // When the test is run on local Windows computers, it passes // Disable the test on ci.jenkins.io and friends when running Windows // Do not disable for Windows developers generally - assumeFalse("TODO: Test fails on Windows VM", Functions.isWindows() && System.getenv("CI") != null); + assumeFalse(Functions.isWindows() && System.getenv("CI") != null, "TODO: Test fails on Windows VM"); reconnection(false); } @Issue("JENKINS-66446") @Test - public void webSocketReconnection() throws Throwable { + void webSocketReconnection() throws Throwable { // TODO Enable when test is reliable on Windows agents of ci.jenkins.io // When builds switched from ACI containers to virtual machines, this test consistently failed // When the test is run on local Windows computers, it passes // Disable the test on ci.jenkins.io and friends when running Windows // Do not disable for Windows developers generally - assumeFalse("TODO: Test fails on Windows VM", Functions.isWindows() && System.getenv("CI") != null); + assumeFalse(Functions.isWindows() && System.getenv("CI") != null, "TODO: Test fails on Windows VM"); reconnection(true); } private void reconnection(boolean webSocket) throws Throwable { AtomicBoolean canWork = new AtomicBoolean(); rr.then(r -> { - InboundAgentRule.Options.Builder builder = InboundAgentRule.Options.newBuilder().name("remote").secret(); + InboundAgentExtension.Options.Builder builder = InboundAgentExtension.Options.newBuilder().name("remote"); if (webSocket) { builder.webSocket(); } diff --git a/test/src/test/java/jenkins/triggers/ReverseBuildTriggerAfterRestartTest.java b/test/src/test/java/jenkins/triggers/ReverseBuildTriggerAfterRestartTest.java index 5694bc5700..57cc04b71c 100644 --- a/test/src/test/java/jenkins/triggers/ReverseBuildTriggerAfterRestartTest.java +++ b/test/src/test/java/jenkins/triggers/ReverseBuildTriggerAfterRestartTest.java @@ -1,21 +1,21 @@ package jenkins.triggers; -import static org.junit.Assert.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNotNull; import hudson.model.FreeStyleProject; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.jvnet.hudson.test.Issue; -import org.jvnet.hudson.test.JenkinsSessionRule; +import org.jvnet.hudson.test.junit.jupiter.JenkinsSessionExtension; -public class ReverseBuildTriggerAfterRestartTest { +class ReverseBuildTriggerAfterRestartTest { - @Rule - public JenkinsSessionRule rule = new JenkinsSessionRule(); + @RegisterExtension + private final JenkinsSessionExtension rule = new JenkinsSessionExtension(); @Issue("JENKINS-67237") @Test - public void testExecutionOfReverseBuildTriggersAfterRestart() throws Throwable { + void testExecutionOfReverseBuildTriggersAfterRestart() throws Throwable { String nameOfUpstreamProject = "upstreamProject"; String nameOfDownstreamProject = "downstreamProject"; diff --git a/test/src/test/java/jenkins/util/SetContextClassLoaderTest.java b/test/src/test/java/jenkins/util/SetContextClassLoaderTest.java index 71cd6e9354..f7f4cddfc5 100644 --- a/test/src/test/java/jenkins/util/SetContextClassLoaderTest.java +++ b/test/src/test/java/jenkins/util/SetContextClassLoaderTest.java @@ -1,19 +1,21 @@ package jenkins.util; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertThrows; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.jvnet.hudson.test.JenkinsRule; import org.jvnet.hudson.test.RealJenkinsRule; +import org.jvnet.hudson.test.junit.jupiter.RealJenkinsExtension; -public class SetContextClassLoaderTest { +class SetContextClassLoaderTest { - @Rule public RealJenkinsRule rr = new RealJenkinsRule(); + @RegisterExtension + private final RealJenkinsExtension rr = new RealJenkinsExtension(); @Test - public void positive() throws Throwable { + void positive() throws Throwable { rr.then(SetContextClassLoaderTest::_positive); } @@ -24,7 +26,7 @@ public class SetContextClassLoaderTest { } @Test - public void negative() throws Throwable { + void negative() throws Throwable { rr.then(SetContextClassLoaderTest::_negative); } diff --git a/test/src/test/java/jenkins/util/SystemPropertiesTest.java b/test/src/test/java/jenkins/util/SystemPropertiesTest.java index 121886a754..2308058715 100644 --- a/test/src/test/java/jenkins/util/SystemPropertiesTest.java +++ b/test/src/test/java/jenkins/util/SystemPropertiesTest.java @@ -29,8 +29,8 @@ import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.hasItem; import static org.hamcrest.Matchers.nullValue; -import static org.junit.Assert.assertEquals; -import static org.junit.Assume.assumeTrue; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assumptions.assumeTrue; import jakarta.servlet.ServletContextEvent; import java.time.Duration; @@ -51,7 +51,9 @@ import org.jvnet.hudson.test.junit.jupiter.WithJenkins; */ @WithJenkins class SystemPropertiesTest { + private final LogRecorder logging = new LogRecorder().record(SystemProperties.class, Level.WARNING); + private JenkinsRule j; @BeforeEach @@ -105,7 +107,7 @@ class SystemPropertiesTest { } @Test - public void duration() { + void duration() { System.setProperty("foo.bar", "1s"); assertEquals(Duration.ofSeconds(1), SystemProperties.getDuration("foo.bar")); System.setProperty("foo.bar", "2m"); @@ -130,7 +132,7 @@ class SystemPropertiesTest { } @Test - public void invalid() { + void invalid() { logging.capture(10); System.setProperty("abc.def", "invalid"); assertThat(SystemProperties.getDuration("abc.def"), Matchers.nullValue()); diff --git a/test/src/test/java/lib/layout/RenderOnDemandTest.java b/test/src/test/java/lib/layout/RenderOnDemandTest.java index b17ef2fdf8..1f7b4d8383 100644 --- a/test/src/test/java/lib/layout/RenderOnDemandTest.java +++ b/test/src/test/java/lib/layout/RenderOnDemandTest.java @@ -56,7 +56,7 @@ import org.jvnet.hudson.test.junit.jupiter.WithJenkins; class RenderOnDemandTest { private JenkinsRule j; - private LogRecorder logging = new LogRecorder().record(RenderOnDemandClosure.class, Level.FINE); + private final LogRecorder logging = new LogRecorder().record(RenderOnDemandClosure.class, Level.FINE); @BeforeEach void setUp(JenkinsRule rule) { @@ -83,7 +83,7 @@ class RenderOnDemandTest { @Disabled("just informational") @Issue("JENKINS-16341") @Test - public void testMemoryConsumption() throws Exception { + void testMemoryConsumption() throws Exception { var wc = j.createWebClient(); callTestBehaviour(wc); // prime caches int total = 0; diff --git a/test/src/test/java/org/jenkins/ui/symbol/SymbolJenkinsTest.java b/test/src/test/java/org/jenkins/ui/symbol/SymbolJenkinsTest.java index 49aaa9cd4f..b7b9944c14 100644 --- a/test/src/test/java/org/jenkins/ui/symbol/SymbolJenkinsTest.java +++ b/test/src/test/java/org/jenkins/ui/symbol/SymbolJenkinsTest.java @@ -4,22 +4,23 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.not; -import org.junit.Rule; -import org.junit.Test; import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.jvnet.hudson.test.Issue; import org.jvnet.hudson.test.JenkinsRule; -import org.jvnet.hudson.test.RealJenkinsRule; +import org.jvnet.hudson.test.junit.jupiter.RealJenkinsExtension; -public class SymbolJenkinsTest { - @Rule - public RealJenkinsRule rjr = new RealJenkinsRule() +class SymbolJenkinsTest { + + @RegisterExtension + private final RealJenkinsExtension rjr = new RealJenkinsExtension() .addPlugins("plugins/design-library.jpi", "plugins/prism-api.jpi", "plugins/bootstrap5-api.jpi"); @Test @Issue("JENKINS-73243") @DisplayName("When resolving a symbol where the tooltip contains '$' no error is thrown") - public void dollarInToolTipSucceeds() throws Throwable { + void dollarInToolTipSucceeds() throws Throwable { rjr.then(SymbolJenkinsTest::_dollarInTooltipSucceeds); } @@ -34,7 +35,7 @@ public class SymbolJenkinsTest { @Test @DisplayName("When resolving a symbol from a missing plugin, the placeholder is generated instead") - public void missingSymbolFromPluginDefaultsToPlaceholder() throws Throwable { + void missingSymbolFromPluginDefaultsToPlaceholder() throws Throwable { rjr.then(SymbolJenkinsTest::_missingSymbolFromPluginDefaultsToPlaceholder); } @@ -49,7 +50,7 @@ public class SymbolJenkinsTest { @Test @DisplayName("Resolving a valid symbol from an installed plugin does not return the placeholder") - public void resolvingSymbolFromPlugin() throws Throwable { + void resolvingSymbolFromPlugin() throws Throwable { rjr.then(SymbolJenkinsTest::_resolvingSymbolFromPlugin); } From 934711acdc6fcf0705c9903476a8d268faadab9d Mon Sep 17 00:00:00 2001 From: strangelookingnerd <49242855+strangelookingnerd@users.noreply.github.com> Date: Thu, 31 Jul 2025 14:49:30 +0200 Subject: [PATCH 2/2] Migrate tests to JUnit5 * second batch of green tests --- .../hudson/ClassicPluginStrategyTest.java | 190 ++-- .../java/hudson/CustomPluginManagerTest.java | 44 +- .../hudson/ExtensionListListenerTest.java | 41 +- .../hudson/PluginManagerInstalledGUITest.java | 238 +++-- .../test/java/hudson/PluginManagerTest.java | 971 ++++++++++-------- .../test/java/hudson/PluginManagerUtil.java | 55 +- .../java/hudson/cli/BuildCommandTest.java | 5 +- .../test/java/hudson/model/ComputerTest.java | 5 +- .../java/hudson/model/QueueCrashTest.java | 77 +- .../hudson/model/UpdateCenterCustomTest.java | 114 +- .../model/UpdateCenterMigrationTest.java | 92 +- .../java/hudson/util/BootFailureTest.java | 242 +++-- .../java/jenkins/bugs/Jenkins64991Test.java | 64 +- .../install/LoadDetachedPluginsTest.java | 48 +- .../java/jenkins/model/ErrorPageTest.java | 47 +- .../JenkinsLocationConfigurationTest.java | 275 +++-- .../jenkins/security/Security3501Test.java | 43 +- .../SecurityContextExecutorServiceTest.java | 73 +- .../jenkins/slaves/OldRemotingAgentTest.java | 159 ++- ...supportedRemotingAgentEscapeHatchTest.java | 135 ++- .../slaves/UnsupportedRemotingAgentTest.java | 109 +- test/src/test/java/lib/form/NameRefTest.java | 39 +- .../java/org/kohsuke/stapler/BindTest.java | 48 +- .../test1.jelly | 0 24 files changed, 1882 insertions(+), 1232 deletions(-) rename test/src/test/resources/lib/form/NameRefTest/{JenkinsRuleWithJelly => RootActionImpl}/test1.jelly (100%) diff --git a/test/src/test/java/hudson/ClassicPluginStrategyTest.java b/test/src/test/java/hudson/ClassicPluginStrategyTest.java index 1bf06531d6..5061896ce1 100644 --- a/test/src/test/java/hudson/ClassicPluginStrategyTest.java +++ b/test/src/test/java/hudson/ClassicPluginStrategyTest.java @@ -25,82 +25,67 @@ package hudson; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; import hudson.model.Hudson; import java.io.File; +import java.lang.reflect.Method; import java.net.URL; import java.util.Collection; import java.util.Enumeration; import java.util.LinkedHashSet; import java.util.Set; -import org.junit.Rule; -import org.junit.Test; -import org.junit.experimental.categories.Category; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.junit.runner.Description; +import org.junit.runners.model.Statement; import org.jvnet.hudson.test.Issue; import org.jvnet.hudson.test.JenkinsRecipe; import org.jvnet.hudson.test.JenkinsRule; -import org.jvnet.hudson.test.SmokeTest; +import org.jvnet.hudson.test.junit.jupiter.JenkinsSessionExtension; import org.jvnet.hudson.test.recipes.LocalData; /** * @author Alan Harder */ -@Category(SmokeTest.class) -public class ClassicPluginStrategyTest { +@Tag("SmokeTest") +class ClassicPluginStrategyTest { - @Rule - public JenkinsRule j = new JenkinsRule() { - @Override - protected Hudson newHudson() throws Exception { - File home = homeLoader.allocate(); - - for (JenkinsRecipe.Runner r : recipes) { - r.decorateHome(this, home); - } - LocalPluginManager pluginManager = new LocalPluginManager(home) { - @Override - protected Collection loadBundledPlugins() { - // Overriding so we can force loading of the detached plugins for testing - Set names = new LinkedHashSet<>(); - names.addAll(loadPluginsFromWar("/WEB-INF/plugins")); - names.addAll(loadPluginsFromWar("/WEB-INF/detached-plugins")); - return names; - } - }; - setPluginManager(pluginManager); - return new Hudson(home, createWebServer2(), pluginManager); - } - }; + @RegisterExtension + private final JenkinsSessionExtension session = new CustomPluginManagerExtension(); /** * Test finding resources via DependencyClassLoader. */ @LocalData @Test - public void testDependencyClassLoader() throws Exception { - // Test data has: foo3 depends on foo2,foo1; foo2 depends on foo1 - // (thus findResources from foo3 can find foo1 resources via 2 dependency paths) - PluginWrapper p = j.jenkins.getPluginManager().getPlugin("foo3"); - String res; + void testDependencyClassLoader() throws Throwable { + session.then(j -> { + // Test data has: foo3 depends on foo2,foo1; foo2 depends on foo1 + // (thus findResources from foo3 can find foo1 resources via 2 dependency paths) + PluginWrapper p = j.jenkins.getPluginManager().getPlugin("foo3"); + String res; - // In the current impl, the dependencies are the parent ClassLoader so resources - // are found there before checking the plugin itself. Adjust the expected results - // below if this is ever changed to check the plugin first. - Enumeration en = p.classLoader.getResources("test-resource"); - for (int i = 0; en.hasMoreElements(); i++) { - res = en.nextElement().toString(); - if (i < 2) - assertTrue("In current impl, " + res + "should be foo1 or foo2", - res.contains("/foo1/") || res.contains("/foo2/")); - else - assertTrue("In current impl, " + res + "should be foo3", res.contains("/foo3/")); - } - res = p.classLoader.getResource("test-resource").toString(); - assertTrue("In current impl, " + res + " should be foo1 or foo2", - res.contains("/foo1/") || res.contains("/foo2/")); + // In the current impl, the dependencies are the parent ClassLoader so resources + // are found there before checking the plugin itself. Adjust the expected results + // below if this is ever changed to check the plugin first. + Enumeration en = p.classLoader.getResources("test-resource"); + for (int i = 0; en.hasMoreElements(); i++) { + res = en.nextElement().toString(); + if (i < 2) + assertTrue(res.contains("/foo1/") || res.contains("/foo2/"), + "In current impl, " + res + "should be foo1 or foo2"); + else + assertTrue(res.contains("/foo3/"), "In current impl, " + res + "should be foo3"); + } + res = p.classLoader.getResource("test-resource").toString(); + assertTrue(res.contains("/foo1/") || res.contains("/foo2/"), + "In current impl, " + res + " should be foo1 or foo2"); + }); } /** @@ -110,17 +95,19 @@ public class ClassicPluginStrategyTest { @LocalData @Issue("JENKINS-18654") @Test - public void testDisabledDependencyClassLoader() throws Exception { - PluginWrapper p = j.jenkins.getPluginManager().getPlugin("foo4"); + void testDisabledDependencyClassLoader() throws Throwable { + session.then(j -> { + PluginWrapper p = j.jenkins.getPluginManager().getPlugin("foo4"); - Enumeration en = p.classLoader.getResources("test-resource"); - for (int i = 0; en.hasMoreElements(); i++) { - String res = en.nextElement().toString(); - if (i == 0) - assertTrue("expected foo4, found " + res, res.contains("/foo4/")); - else - fail("disabled dependency should not be included"); - } + Enumeration en = p.classLoader.getResources("test-resource"); + for (int i = 0; en.hasMoreElements(); i++) { + String res = en.nextElement().toString(); + if (i == 0) + assertTrue(res.contains("/foo4/"), "expected foo4, found " + res); + else + fail("disabled dependency should not be included"); + } + }); } /** @@ -130,12 +117,77 @@ public class ClassicPluginStrategyTest { @LocalData @Issue("JENKINS-27289") @Test - public void testMaskResourceClassLoader() throws Exception { - PluginWrapper pw = j.jenkins.getPluginManager().getPlugin("foo1"); - Class clazz = pw.classLoader.loadClass("org.apache.http.impl.io.SocketInputBuffer"); - ClassLoader cl = clazz.getClassLoader(); - URL url = cl.getResource("org/apache/http/impl/io/SocketInputBuffer.class"); - assertNotNull(url); - assertTrue("expected to find the class from foo1 plugin", url.toString().contains("plugins/foo1")); + void testMaskResourceClassLoader() throws Throwable { + session.then(j -> { + PluginWrapper pw = j.jenkins.getPluginManager().getPlugin("foo1"); + Class clazz = pw.classLoader.loadClass("org.apache.http.impl.io.SocketInputBuffer"); + ClassLoader cl = clazz.getClassLoader(); + URL url = cl.getResource("org/apache/http/impl/io/SocketInputBuffer.class"); + assertNotNull(url); + assertTrue(url.toString().contains("plugins/foo1"), "expected to find the class from foo1 plugin"); + }); + } + + private static final class CustomPluginManagerExtension extends JenkinsSessionExtension { + + private int port; + private Description description; + + @Override + public void beforeEach(ExtensionContext context) { + super.beforeEach(context); + description = Description.createTestDescription( + context.getTestClass().map(Class::getName).orElse(null), + context.getTestMethod().map(Method::getName).orElse(null), + context.getTestMethod().map(Method::getAnnotations).orElse(null)); + } + + @Override + public void then(Step s) throws Throwable { + CustomJenkinsRule r = new CustomJenkinsRule(getHome(), port); + r.apply( + new Statement() { + @Override + public void evaluate() throws Throwable { + port = r.getPort(); + s.run(r); + } + }, + description + ).evaluate(); + } + + private static final class CustomJenkinsRule extends JenkinsRule { + + CustomJenkinsRule(File home, int port) { + with(() -> home); + localPort = port; + } + + int getPort() { + return localPort; + } + + @Override + protected Hudson newHudson() throws Exception { + File home = homeLoader.allocate(); + + for (JenkinsRecipe.Runner r : recipes) { + r.decorateHome(this, home); + } + LocalPluginManager pluginManager = new LocalPluginManager(home) { + @Override + protected Collection loadBundledPlugins() { + // Overriding so we can force loading of the detached plugins for testing + Set names = new LinkedHashSet<>(); + names.addAll(loadPluginsFromWar("/WEB-INF/plugins")); + names.addAll(loadPluginsFromWar("/WEB-INF/detached-plugins")); + return names; + } + }; + setPluginManager(pluginManager); + return new Hudson(home, createWebServer2(), pluginManager); + } + } } } diff --git a/test/src/test/java/hudson/CustomPluginManagerTest.java b/test/src/test/java/hudson/CustomPluginManagerTest.java index 3ce9ae08eb..76334841e0 100644 --- a/test/src/test/java/hudson/CustomPluginManagerTest.java +++ b/test/src/test/java/hudson/CustomPluginManagerTest.java @@ -29,26 +29,29 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.not; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; import jakarta.servlet.ServletContext; import java.io.File; import java.lang.annotation.Retention; import java.lang.annotation.Target; import jenkins.model.Jenkins; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.jvnet.hudson.test.Issue; import org.jvnet.hudson.test.JenkinsRecipe; import org.jvnet.hudson.test.JenkinsRule; +import org.jvnet.hudson.test.junit.jupiter.JenkinsSessionExtension; import org.jvnet.hudson.test.recipes.WithPlugin; /** * Tests for the use of a custom plugin manager in custom wars. */ -public class CustomPluginManagerTest { - @Rule public final JenkinsRule r = new JenkinsRule(); +class CustomPluginManagerTest { + + @RegisterExtension + private final JenkinsSessionExtension session = new JenkinsSessionExtension(); // TODO: Move to jenkins-test-harness @JenkinsRecipe(WithCustomLocalPluginManager.RuleRunnerImpl.class) @@ -65,7 +68,6 @@ public class CustomPluginManagerTest { jenkinsRule.useLocalPluginManager = true; oldValue = System.getProperty(PluginManager.CUSTOM_PLUGIN_MANAGER); System.setProperty(PluginManager.CUSTOM_PLUGIN_MANAGER, recipe.value().getName()); - } @Override @@ -79,9 +81,11 @@ public class CustomPluginManagerTest { } } - private void check(Class klass) { - assertTrue("Correct plugin manager installed", klass.isAssignableFrom(r.getPluginManager().getClass())); - assertNotNull("Plugin 'htmlpublisher' installed", r.jenkins.getPlugin("htmlpublisher")); + private void check(Class klass) throws Throwable { + session.then(r -> { + assertTrue(klass.isAssignableFrom(r.getPluginManager().getClass()), "Correct plugin manager installed"); + assertNotNull(r.jenkins.getPlugin("htmlpublisher"), "Plugin 'htmlpublisher' installed"); + }); } // An interface not to override every constructor. @@ -91,11 +95,13 @@ public class CustomPluginManagerTest { @Issue("JENKINS-34681") @WithPlugin("htmlpublisher.jpi") @WithCustomLocalPluginManager(CustomPluginManager1.class) - @Test public void customPluginManager1() { + @Test + void customPluginManager1() throws Throwable { check(CustomPluginManager1.class); } public static class CustomPluginManager1 extends LocalPluginManager implements CustomPluginManager { + @SuppressWarnings("checkstyle:redundantmodifier") public CustomPluginManager1(Jenkins jenkins) { super(jenkins); } @@ -104,11 +110,13 @@ public class CustomPluginManagerTest { @Issue("JENKINS-34681") @WithPlugin("htmlpublisher.jpi") @WithCustomLocalPluginManager(CustomPluginManager2.class) - @Test public void customPluginManager2() { + @Test + void customPluginManager2() throws Throwable { check(CustomPluginManager2.class); } public static class CustomPluginManager2 extends LocalPluginManager implements CustomPluginManager { + @SuppressWarnings("checkstyle:redundantmodifier") public CustomPluginManager2(ServletContext ctx, File root) { super(ctx, root); } @@ -117,11 +125,13 @@ public class CustomPluginManagerTest { @Issue("JENKINS-34681") @WithPlugin("htmlpublisher.jpi") @WithCustomLocalPluginManager(CustomPluginManager3.class) - @Test public void customPluginManager3() { + @Test + void customPluginManager3() throws Throwable { check(CustomPluginManager3.class); } public static class CustomPluginManager3 extends LocalPluginManager implements CustomPluginManager { + @SuppressWarnings("checkstyle:redundantmodifier") public CustomPluginManager3(File root) { super(root); } @@ -130,11 +140,15 @@ public class CustomPluginManagerTest { @Issue("JENKINS-34681") @WithPlugin("htmlpublisher.jpi") @WithCustomLocalPluginManager(BadCustomPluginManager.class) - @Test public void badCustomPluginManager() { - assertThat("Custom plugin manager not installed", r.getPluginManager(), not(instanceOf(CustomPluginManager.class))); + @Test + void badCustomPluginManager() throws Throwable { + session.then(r -> + assertThat("Custom plugin manager not installed", r.getPluginManager(), not(instanceOf(CustomPluginManager.class))) + ); } public static class BadCustomPluginManager extends LocalPluginManager implements CustomPluginManager { + @SuppressWarnings("checkstyle:redundantmodifier") public BadCustomPluginManager(File root, ServletContext ctx) { super(ctx, root); } diff --git a/test/src/test/java/hudson/ExtensionListListenerTest.java b/test/src/test/java/hudson/ExtensionListListenerTest.java index 4e53c5d2a6..f4f449c670 100644 --- a/test/src/test/java/hudson/ExtensionListListenerTest.java +++ b/test/src/test/java/hudson/ExtensionListListenerTest.java @@ -24,37 +24,40 @@ package hudson; +import static org.junit.jupiter.api.Assertions.assertEquals; + import jenkins.model.TransientActionFactory; -import org.junit.Assert; -import org.junit.Rule; -import org.junit.Test; -import org.jvnet.hudson.test.JenkinsRule; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.jvnet.hudson.test.junit.jupiter.JenkinsSessionExtension; /** * @author tom.fennelly@gmail.com */ -public class ExtensionListListenerTest { +class ExtensionListListenerTest { - @Rule - public JenkinsRule r = PluginManagerUtil.newJenkinsRule(); + @RegisterExtension + public JenkinsSessionExtension session = PluginManagerUtil.newJenkinsSessionExtension(); @Test - public void test_onChange() throws Exception { - ExtensionList extensionList = ExtensionList.lookup(TransientActionFactory.class); + void test_onChange() throws Throwable { + session.then(r -> { + ExtensionList extensionList = ExtensionList.lookup(TransientActionFactory.class); - // force ExtensionList.ensureLoaded, otherwise the refresh will be ignored because - // the extension list will not be initialised. - extensionList.size(); + // force ExtensionList.ensureLoaded, otherwise the refresh will be ignored because + // the extension list will not be initialised. + extensionList.size(); - // Add the listener - MyExtensionListListener listListener = new MyExtensionListListener(); - extensionList.addListener(listListener); + // Add the listener + MyExtensionListListener listListener = new MyExtensionListListener(); + extensionList.addListener(listListener); - // magiext.hpi has a TransientActionFactory @Extension impl in it. The loading of that - // plugin should trigger onChange in the MyExtensionListListener instance. - PluginManagerUtil.dynamicLoad("magicext.hpi", r.jenkins); + // magiext.hpi has a TransientActionFactory @Extension impl in it. The loading of that + // plugin should trigger onChange in the MyExtensionListListener instance. + PluginManagerUtil.dynamicLoad("magicext.hpi", r.jenkins); - Assert.assertEquals(1, listListener.onChangeCallCount); + assertEquals(1, listListener.onChangeCallCount); + }); } private static class MyExtensionListListener extends ExtensionListListener { diff --git a/test/src/test/java/hudson/PluginManagerInstalledGUITest.java b/test/src/test/java/hudson/PluginManagerInstalledGUITest.java index 4927767185..1d93356f0a 100644 --- a/test/src/test/java/hudson/PluginManagerInstalledGUITest.java +++ b/test/src/test/java/hudson/PluginManagerInstalledGUITest.java @@ -24,7 +24,13 @@ package hudson; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; + +import java.io.File; import java.io.IOException; +import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -37,116 +43,99 @@ import org.htmlunit.html.HtmlElementUtil; import org.htmlunit.html.HtmlInput; import org.htmlunit.html.HtmlPage; import org.htmlunit.html.HtmlTableRow; -import org.junit.Assert; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.junit.runner.Description; +import org.junit.runners.model.Statement; import org.jvnet.hudson.test.Issue; import org.jvnet.hudson.test.JenkinsRule; import org.jvnet.hudson.test.TestPluginManager; +import org.jvnet.hudson.test.junit.jupiter.JenkinsSessionExtension; import org.xml.sax.SAXException; /** * @author tom.fennelly@gmail.com */ -public class PluginManagerInstalledGUITest { +class PluginManagerInstalledGUITest { - @Rule - public JenkinsRule jenkinsRule = new JenkinsRule() { - @Override - public PluginManager getPluginManager() { - try { - return new TestPluginManager() { - @Override - protected Collection loadBundledPlugins() throws Exception { - try { - return super.loadBundledPlugins(); - } finally { - copyBundledPlugin(PluginManagerInstalledGUITest.class.getResource("/WEB-INF/detached-plugins/matrix-auth.hpi"), "matrix-auth.jpi"); // cannot use installDetachedPlugin at this point - copyBundledPlugin(PluginManagerInstalledGUITest.class.getResource("/plugins/dependee-0.0.2.hpi"), "dependee.jpi"); - copyBundledPlugin(PluginManagerInstalledGUITest.class.getResource("/plugins/depender-0.0.2.hpi"), "depender.jpi"); - copyBundledPlugin(PluginManagerInstalledGUITest.class.getResource("/plugins/mandatory-depender-0.0.2.hpi"), "mandatory-depender.jpi"); - } - } - }; - } catch (IOException e) { - Assert.fail(e.getMessage()); - return null; - } - } - }; + @RegisterExtension + private final JenkinsSessionExtension session = new CustomPluginManagerExtension(); @Issue("JENKINS-33843") @Test - public void test_enable_disable_uninstall() throws IOException, SAXException { - InstalledPlugins installedPlugins = new InstalledPlugins(); + void test_enable_disable_uninstall() throws Throwable { + session.then(j -> { + InstalledPlugins installedPlugins = new InstalledPlugins(j); - InstalledPlugin matrixAuthPlugin = installedPlugins.get("matrix-auth"); - InstalledPlugin dependeePlugin = installedPlugins.get("dependee"); - InstalledPlugin dependerPlugin = installedPlugins.get("depender"); - InstalledPlugin mandatoryDependerPlugin = installedPlugins.get("mandatory-depender"); + InstalledPlugin matrixAuthPlugin = installedPlugins.get("matrix-auth"); + InstalledPlugin dependeePlugin = installedPlugins.get("dependee"); + InstalledPlugin dependerPlugin = installedPlugins.get("depender"); + InstalledPlugin mandatoryDependerPlugin = installedPlugins.get("mandatory-depender"); - // As a detached plugin, it is an optional dependency of others built against a newer baseline. - matrixAuthPlugin.assertHasNoDependents(); - // Has a mandatory dependency: - dependeePlugin.assertHasDependents(); - // Leaf plugins: - dependerPlugin.assertHasNoDependents(); - mandatoryDependerPlugin.assertHasNoDependents(); + // As a detached plugin, it is an optional dependency of others built against a newer baseline. + matrixAuthPlugin.assertHasNoDependents(); + // Has a mandatory dependency: + dependeePlugin.assertHasDependents(); + // Leaf plugins: + dependerPlugin.assertHasNoDependents(); + mandatoryDependerPlugin.assertHasNoDependents(); - // This plugin should be enabled and it should be possible to disable it - // because no other plugins depend on it. - mandatoryDependerPlugin.assertEnabled(); - mandatoryDependerPlugin.assertEnabledStateChangeable(); - mandatoryDependerPlugin.assertUninstallable(); + // This plugin should be enabled and it should be possible to disable it + // because no other plugins depend on it. + mandatoryDependerPlugin.assertEnabled(); + mandatoryDependerPlugin.assertEnabledStateChangeable(); + mandatoryDependerPlugin.assertUninstallable(); - // This plugin should be enabled, but it should not be possible to disable or uninstall it - // because another plugin depends on it. - dependeePlugin.assertEnabled(); - dependeePlugin.assertEnabledStateNotChangeable(); - dependeePlugin.assertNotUninstallable(); + // This plugin should be enabled, but it should not be possible to disable or uninstall it + // because another plugin depends on it. + dependeePlugin.assertEnabled(); + dependeePlugin.assertEnabledStateNotChangeable(); + dependeePlugin.assertNotUninstallable(); - // Disable one plugin - mandatoryDependerPlugin.clickEnabledWidget(); + // Disable one plugin + mandatoryDependerPlugin.clickEnabledWidget(); - // Now that plugin should be disabled, but it should be possible to re-enable it - // and it should still be uninstallable. - mandatoryDependerPlugin.assertNotEnabled(); // this is different to earlier - mandatoryDependerPlugin.assertEnabledStateChangeable(); - mandatoryDependerPlugin.assertUninstallable(); + // Now that plugin should be disabled, but it should be possible to re-enable it + // and it should still be uninstallable. + mandatoryDependerPlugin.assertNotEnabled(); // this is different to earlier + mandatoryDependerPlugin.assertEnabledStateChangeable(); + mandatoryDependerPlugin.assertUninstallable(); - // The dependee plugin should still be enabled, but it should now be possible to disable it because - // the mandatory depender plugin is no longer enabled. Should still not be possible to uninstall it. - // Note that the depender plugin does not block its disablement. - dependeePlugin.assertEnabled(); - dependeePlugin.assertEnabledStateChangeable(); // this is different to earlier - dependeePlugin.assertNotUninstallable(); - dependerPlugin.assertEnabled(); + // The dependee plugin should still be enabled, but it should now be possible to disable it because + // the mandatory depender plugin is no longer enabled. Should still not be possible to uninstall it. + // Note that the depender plugin does not block its disablement. + dependeePlugin.assertEnabled(); + dependeePlugin.assertEnabledStateChangeable(); // this is different to earlier + dependeePlugin.assertNotUninstallable(); + dependerPlugin.assertEnabled(); - // Disable the dependee plugin - dependeePlugin.clickEnabledWidget(); + // Disable the dependee plugin + dependeePlugin.clickEnabledWidget(); - // Now it should NOT be possible to change the enable state of the depender plugin because one - // of the plugins it depends on is not enabled. - mandatoryDependerPlugin.assertNotEnabled(); - mandatoryDependerPlugin.assertEnabledStateNotChangeable(); // this is different to earlier - mandatoryDependerPlugin.assertUninstallable(); - dependerPlugin.assertEnabled(); + // Now it should NOT be possible to change the enable state of the depender plugin because one + // of the plugins it depends on is not enabled. + mandatoryDependerPlugin.assertNotEnabled(); + mandatoryDependerPlugin.assertEnabledStateNotChangeable(); // this is different to earlier + mandatoryDependerPlugin.assertUninstallable(); + dependerPlugin.assertEnabled(); - // You can disable a detached plugin if there is no explicit dependency on it. - matrixAuthPlugin.assertEnabled(); - matrixAuthPlugin.assertEnabledStateChangeable(); - matrixAuthPlugin.assertUninstallable(); - matrixAuthPlugin.clickEnabledWidget(); - matrixAuthPlugin.assertNotEnabled(); - matrixAuthPlugin.assertEnabledStateChangeable(); - matrixAuthPlugin.assertUninstallable(); + // You can disable a detached plugin if there is no explicit dependency on it. + matrixAuthPlugin.assertEnabled(); + matrixAuthPlugin.assertEnabledStateChangeable(); + matrixAuthPlugin.assertUninstallable(); + matrixAuthPlugin.clickEnabledWidget(); + matrixAuthPlugin.assertNotEnabled(); + matrixAuthPlugin.assertEnabledStateChangeable(); + matrixAuthPlugin.assertUninstallable(); + }); } - private class InstalledPlugins { + private static class InstalledPlugins { private final List installedPlugins; - private InstalledPlugins() throws IOException, SAXException { + private InstalledPlugins(JenkinsRule jenkinsRule) throws IOException, SAXException { JenkinsRule.WebClient webClient = jenkinsRule.createWebClient(); HtmlPage installedPage = webClient.goTo("pluginManager/installed"); final boolean healthScoresAvailable = jenkinsRule.jenkins.getUpdateCenter().isHealthScoresAvailable(); @@ -170,13 +159,13 @@ public class PluginManagerInstalledGUITest { return plugin; } } - Assert.fail("No pluginManager/installed row for plugin " + pluginId); + fail("No pluginManager/installed row for plugin " + pluginId); return null; } } - private class InstalledPlugin { + private static class InstalledPlugin { private final HtmlTableRow pluginRow; private final boolean hasHealth; @@ -201,12 +190,12 @@ public class PluginManagerInstalledGUITest { public void assertEnabled() { HtmlInput enableWidget = getEnableWidget(); - Assert.assertTrue("Plugin '" + getId() + "' is expected to be enabled.", enableWidget.isChecked()); + assertTrue(enableWidget.isChecked(), "Plugin '" + getId() + "' is expected to be enabled."); } public void assertNotEnabled() { HtmlInput enableWidget = getEnableWidget(); - Assert.assertFalse("Plugin '" + getId() + "' is not expected to be enabled.", enableWidget.isChecked()); + assertFalse(enableWidget.isChecked(), "Plugin '" + getId() + "' is not expected to be enabled."); } public void clickEnabledWidget() throws IOException { @@ -222,7 +211,7 @@ public class PluginManagerInstalledGUITest { return; } - Assert.fail("The enable/disable state of plugin '" + getId() + "' cannot be changed."); + fail("The enable/disable state of plugin '" + getId() + "' cannot be changed."); } public void assertEnabledStateNotChangeable() { @@ -233,23 +222,23 @@ public class PluginManagerInstalledGUITest { return; } - Assert.fail("The enable/disable state of plugin '" + getId() + "' cannot be changed."); + fail("The enable/disable state of plugin '" + getId() + "' cannot be changed."); } public void assertUninstallable() { - Assert.assertFalse("Plugin '" + getId() + "' cannot be uninstalled.", hasDependents()); + assertFalse(hasDependents(), "Plugin '" + getId() + "' cannot be uninstalled."); } public void assertNotUninstallable() { - Assert.assertTrue("Plugin '" + getId() + "' can be uninstalled.", hasDependents()); + assertTrue(hasDependents(), "Plugin '" + getId() + "' can be uninstalled."); } public void assertHasDependents() { - Assert.assertTrue("Plugin '" + getId() + "' is expected to have dependents.", hasDependents()); + assertTrue(hasDependents(), "Plugin '" + getId() + "' is expected to have dependents."); } public void assertHasNoDependents() { - Assert.assertFalse("Plugin '" + getId() + "' is expected to have no dependents.", hasDependents()); + assertFalse(hasDependents(), "Plugin '" + getId() + "' is expected to have no dependents."); } private boolean hasClassName(String className) { @@ -270,4 +259,67 @@ public class PluginManagerInstalledGUITest { return hasClassName("has-dependents"); } } + + private static final class CustomPluginManagerExtension extends JenkinsSessionExtension { + + private int port; + private Description description; + + @Override + public void beforeEach(ExtensionContext context) { + super.beforeEach(context); + description = Description.createTestDescription( + context.getTestClass().map(Class::getName).orElse(null), + context.getTestMethod().map(Method::getName).orElse(null), + context.getTestMethod().map(Method::getAnnotations).orElse(null)); + } + + @Override + public void then(Step s) throws Throwable { + CustomJenkinsRule r = new CustomJenkinsRule(getHome(), port); + r.apply( + new Statement() { + @Override + public void evaluate() throws Throwable { + port = r.getPort(); + s.run(r); + } + }, + description + ).evaluate(); + } + + private static final class CustomJenkinsRule extends JenkinsRule { + + CustomJenkinsRule(File home, int port) { + with(() -> home); + localPort = port; + } + + int getPort() { + return localPort; + } + + @Override + public PluginManager getPluginManager() { + try { + return new TestPluginManager() { + @Override + protected Collection loadBundledPlugins() throws Exception { + try { + return super.loadBundledPlugins(); + } finally { + copyBundledPlugin(PluginManagerInstalledGUITest.class.getResource("/WEB-INF/detached-plugins/matrix-auth.hpi"), "matrix-auth.jpi"); // cannot use installDetachedPlugin at this point + copyBundledPlugin(PluginManagerInstalledGUITest.class.getResource("/plugins/dependee-0.0.2.hpi"), "dependee.jpi"); + copyBundledPlugin(PluginManagerInstalledGUITest.class.getResource("/plugins/depender-0.0.2.hpi"), "depender.jpi"); + copyBundledPlugin(PluginManagerInstalledGUITest.class.getResource("/plugins/mandatory-depender-0.0.2.hpi"), "mandatory-depender.jpi"); + } + } + }; + } catch (IOException e) { + return fail(e.getMessage()); + } + } + } + } } diff --git a/test/src/test/java/hudson/PluginManagerTest.java b/test/src/test/java/hudson/PluginManagerTest.java index d4bcc4e9bf..113e89915b 100644 --- a/test/src/test/java/hudson/PluginManagerTest.java +++ b/test/src/test/java/hudson/PluginManagerTest.java @@ -32,13 +32,14 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsInRelativeOrder; import static org.hamcrest.Matchers.empty; import static org.hamcrest.Matchers.not; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertThrows; -import static org.junit.Assert.assertTrue; -import static org.junit.Assume.assumeFalse; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assumptions.assumeFalse; import hudson.PluginManager.UberClassLoader; import hudson.model.DownloadService; @@ -83,7 +84,6 @@ import java.util.Optional; import java.util.Set; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; -import java.util.stream.Collectors; import jenkins.ClassLoaderReflectionToolkit; import jenkins.RestartRequiredException; import jenkins.model.Jenkins; @@ -95,16 +95,17 @@ import org.htmlunit.Page; import org.htmlunit.html.HtmlAnchor; import org.htmlunit.html.HtmlForm; import org.htmlunit.html.HtmlPage; -import org.junit.Assert; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TemporaryFolder; -import org.jvnet.hudson.test.FlagRule; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.junit.jupiter.api.io.TempDir; import org.jvnet.hudson.test.Issue; import org.jvnet.hudson.test.JenkinsRule; import org.jvnet.hudson.test.MockAuthorizationStrategy; import org.jvnet.hudson.test.TestExtension; import org.jvnet.hudson.test.Url; +import org.jvnet.hudson.test.junit.jupiter.JenkinsSessionExtension; import org.jvnet.hudson.test.recipes.WithPlugin; import org.jvnet.hudson.test.recipes.WithPluginManager; import org.kohsuke.stapler.StaplerRequest2; @@ -113,50 +114,71 @@ import org.kohsuke.stapler.StaplerResponse2; /** * @author Kohsuke Kawaguchi */ -public class PluginManagerTest { +class PluginManagerTest { - @Rule public JenkinsRule r = PluginManagerUtil.newJenkinsRule(); - @Rule public TemporaryFolder tmp = new TemporaryFolder(); - @Rule public FlagRule signatureCheck = new FlagRule<>(() -> DownloadService.signatureCheck, x -> DownloadService.signatureCheck = x); + @RegisterExtension + private final JenkinsSessionExtension session = PluginManagerUtil.newJenkinsSessionExtension(); + @TempDir + private File tmp; + private boolean signatureCheck; - /** - * Manual submission form. - */ - @Test public void uploadJpi() throws Exception { - HtmlPage page = r.createWebClient().goTo("pluginManager/advanced"); - HtmlForm f = page.getFormByName("uploadPlugin"); - File dir = tmp.newFolder(); - File plugin = new File(dir, "htmlpublisher.jpi"); - FileUtils.copyURLToFile(getClass().getClassLoader().getResource("plugins/htmlpublisher.jpi"), plugin); - f.getInputByName("name").setValue(plugin.getAbsolutePath()); - r.submit(f); + @BeforeEach + void setUp() { + signatureCheck = DownloadService.signatureCheck; + } - assertTrue(new File(r.jenkins.getRootDir(), "plugins/htmlpublisher.jpi").exists()); + @AfterEach + void tearDown() { + DownloadService.signatureCheck = signatureCheck; } /** * Manual submission form. */ - @Test public void uploadHpi() throws Exception { - HtmlPage page = r.createWebClient().goTo("pluginManager/advanced"); - HtmlForm f = page.getFormByName("uploadPlugin"); - File dir = tmp.newFolder(); - File plugin = new File(dir, "legacy.hpi"); - FileUtils.copyURLToFile(getClass().getClassLoader().getResource("plugins/legacy.hpi"), plugin); - f.getInputByName("name").setValue(plugin.getAbsolutePath()); - r.submit(f); + @Test + void uploadJpi() throws Throwable { + session.then(r -> { + HtmlPage page = r.createWebClient().goTo("pluginManager/advanced"); + HtmlForm f = page.getFormByName("uploadPlugin"); + File dir = newFolder(tmp, "junit"); + File plugin = new File(dir, "htmlpublisher.jpi"); + FileUtils.copyURLToFile(getClass().getClassLoader().getResource("plugins/htmlpublisher.jpi"), plugin); + f.getInputByName("name").setValue(plugin.getAbsolutePath()); + r.submit(f); - // uploaded legacy plugins get renamed to *.jpi - assertTrue(new File(r.jenkins.getRootDir(), "plugins/legacy.jpi").exists()); + assertTrue(new File(r.jenkins.getRootDir(), "plugins/htmlpublisher.jpi").exists()); + }); } - @Test public void deployJpiFromUrl() throws Exception { - HtmlPage page = r.createWebClient().goTo("pluginManager/advanced"); - HtmlForm f = page.getFormByName("uploadPlugin"); - f.getInputByName("pluginUrl").setValue(Jenkins.get().getRootUrl() + "pluginManagerGetPlugin/htmlpublisher.jpi"); - r.submit(f); + /** + * Manual submission form. + */ + @Test + void uploadHpi() throws Throwable { + session.then(r -> { + HtmlPage page = r.createWebClient().goTo("pluginManager/advanced"); + HtmlForm f = page.getFormByName("uploadPlugin"); + File dir = newFolder(tmp, "junit"); + File plugin = new File(dir, "legacy.hpi"); + FileUtils.copyURLToFile(getClass().getClassLoader().getResource("plugins/legacy.hpi"), plugin); + f.getInputByName("name").setValue(plugin.getAbsolutePath()); + r.submit(f); - assertTrue(new File(r.jenkins.getRootDir(), "plugins/htmlpublisher.jpi").exists()); + // uploaded legacy plugins get renamed to *.jpi + assertTrue(new File(r.jenkins.getRootDir(), "plugins/legacy.jpi").exists()); + }); + } + + @Test + void deployJpiFromUrl() throws Throwable { + session.then(r -> { + HtmlPage page = r.createWebClient().goTo("pluginManager/advanced"); + HtmlForm f = page.getFormByName("uploadPlugin"); + f.getInputByName("pluginUrl").setValue(Jenkins.get().getRootUrl() + "pluginManagerGetPlugin/htmlpublisher.jpi"); + r.submit(f); + + assertTrue(new File(r.jenkins.getRootDir(), "plugins/htmlpublisher.jpi").exists()); + }); } @TestExtension("deployJpiFromUrl") @@ -188,16 +210,18 @@ public class PluginManagerTest { * Tests the effect of {@link WithPlugin}. */ @WithPlugin("htmlpublisher.jpi") - @Test public void withRecipeJpi() { - assertNotNull(r.jenkins.getPlugin("htmlpublisher")); + @Test + void withRecipeJpi() throws Throwable { + session.then(r -> assertNotNull(r.jenkins.getPlugin("htmlpublisher"))); } /** * Tests the effect of {@link WithPlugin}. */ @WithPlugin("legacy.hpi") - @Test public void withRecipeHpi() { - assertNotNull(r.jenkins.getPlugin("legacy")); + @Test + void withRecipeHpi() throws Throwable { + session.then(r -> assertNotNull(r.jenkins.getPlugin("legacy"))); } /** @@ -208,13 +232,15 @@ public class PluginManagerTest { */ @WithPlugin("htmlpublisher.jpi") @WithPluginManager(PluginManagerImpl_for_testUberClassLoaderIsAvailableDuringStart.class) - @Test public void uberClassLoaderIsAvailableDuringStart() { - assertTrue(((PluginManagerImpl_for_testUberClassLoaderIsAvailableDuringStart) r.jenkins.pluginManager).tested); + @Test + void uberClassLoaderIsAvailableDuringStart() throws Throwable { + session.then(r -> assertTrue(((PluginManagerImpl_for_testUberClassLoaderIsAvailableDuringStart) r.jenkins.pluginManager).tested)); } public static class PluginManagerImpl_for_testUberClassLoaderIsAvailableDuringStart extends LocalPluginManager { boolean tested; + @SuppressWarnings("checkstyle:redundantmodifier") public PluginManagerImpl_for_testUberClassLoaderIsAvailableDuringStart(File rootDir) { super(rootDir); } @@ -243,53 +269,62 @@ public class PluginManagerTest { * infinite cycle ensues. */ @Url("http://jenkins.361315.n4.nabble.com/channel-example-and-plugin-classes-gives-ClassNotFoundException-td3756092.html") - @Test public void uberClassLoaderDoesntUseContextClassLoader() throws Exception { - Thread t = Thread.currentThread(); + @Test + void uberClassLoaderDoesntUseContextClassLoader() throws Throwable { + session.then(r -> { + Thread t = Thread.currentThread(); - URLClassLoader ucl = new URLClassLoader(new URL[0], r.jenkins.pluginManager.uberClassLoader); + URLClassLoader ucl = new URLClassLoader(new URL[0], r.jenkins.pluginManager.uberClassLoader); - ClassLoader old = t.getContextClassLoader(); - t.setContextClassLoader(ucl); - try { - assertThrows(ClassNotFoundException.class, () -> ucl.loadClass("No such class")); + ClassLoader old = t.getContextClassLoader(); + t.setContextClassLoader(ucl); + try { + assertThrows(ClassNotFoundException.class, () -> ucl.loadClass("No such class")); - ucl.loadClass(Hudson.class.getName()); - } finally { - t.setContextClassLoader(old); - } + ucl.loadClass(Hudson.class.getName()); + } finally { + t.setContextClassLoader(old); + } + }); } - @Test public void installWithoutRestart() throws Exception { - URL res = getClass().getClassLoader().getResource("plugins/htmlpublisher.jpi"); - File f = new File(r.jenkins.getRootDir(), "plugins/htmlpublisher.jpi"); - FileUtils.copyURLToFile(res, f); - r.jenkins.pluginManager.dynamicLoad(f); + @Test + void installWithoutRestart() throws Throwable { + session.then(r -> { + URL res = getClass().getClassLoader().getResource("plugins/htmlpublisher.jpi"); + File f = new File(r.jenkins.getRootDir(), "plugins/htmlpublisher.jpi"); + FileUtils.copyURLToFile(res, f); + r.jenkins.pluginManager.dynamicLoad(f); - Class c = r.jenkins.getPluginManager().uberClassLoader.loadClass("htmlpublisher.HtmlPublisher$DescriptorImpl"); - assertNotNull(r.jenkins.getDescriptorByType(c)); + Class c = r.jenkins.getPluginManager().uberClassLoader.loadClass("htmlpublisher.HtmlPublisher$DescriptorImpl"); + assertNotNull(r.jenkins.getDescriptorByType(c)); + }); } - @Test public void prevalidateConfig() throws Exception { - assumeFalse("TODO: Implement this test on Windows", Functions.isWindows()); - PersistedList sites = r.jenkins.getUpdateCenter().getSites(); - sites.clear(); - URL url = PluginManagerTest.class.getResource("/plugins/htmlpublisher-update-center.json"); - UpdateSite site = new UpdateSite(UpdateCenter.ID_DEFAULT, url.toString()); - sites.add(site); - assertEquals(FormValidation.ok(), site.updateDirectly(false).get()); - assertNotNull(site.getData()); - assertEquals(Collections.emptyList(), r.jenkins.getPluginManager().prevalidateConfig(new ByteArrayInputStream("".getBytes(StandardCharsets.UTF_8)))); - assertNull(r.jenkins.getPluginManager().getPlugin("htmlpublisher")); - List> jobs = r.jenkins.getPluginManager().prevalidateConfig(new ByteArrayInputStream("".getBytes(StandardCharsets.UTF_8))); - assertEquals(1, jobs.size()); - UpdateCenterJob job = jobs.get(0).get(); // blocks for completion - assertEquals("InstallationJob", job.getType()); - UpdateCenter.InstallationJob ijob = (UpdateCenter.InstallationJob) job; - assertEquals("htmlpublisher", ijob.plugin.name); - assertNotNull(r.jenkins.getPluginManager().getPlugin("htmlpublisher")); - // TODO restart scheduled (SuccessButRequiresRestart) after upgrade or Support-Dynamic-Loading: false - // TODO dependencies installed or upgraded too - // TODO required plugin installed but inactive + @Test + void prevalidateConfig() throws Throwable { + session.then(r -> { + assumeFalse(Functions.isWindows(), "TODO: Implement this test on Windows"); + PersistedList sites = r.jenkins.getUpdateCenter().getSites(); + sites.clear(); + URL url = PluginManagerTest.class.getResource("/plugins/htmlpublisher-update-center.json"); + UpdateSite site = new UpdateSite(UpdateCenter.ID_DEFAULT, url.toString()); + sites.add(site); + assertEquals(FormValidation.ok(), site.updateDirectly(false).get()); + assertNotNull(site.getData()); + assertEquals(Collections.emptyList(), r.jenkins.getPluginManager().prevalidateConfig(new ByteArrayInputStream("".getBytes(StandardCharsets.UTF_8)))); + assertNull(r.jenkins.getPluginManager().getPlugin("htmlpublisher")); + List> jobs = r.jenkins.getPluginManager().prevalidateConfig(new ByteArrayInputStream("".getBytes(StandardCharsets.UTF_8))); + assertEquals(1, jobs.size()); + UpdateCenterJob job = jobs.get(0).get(); // blocks for completion + assertEquals("InstallationJob", job.getType()); + UpdateCenter.InstallationJob ijob = (UpdateCenter.InstallationJob) job; + assertEquals("htmlpublisher", ijob.plugin.name); + assertNotNull(r.jenkins.getPluginManager().getPlugin("htmlpublisher")); + // TODO restart scheduled (SuccessButRequiresRestart) after upgrade or Support-Dynamic-Loading: false + // TODO dependencies installed or upgraded too + // TODO required plugin installed but inactive + }); } // plugin "depender" optionally depends on plugin "dependee". @@ -322,7 +357,7 @@ public class PluginManagerTest { /** * call org.jenkinsci.plugins.dependencytest.depender.Depender.getValue(). */ - private String callDependerValue() throws Exception { + private String callDependerValue(JenkinsRule r) throws Exception { Class c = r.jenkins.getPluginManager().uberClassLoader.loadClass("org.jenkinsci.plugins.dependencytest.depender.Depender"); Method m = c.getMethod("getValue"); return (String) m.invoke(null); @@ -332,28 +367,31 @@ public class PluginManagerTest { * Load "dependee" and then load "depender". * Asserts that "depender" can access to "dependee". */ - @Test public void installDependingPluginWithoutRestart() throws Exception { - // Load dependee. - { - dynamicLoad("dependee.hpi"); - } + @Test + void installDependingPluginWithoutRestart() throws Throwable { + session.then(r -> { + // Load dependee. + { + dynamicLoad(r, "dependee.hpi"); + } - // before load depender, of course failed to call Depender.getValue() - assertThrows(ClassNotFoundException.class, this::callDependerValue); + // before load depender, of course failed to call Depender.getValue() + assertThrows(ClassNotFoundException.class, () -> callDependerValue(r)); - // No extensions exist. - assertTrue(r.jenkins.getExtensionList("org.jenkinsci.plugins.dependencytest.dependee.DependeeExtensionPoint").isEmpty()); + // No extensions exist. + assertTrue(r.jenkins.getExtensionList("org.jenkinsci.plugins.dependencytest.dependee.DependeeExtensionPoint").isEmpty()); - // Load depender. - { - dynamicLoad("depender.hpi"); - } + // Load depender. + { + dynamicLoad(r, "depender.hpi"); + } - // depender successfully accesses to dependee. - assertEquals("dependee", callDependerValue()); + // depender successfully accesses to dependee. + assertEquals("dependee", callDependerValue(r)); - // Extension in depender is loaded. - assertFalse(r.jenkins.getExtensionList("org.jenkinsci.plugins.dependencytest.dependee.DependeeExtensionPoint").isEmpty()); + // Extension in depender is loaded. + assertFalse(r.jenkins.getExtensionList("org.jenkinsci.plugins.dependencytest.dependee.DependeeExtensionPoint").isEmpty()); + }); } /** @@ -361,457 +399,507 @@ public class PluginManagerTest { * Asserts that "depender" can access to "dependee". */ @Issue("JENKINS-19976") - @Test public void installDependedPluginWithoutRestart() throws Exception { - // Load depender. - { - dynamicLoad("depender.hpi"); - } + @Test + void installDependedPluginWithoutRestart() throws Throwable { + session.then(r -> { + // Load depender. + { + dynamicLoad(r, "depender.hpi"); + } - // before load dependee, depender does not access to dependee. - assertEquals("depender", callDependerValue()); + // before load dependee, depender does not access to dependee. + assertEquals("depender", callDependerValue(r)); - // before load dependee, of course failed to list extensions for dependee. - assertThrows(ClassNotFoundException.class, () -> r.jenkins.getExtensionList("org.jenkinsci.plugins.dependencytest.dependee.DependeeExtensionPoint")); - // Extension extending a dependee class can't be loaded either - assertThrows(NoClassDefFoundError.class, () -> r.jenkins.getExtensionList("org.jenkinsci.plugins.dependencytest.depender.DependerExtension")); + // before load dependee, of course failed to list extensions for dependee. + assertThrows(ClassNotFoundException.class, () -> r.jenkins.getExtensionList("org.jenkinsci.plugins.dependencytest.dependee.DependeeExtensionPoint")); + // Extension extending a dependee class can't be loaded either + assertThrows(NoClassDefFoundError.class, () -> r.jenkins.getExtensionList("org.jenkinsci.plugins.dependencytest.depender.DependerExtension")); - // Load dependee. - { - dynamicLoad("dependee.hpi"); - } + // Load dependee. + { + dynamicLoad(r, "dependee.hpi"); + } - // (MUST) Not throws an exception - // (SHOULD) depender successfully accesses to dependee. - assertEquals("dependee", callDependerValue()); + // (MUST) Not throws an exception + // (SHOULD) depender successfully accesses to dependee. + assertEquals("dependee", callDependerValue(r)); - // Extensions in depender are loaded. - assertEquals(1, r.jenkins.getExtensionList("org.jenkinsci.plugins.dependencytest.depender.DependerExtension").size()); + // Extensions in depender are loaded. + assertEquals(1, r.jenkins.getExtensionList("org.jenkinsci.plugins.dependencytest.depender.DependerExtension").size()); + }); } @Issue("JENKINS-21486") - @Test public void installPluginWithObsoleteDependencyFails() throws Exception { - // Load dependee 0.0.1. - { - dynamicLoad("dependee.hpi"); - } + @Test + void installPluginWithObsoleteDependencyFails() throws Throwable { + session.then(r -> { + // Load dependee 0.0.1. + { + dynamicLoad(r, "dependee.hpi"); + } - // Load mandatory-depender 0.0.2, depending on dependee 0.0.2 - assertThrows(IOException.class, () -> dynamicLoad("mandatory-depender-0.0.2.hpi")); + // Load mandatory-depender 0.0.2, depending on dependee 0.0.2 + assertThrows(IOException.class, () -> dynamicLoad(r, "mandatory-depender-0.0.2.hpi")); + }); } @Issue("JENKINS-21486") - @Test public void installPluginWithDisabledOptionalDependencySucceeds() throws Exception { - // Load dependee 0.0.2. - { - dynamicLoadAndDisable("dependee-0.0.2.hpi"); - } + @Test + void installPluginWithDisabledOptionalDependencySucceeds() throws Throwable { + session.then(r -> { + // Load dependee 0.0.2. + { + dynamicLoadAndDisable(r, "dependee-0.0.2.hpi"); + } - // Load depender 0.0.2, depending optionally on dependee 0.0.2 - { - dynamicLoad("depender-0.0.2.hpi"); - } + // Load depender 0.0.2, depending optionally on dependee 0.0.2 + { + dynamicLoad(r, "depender-0.0.2.hpi"); + } - // dependee is not loaded so we cannot list any extension for it. - assertThrows(ClassNotFoundException.class, () -> r.jenkins.getExtensionList("org.jenkinsci.plugins.dependencytest.dependee.DependeeExtensionPoint")); + // dependee is not loaded so we cannot list any extension for it. + assertThrows(ClassNotFoundException.class, () -> r.jenkins.getExtensionList("org.jenkinsci.plugins.dependencytest.dependee.DependeeExtensionPoint")); + }); } @Issue("JENKINS-21486") - @Test public void installPluginWithDisabledDependencyFails() throws Exception { - // Load dependee 0.0.2. - { - dynamicLoadAndDisable("dependee-0.0.2.hpi"); - } + @Test + void installPluginWithDisabledDependencyFails() throws Throwable { + session.then(r -> { + // Load dependee 0.0.2. + { + dynamicLoadAndDisable(r, "dependee-0.0.2.hpi"); + } - // Load mandatory-depender 0.0.2, depending on dependee 0.0.2 - assertThrows(IOException.class, () -> dynamicLoad("mandatory-depender-0.0.2.hpi")); + // Load mandatory-depender 0.0.2, depending on dependee 0.0.2 + assertThrows(IOException.class, () -> dynamicLoad(r, "mandatory-depender-0.0.2.hpi")); + }); } @Issue("JENKINS-68194") @WithPlugin("dependee.hpi") - @Test public void clearDisabledStatusAfterUninstall() throws Exception { - PluginWrapper pw = r.jenkins.pluginManager.getPlugin("dependee"); - assertNotNull(pw); + @Test + void clearDisabledStatusAfterUninstall() throws Throwable { + session.then(r -> { + PluginWrapper pw = r.jenkins.pluginManager.getPlugin("dependee"); + assertNotNull(pw); - pw.doMakeDisabled(); - pw.doDoUninstall(); + pw.doMakeDisabled(); + pw.doDoUninstall(); - File disabledHpi = new File(r.jenkins.getRootDir(), "plugins/dependee.hpi.disabled"); - assertFalse(disabledHpi.exists()); // `.disabled` file should be deleted after uninstall + File disabledHpi = new File(r.jenkins.getRootDir(), "plugins/dependee.hpi.disabled"); + assertFalse(disabledHpi.exists()); // `.disabled` file should be deleted after uninstall + }); } @Issue("JENKINS-21486") - @Test public void installPluginWithObsoleteOptionalDependencyFails() throws Exception { - // Load dependee 0.0.1. - { - dynamicLoad("dependee.hpi"); - } + @Test + void installPluginWithObsoleteOptionalDependencyFails() throws Throwable { + session.then(r -> { + // Load dependee 0.0.1. + { + dynamicLoad(r, "dependee.hpi"); + } - // Load depender 0.0.2, depending optionally on dependee 0.0.2 - assertThrows(IOException.class, () -> dynamicLoad("depender-0.0.2.hpi")); + // Load depender 0.0.2, depending optionally on dependee 0.0.2 + assertThrows(IOException.class, () -> dynamicLoad(r, "depender-0.0.2.hpi")); + }); } @Issue("JENKINS-12753") @WithPlugin("htmlpublisher.jpi") - @Test public void dynamicLoadRestartRequiredException() throws Exception { - File jpi = new File(r.jenkins.getRootDir(), "plugins/htmlpublisher.jpi"); - assertTrue(jpi.isFile()); - FileUtils.touch(jpi); - File timestamp = new File(r.jenkins.getRootDir(), "plugins/htmlpublisher/.timestamp2"); - assertTrue(timestamp.isFile()); - long lastMod = timestamp.lastModified(); - assertThrows(RestartRequiredException.class, () -> r.jenkins.getPluginManager().dynamicLoad(jpi)); - assertEquals("should not have tried to delete & unpack", lastMod, timestamp.lastModified()); + @Test + void dynamicLoadRestartRequiredException() throws Throwable { + session.then(r -> { + File jpi = new File(r.jenkins.getRootDir(), "plugins/htmlpublisher.jpi"); + assertTrue(jpi.isFile()); + FileUtils.touch(jpi); + File timestamp = new File(r.jenkins.getRootDir(), "plugins/htmlpublisher/.timestamp2"); + assertTrue(timestamp.isFile()); + long lastMod = timestamp.lastModified(); + assertThrows(RestartRequiredException.class, () -> r.jenkins.getPluginManager().dynamicLoad(jpi)); + assertEquals(lastMod, timestamp.lastModified(), "should not have tried to delete & unpack"); + }); } @WithPlugin("htmlpublisher.jpi") - @Test public void pluginListJSONApi() throws IOException { - JSONObject response = r.getJSON("pluginManager/plugins").getJSONObject(); + @Test + void pluginListJSONApi() throws Throwable { + session.then(r -> { + JSONObject response = r.getJSON("pluginManager/plugins").getJSONObject(); - // Check that the basic API endpoint invocation works. - assertEquals("ok", response.getString("status")); - JSONArray data = response.getJSONArray("data"); - assertThat(data, not(empty())); + // Check that the basic API endpoint invocation works. + assertEquals("ok", response.getString("status")); + JSONArray data = response.getJSONArray("data"); + assertThat(data, not(empty())); - // Check that there was some data in the response and that the first entry - // at least had some of the expected fields. - JSONObject pluginInfo = data.getJSONObject(0); - assertNotNull(pluginInfo.getString("name")); - assertNotNull(pluginInfo.getString("title")); - assertNotNull(pluginInfo.getString("dependencies")); + // Check that there was some data in the response and that the first entry + // at least had some of the expected fields. + JSONObject pluginInfo = data.getJSONObject(0); + assertNotNull(pluginInfo.getString("name")); + assertNotNull(pluginInfo.getString("title")); + assertNotNull(pluginInfo.getString("dependencies")); + }); } @Issue("JENKINS-41684") @Test - public void requireSystemDuringLoad() throws Exception { - r.jenkins.setSecurityRealm(r.createDummySecurityRealm()); - r.jenkins.setAuthorizationStrategy(new MockAuthorizationStrategy()); - try (ACLContext context = ACL.as2(User.getById("underprivileged", true).impersonate2())) { - dynamicLoad("require-system-during-load.hpi"); - } + void requireSystemDuringLoad() throws Throwable { + session.then(r -> { + r.jenkins.setSecurityRealm(r.createDummySecurityRealm()); + r.jenkins.setAuthorizationStrategy(new MockAuthorizationStrategy()); + try (ACLContext context = ACL.as2(User.getById("underprivileged", true).impersonate2())) { + dynamicLoad(r, "require-system-during-load.hpi"); + } + }); } - @Test @Issue("JENKINS-59775") - public void requireSystemDuringStart() throws Exception { - r.jenkins.setSecurityRealm(r.createDummySecurityRealm()); - r.jenkins.setAuthorizationStrategy(new MockAuthorizationStrategy()); - String pluginShortName = "require-system-during-load"; - dynamicLoad(pluginShortName + ".hpi"); - try (ACLContext context = ACL.as2(User.getById("underprivileged", true).impersonate2())) { - r.jenkins.pluginManager.start(List.of(r.jenkins.pluginManager.getPlugin(pluginShortName))); - } + void requireSystemDuringStart() throws Throwable { + session.then(r -> { + r.jenkins.setSecurityRealm(r.createDummySecurityRealm()); + r.jenkins.setAuthorizationStrategy(new MockAuthorizationStrategy()); + String pluginShortName = "require-system-during-load"; + dynamicLoad(r, pluginShortName + ".hpi"); + try (ACLContext context = ACL.as2(User.getById("underprivileged", true).impersonate2())) { + r.jenkins.pluginManager.start(List.of(r.jenkins.pluginManager.getPlugin(pluginShortName))); + } + }); } @Issue("JENKINS-61071") @Test - public void requireSystemInInitializer() throws Exception { - r.jenkins.setSecurityRealm(r.createDummySecurityRealm()); - r.jenkins.setAuthorizationStrategy(new MockAuthorizationStrategy()); - String pluginShortName = "require-system-in-initializer"; - dynamicLoad(pluginShortName + ".jpi"); - try (ACLContext context = ACL.as2(User.getById("underprivileged", true).impersonate2())) { - r.jenkins.pluginManager.start(List.of(r.jenkins.pluginManager.getPlugin(pluginShortName))); - } + void requireSystemInInitializer() throws Throwable { + session.then(r -> { + r.jenkins.setSecurityRealm(r.createDummySecurityRealm()); + r.jenkins.setAuthorizationStrategy(new MockAuthorizationStrategy()); + String pluginShortName = "require-system-in-initializer"; + dynamicLoad(r, pluginShortName + ".jpi"); + try (ACLContext context = ACL.as2(User.getById("underprivileged", true).impersonate2())) { + r.jenkins.pluginManager.start(List.of(r.jenkins.pluginManager.getPlugin(pluginShortName))); + } + }); } - private void dynamicLoad(String plugin) throws IOException, InterruptedException, RestartRequiredException { + private void dynamicLoad(JenkinsRule r, String plugin) throws IOException, InterruptedException, RestartRequiredException { PluginManagerUtil.dynamicLoad(plugin, r.jenkins); } - private void dynamicLoadAndDisable(String plugin) throws IOException, InterruptedException, RestartRequiredException { + private void dynamicLoadAndDisable(JenkinsRule r, String plugin) throws IOException, InterruptedException, RestartRequiredException { PluginManagerUtil.dynamicLoad(plugin, r.jenkins, true); } - @Test public void uploadDependencyResolution() throws Exception { - assumeFalse("TODO: Implement this test for Windows", Functions.isWindows()); - PersistedList sites = r.jenkins.getUpdateCenter().getSites(); - sites.clear(); - URL url = PluginManagerTest.class.getResource("/plugins/upload-test-update-center.json"); - UpdateSite site = new UpdateSite(UpdateCenter.ID_DEFAULT, url.toString()); - sites.add(site); + @Test + void uploadDependencyResolution() throws Throwable { + session.then(r -> { + assumeFalse(Functions.isWindows(), "TODO: Implement this test for Windows"); + PersistedList sites = r.jenkins.getUpdateCenter().getSites(); + sites.clear(); + URL url = PluginManagerTest.class.getResource("/plugins/upload-test-update-center.json"); + UpdateSite site = new UpdateSite(UpdateCenter.ID_DEFAULT, url.toString()); + sites.add(site); - assertEquals(FormValidation.ok(), site.updateDirectly(false).get()); - assertNotNull(site.getData()); + assertEquals(FormValidation.ok(), site.updateDirectly(false).get()); + assertNotNull(site.getData()); - // neither of the following plugins should be installed - assertNull(r.jenkins.getPluginManager().getPlugin("mandatory-depender")); - assertNull(r.jenkins.getPluginManager().getPlugin("dependee")); + // neither of the following plugins should be installed + assertNull(r.jenkins.getPluginManager().getPlugin("mandatory-depender")); + assertNull(r.jenkins.getPluginManager().getPlugin("dependee")); - HtmlPage page = r.createWebClient().goTo("pluginManager/advanced"); - HtmlForm f = page.getFormByName("uploadPlugin"); - File dir = tmp.newFolder(); - File plugin = new File(dir, "mandatory-depender-0.0.2.hpi"); - FileUtils.copyURLToFile(getClass().getClassLoader().getResource("plugins/mandatory-depender-0.0.2.hpi"), plugin); - f.getInputByName("name").setValue(plugin.getAbsolutePath()); - r.submit(f); + HtmlPage page = r.createWebClient().goTo("pluginManager/advanced"); + HtmlForm f = page.getFormByName("uploadPlugin"); + File dir = newFolder(tmp, "junit"); + File plugin = new File(dir, "mandatory-depender-0.0.2.hpi"); + FileUtils.copyURLToFile(getClass().getClassLoader().getResource("plugins/mandatory-depender-0.0.2.hpi"), plugin); + f.getInputByName("name").setValue(plugin.getAbsolutePath()); + r.submit(f); - assertThat(r.jenkins.getUpdateCenter().getJobs(), not(empty())); + assertThat(r.jenkins.getUpdateCenter().getJobs(), not(empty())); - // wait for all the download jobs to complete - boolean done = true; - boolean passed = true; - do { - Thread.sleep(100); - done = true; - for (UpdateCenterJob job : r.jenkins.getUpdateCenter().getJobs()) { - if (job instanceof UpdateCenter.DownloadJob j) { - assertFalse(j.status instanceof UpdateCenter.DownloadJob.Failure); - done &= !(j.status instanceof UpdateCenter.DownloadJob.Pending || - j.status instanceof UpdateCenter.DownloadJob.Installing); + // wait for all the download jobs to complete + boolean done = true; + boolean passed = true; + do { + Thread.sleep(100); + done = true; + for (UpdateCenterJob job : r.jenkins.getUpdateCenter().getJobs()) { + if (job instanceof UpdateCenter.DownloadJob j) { + assertFalse(j.status instanceof UpdateCenter.DownloadJob.Failure); + done &= !(j.status instanceof UpdateCenter.DownloadJob.Pending || + j.status instanceof UpdateCenter.DownloadJob.Installing); + } } - } - } while (!done); + } while (!done); - // the files get renamed to .jpi - assertTrue(new File(r.jenkins.getRootDir(), "plugins/mandatory-depender.jpi").exists()); - assertTrue(new File(r.jenkins.getRootDir(), "plugins/dependee.jpi").exists()); + // the files get renamed to .jpi + assertTrue(new File(r.jenkins.getRootDir(), "plugins/mandatory-depender.jpi").exists()); + assertTrue(new File(r.jenkins.getRootDir(), "plugins/dependee.jpi").exists()); - // now the other plugins should have been found as dependencies and downloaded - assertNotNull(r.jenkins.getPluginManager().getPlugin("mandatory-depender")); - assertNotNull(r.jenkins.getPluginManager().getPlugin("dependee")); + // now the other plugins should have been found as dependencies and downloaded + assertNotNull(r.jenkins.getPluginManager().getPlugin("mandatory-depender")); + assertNotNull(r.jenkins.getPluginManager().getPlugin("dependee")); + }); } @Issue("JENKINS-44898") @WithPlugin("plugin-first.hpi") @Test - public void findResourceForPluginFirstClassLoader() { - PluginWrapper w = r.jenkins.getPluginManager().getPlugin("plugin-first"); - assertNotNull(w); + void findResourceForPluginFirstClassLoader() throws Throwable { + session.then(r -> { + PluginWrapper w = r.jenkins.getPluginManager().getPlugin("plugin-first"); + assertNotNull(w); - URL fromPlugin = w.classLoader.getResource("org/jenkinsci/plugins/pluginfirst/HelloWorldBuilder/config.jelly"); - assertNotNull(fromPlugin); + URL fromPlugin = w.classLoader.getResource("org/jenkinsci/plugins/pluginfirst/HelloWorldBuilder/config.jelly"); + assertNotNull(fromPlugin); - // This is how UberClassLoader.findResource functions. - URL fromToolkit = ClassLoaderReflectionToolkit._findResource(w.classLoader, "org/jenkinsci/plugins/pluginfirst/HelloWorldBuilder/config.jelly"); + // This is how UberClassLoader.findResource functions. + URL fromToolkit = ClassLoaderReflectionToolkit._findResource(w.classLoader, "org/jenkinsci/plugins/pluginfirst/HelloWorldBuilder/config.jelly"); - assertEquals(fromPlugin, fromToolkit); + assertEquals(fromPlugin, fromToolkit); + }); } - @Test @Issue("JENKINS-64840") + @Test + @Issue("JENKINS-64840") @WithPlugin({"mandatory-depender-0.0.2.hpi", "dependee-0.0.2.hpi", "depender-0.0.2.hpi"}) - public void getPluginsSortedByTitle() throws Exception { - List installedPlugins = r.jenkins.getPluginManager().getPluginsSortedByTitle() - .stream() - .map(PluginWrapper::getDisplayName) - .collect(Collectors.toUnmodifiableList()); + void getPluginsSortedByTitle() throws Throwable { + session.then(r -> { + List installedPlugins = r.jenkins.getPluginManager().getPluginsSortedByTitle() + .stream() + .map(PluginWrapper::getDisplayName) + .toList(); - assertThat(installedPlugins, containsInRelativeOrder("dependee", "depender", "mandatory-depender")); + assertThat(installedPlugins, containsInRelativeOrder("dependee", "depender", "mandatory-depender")); + }); } @Issue("JENKINS-62622") @Test @WithPlugin("legacy.hpi") - public void doNotThrowWithUnknownPlugins() throws Exception { - final UpdateCenter uc = Jenkins.get().getUpdateCenter(); - Assert.assertNull("This test requires the plugin with ID 'legacy' to not exist in update sites", uc.getPlugin("legacy")); + void doNotThrowWithUnknownPlugins() throws Throwable { + session.then(r -> { + final UpdateCenter uc = Jenkins.get().getUpdateCenter(); + assertNull(uc.getPlugin("legacy"), "This test requires the plugin with ID 'legacy' to not exist in update sites"); - // ensure data is loaded - probably unnecessary, but closer to reality - Assert.assertSame(FormValidation.Kind.OK, uc.getSite("default").updateDirectlyNow().kind); + // ensure data is loaded - probably unnecessary, but closer to reality + assertSame(FormValidation.Kind.OK, uc.getSite("default").updateDirectlyNow().kind); + }); } - @Test @Issue("JENKINS-64840") - public void searchMultipleUpdateSites() throws Exception { - assumeFalse("TODO: Implement this test for Windows", Functions.isWindows()); - PersistedList sites = r.jenkins.getUpdateCenter().getSites(); - sites.clear(); - URL url = PluginManagerTest.class.getResource("/plugins/search-test-update-center1.json"); - UpdateSite site = new UpdateSite(UpdateCenter.ID_DEFAULT, url.toString()); - sites.add(site); - assertEquals(FormValidation.ok(), site.updateDirectly(false).get()); - assertNotNull(site.getData()); - url = PluginManagerTest.class.getResource("/plugins/search-test-update-center2.json"); - site = new UpdateSite("secondary", url.toString()); - sites.add(site); - final Future future = site.updateDirectly(false); - if (future != null) { - assertEquals(FormValidation.ok(), future.get()); - } - assertNotNull(site.getData()); + @Test + @Issue("JENKINS-64840") + void searchMultipleUpdateSites() throws Throwable { + session.then(r -> { + assumeFalse(Functions.isWindows(), "TODO: Implement this test for Windows"); + PersistedList sites = r.jenkins.getUpdateCenter().getSites(); + sites.clear(); + URL url = PluginManagerTest.class.getResource("/plugins/search-test-update-center1.json"); + UpdateSite site = new UpdateSite(UpdateCenter.ID_DEFAULT, url.toString()); + sites.add(site); + assertEquals(FormValidation.ok(), site.updateDirectly(false).get()); + assertNotNull(site.getData()); + url = PluginManagerTest.class.getResource("/plugins/search-test-update-center2.json"); + site = new UpdateSite("secondary", url.toString()); + sites.add(site); + final Future future = site.updateDirectly(false); + if (future != null) { + assertEquals(FormValidation.ok(), future.get()); + } + assertNotNull(site.getData()); - //Dummy plugin is found in the second site (should have worked before the fix) - JenkinsRule.JSONWebResponse response = r.getJSON("pluginManager/pluginsSearch?query=dummy&limit=5"); - JSONObject json = response.getJSONObject(); - assertTrue(json.has("data")); - JSONArray data = json.getJSONArray("data"); - assertEquals("Should be one search hit for dummy", 1, data.size()); + //Dummy plugin is found in the second site (should have worked before the fix) + JenkinsRule.JSONWebResponse response = r.getJSON("pluginManager/pluginsSearch?query=dummy&limit=5"); + JSONObject json = response.getJSONObject(); + assertTrue(json.has("data")); + JSONArray data = json.getJSONArray("data"); + assertEquals(1, data.size(), "Should be one search hit for dummy"); - //token-macro plugin is found in the first site (didn't work before the fix) - response = r.getJSON("pluginManager/pluginsSearch?query=token&limit=5"); - json = response.getJSONObject(); - assertTrue(json.has("data")); - data = json.getJSONArray("data"); - assertEquals("Should be one search hit for token", 1, data.size()); + //token-macro plugin is found in the first site (didn't work before the fix) + response = r.getJSON("pluginManager/pluginsSearch?query=token&limit=5"); + json = response.getJSONObject(); + assertTrue(json.has("data")); + data = json.getJSONArray("data"); + assertEquals(1, data.size(), "Should be one search hit for token"); - //hello-world plugin is found in the first site and hello-huston in the second (didn't work before the fix) - response = r.getJSON("pluginManager/pluginsSearch?query=hello&limit=5"); - json = response.getJSONObject(); - assertTrue(json.has("data")); - data = json.getJSONArray("data"); - assertEquals("Should be two search hits for hello", 2, data.size()); + //hello-world plugin is found in the first site and hello-huston in the second (didn't work before the fix) + response = r.getJSON("pluginManager/pluginsSearch?query=hello&limit=5"); + json = response.getJSONObject(); + assertTrue(json.has("data")); + data = json.getJSONArray("data"); + assertEquals(2, data.size(), "Should be two search hits for hello"); + }); } @Issue("JENKINS-70599") @Test - public void installNecessaryPluginsTest() throws Exception { - String jenkinsUrl = r.getURL().toString(); + void installNecessaryPluginsTest() throws Throwable { + session.then(r -> { + String jenkinsUrl = r.getURL().toString(); - // Define a cookie handler - CookieHandler.setDefault(new CookieManager()); - HttpCookie sessionCookie = new HttpCookie("session", "test-session-cookie"); - sessionCookie.setPath("/"); - sessionCookie.setVersion(0); - ((CookieManager) CookieHandler.getDefault()) - .getCookieStore() - .add(new URI(jenkinsUrl), sessionCookie); + // Define a cookie handler + CookieHandler.setDefault(new CookieManager()); + HttpCookie sessionCookie = new HttpCookie("session", "test-session-cookie"); + sessionCookie.setPath("/"); + sessionCookie.setVersion(0); + ((CookieManager) CookieHandler.getDefault()) + .getCookieStore() + .add(new URI(jenkinsUrl), sessionCookie); - // Initialize the cookie handler and get the crumb - URI crumbIssuer = new URI(jenkinsUrl + "crumbIssuer/api/json"); - HttpRequest httpGet = - HttpRequest.newBuilder() - .uri(crumbIssuer) - .header("Accept", "application/json") - .timeout(Duration.ofSeconds(7)) - .GET() - .build(); - HttpClient clientGet = - HttpClient.newBuilder() - .cookieHandler(CookieHandler.getDefault()) - .connectTimeout(Duration.ofSeconds(2)) - .build(); - HttpResponse responseGet = clientGet.send(httpGet, HttpResponse.BodyHandlers.ofString()); - assertEquals("Bad response for crumb issuer", 200, responseGet.statusCode()); - String body = responseGet.body(); - assertTrue("crumbRequestField not in response", body.contains("crumbRequestField")); - org.json.JSONObject jsonObject = new org.json.JSONObject(body); - String crumb = (String) jsonObject.get("crumb"); - String crumbRequestField = (String) jsonObject.get("crumbRequestField"); + // Initialize the cookie handler and get the crumb + URI crumbIssuer = new URI(jenkinsUrl + "crumbIssuer/api/json"); + HttpRequest httpGet = + HttpRequest.newBuilder() + .uri(crumbIssuer) + .header("Accept", "application/json") + .timeout(Duration.ofSeconds(7)) + .GET() + .build(); + HttpClient clientGet = + HttpClient.newBuilder() + .cookieHandler(CookieHandler.getDefault()) + .connectTimeout(Duration.ofSeconds(2)) + .build(); + HttpResponse responseGet = clientGet.send(httpGet, HttpResponse.BodyHandlers.ofString()); + assertEquals(200, responseGet.statusCode(), "Bad response for crumb issuer"); + String body = responseGet.body(); + assertTrue(body.contains("crumbRequestField"), "crumbRequestField not in response"); + org.json.JSONObject jsonObject = new org.json.JSONObject(body); + String crumb = (String) jsonObject.get("crumb"); + String crumbRequestField = (String) jsonObject.get("crumbRequestField"); - // Call installNecessaryPlugins XML API for git client plugin 4.0.0 with crumb - URI installNecessaryPlugins = new URI(jenkinsUrl + "pluginManager/installNecessaryPlugins"); - String xmlRequest = ""; - HttpRequest request = - HttpRequest.newBuilder() - .uri(installNecessaryPlugins) - .timeout(Duration.ofSeconds(20)) - .header("Content-Type", "application/xml") - .header(crumbRequestField, crumb) - .POST(HttpRequest.BodyPublishers.ofString(xmlRequest)) - .build(); - HttpClient client = - HttpClient.newBuilder() - .cookieHandler(CookieHandler.getDefault()) - .followRedirects(HttpClient.Redirect.ALWAYS) - .connectTimeout(Duration.ofSeconds(2)) - .build(); - HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); + // Call installNecessaryPlugins XML API for git client plugin 4.0.0 with crumb + URI installNecessaryPlugins = new URI(jenkinsUrl + "pluginManager/installNecessaryPlugins"); + String xmlRequest = ""; + HttpRequest request = + HttpRequest.newBuilder() + .uri(installNecessaryPlugins) + .timeout(Duration.ofSeconds(20)) + .header("Content-Type", "application/xml") + .header(crumbRequestField, crumb) + .POST(HttpRequest.BodyPublishers.ofString(xmlRequest)) + .build(); + HttpClient client = + HttpClient.newBuilder() + .cookieHandler(CookieHandler.getDefault()) + .followRedirects(HttpClient.Redirect.ALWAYS) + .connectTimeout(Duration.ofSeconds(2)) + .build(); + HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); - // Redirect reported 404 before bug was fixed - assertEquals("Bad response for installNecessaryPlugins", 200, response.statusCode()); + // Redirect reported 404 before bug was fixed + assertEquals(200, response.statusCode(), "Bad response for installNecessaryPlugins"); + }); } @Test @Issue("SECURITY-2823") - public void verifyUploadedPluginPermission() throws Exception { + void verifyUploadedPluginPermission() throws Throwable { assumeFalse(Functions.isWindows()); - HtmlPage page = r.createWebClient().goTo("pluginManager/advanced"); - HtmlForm f = page.getFormByName("uploadPlugin"); - File dir = tmp.newFolder(); - File plugin = new File(dir, "htmlpublisher.jpi"); - FileUtils.copyURLToFile(Objects.requireNonNull(getClass().getClassLoader().getResource("plugins/htmlpublisher.jpi")), plugin); - f.getInputByName("name").setValue(plugin.getAbsolutePath()); - r.submit(f); + session.then(r -> { + HtmlPage page = r.createWebClient().goTo("pluginManager/advanced"); + HtmlForm f = page.getFormByName("uploadPlugin"); + File dir = newFolder(tmp, "junit"); + File plugin = new File(dir, "htmlpublisher.jpi"); + FileUtils.copyURLToFile(Objects.requireNonNull(getClass().getClassLoader().getResource("plugins/htmlpublisher.jpi")), plugin); + f.getInputByName("name").setValue(plugin.getAbsolutePath()); + r.submit(f); - File filesRef = Files.createTempFile("tmp", ".tmp").toFile(); - File filesTmpDir = filesRef.getParentFile(); - filesRef.deleteOnExit(); + File filesRef = Files.createTempFile("tmp", ".tmp").toFile(); + File filesTmpDir = filesRef.getParentFile(); + filesRef.deleteOnExit(); - final Set[] filesPermission = new Set[]{new HashSet<>()}; - await().pollInterval(250, TimeUnit.MILLISECONDS) - .atMost(10, TimeUnit.SECONDS) - .until(() -> { - Optional lastUploadedPluginDir = Arrays.stream(Objects.requireNonNull( - filesTmpDir.listFiles((file, fileName) -> - fileName.startsWith("uploadDir")))). - max(Comparator.comparingLong(File::lastModified)); - if (lastUploadedPluginDir.isPresent()) { - filesPermission[0] = Files.getPosixFilePermissions(lastUploadedPluginDir.get().toPath(), LinkOption.NOFOLLOW_LINKS); - Optional pluginFile = Arrays.stream(Objects.requireNonNull( - lastUploadedPluginDir.get().listFiles((file, fileName) -> - fileName.startsWith("uploaded")))). + final Set[] filesPermission = new Set[]{new HashSet<>()}; + await().pollInterval(250, TimeUnit.MILLISECONDS) + .atMost(10, TimeUnit.SECONDS) + .until(() -> { + Optional lastUploadedPluginDir = Arrays.stream(Objects.requireNonNull( + filesTmpDir.listFiles((file, fileName) -> + fileName.startsWith("uploadDir")))). max(Comparator.comparingLong(File::lastModified)); - assertTrue(pluginFile.isPresent()); - return true; - } else { - return false; - } - }); - assertEquals(EnumSet.of(OWNER_EXECUTE, OWNER_READ, OWNER_WRITE), filesPermission[0]); + if (lastUploadedPluginDir.isPresent()) { + filesPermission[0] = Files.getPosixFilePermissions(lastUploadedPluginDir.get().toPath(), LinkOption.NOFOLLOW_LINKS); + Optional pluginFile = Arrays.stream(Objects.requireNonNull( + lastUploadedPluginDir.get().listFiles((file, fileName) -> + fileName.startsWith("uploaded")))). + max(Comparator.comparingLong(File::lastModified)); + assertTrue(pluginFile.isPresent()); + return true; + } else { + return false; + } + }); + assertEquals(EnumSet.of(OWNER_EXECUTE, OWNER_READ, OWNER_WRITE), filesPermission[0]); + }); } @Test @Issue("SECURITY-3037") - public void noInjectionOnAvailablePluginsPage() throws Exception { - DownloadService.signatureCheck = false; - Jenkins.get().getUpdateCenter().getSites().clear(); - UpdateSite us = new UpdateSite("Security3037", Jenkins.get().getRootUrl() + "security3037UpdateCenter/security3037-update-center.json"); - Jenkins.get().getUpdateCenter().getSites().add(us); + void noInjectionOnAvailablePluginsPage() throws Throwable { + session.then(r -> { + DownloadService.signatureCheck = false; + Jenkins.get().getUpdateCenter().getSites().clear(); + UpdateSite us = new UpdateSite("Security3037", Jenkins.get().getRootUrl() + "security3037UpdateCenter/security3037-update-center.json"); + Jenkins.get().getUpdateCenter().getSites().add(us); - try (JenkinsRule.WebClient wc = r.createWebClient()) { - HtmlPage p = wc.goTo("pluginManager"); + try (JenkinsRule.WebClient wc = r.createWebClient()) { + HtmlPage p = wc.goTo("pluginManager"); - AlertHandlerImpl alertHandler = new AlertHandlerImpl(); - wc.setAlertHandler(alertHandler); + AlertHandlerImpl alertHandler = new AlertHandlerImpl(); + wc.setAlertHandler(alertHandler); - PluginManagerUtil.getCheckForUpdatesButton(p).click(); - HtmlPage available = wc.goTo("pluginManager/available"); - assertTrue(available.querySelector(".jenkins-alert-danger") - .getTextContent().contains("This plugin is built for Jenkins 9999999")); - wc.waitForBackgroundJavaScript(100); + PluginManagerUtil.getCheckForUpdatesButton(p).click(); + HtmlPage available = wc.goTo("pluginManager/available"); + assertTrue(available.querySelector(".jenkins-alert-danger") + .getTextContent().contains("This plugin is built for Jenkins 9999999")); + wc.waitForBackgroundJavaScript(100); - HtmlAnchor anchor = available.querySelector(".jenkins-table__link"); - anchor.click(true, false, false); - wc.waitForBackgroundJavaScript(100); - assertTrue(alertHandler.messages.isEmpty()); - } + HtmlAnchor anchor = available.querySelector(".jenkins-table__link"); + anchor.click(true, false, false); + wc.waitForBackgroundJavaScript(100); + assertTrue(alertHandler.messages.isEmpty()); + } + }); } @Test @Issue("SECURITY-3072") - public void verifyUploadedPluginFromURLPermission() throws Exception { + void verifyUploadedPluginFromURLPermission() throws Throwable { assumeFalse(Functions.isWindows()); - HtmlPage page = r.createWebClient().goTo("pluginManager/advanced"); - HtmlForm f = page.getFormByName("uploadPlugin"); - f.getInputByName("pluginUrl").setValue(Jenkins.get().getRootUrl() + "pluginManagerGetPlugin/htmlpublisher.jpi"); - r.submit(f); + session.then(r -> { + HtmlPage page = r.createWebClient().goTo("pluginManager/advanced"); + HtmlForm f = page.getFormByName("uploadPlugin"); + f.getInputByName("pluginUrl").setValue(Jenkins.get().getRootUrl() + "pluginManagerGetPlugin/htmlpublisher.jpi"); + r.submit(f); - File filesRef = Files.createTempFile("tmp", ".tmp").toFile(); - File filesTmpDir = filesRef.getParentFile(); - filesRef.deleteOnExit(); + File filesRef = Files.createTempFile("tmp", ".tmp").toFile(); + File filesTmpDir = filesRef.getParentFile(); + filesRef.deleteOnExit(); - final Set[] filesPermission = new Set[]{new HashSet<>()}; - await().pollInterval(250, TimeUnit.MILLISECONDS) - .atMost(10, TimeUnit.SECONDS) - .until(() -> { - Optional lastUploadedPluginDir = Arrays.stream(Objects.requireNonNull( - filesTmpDir.listFiles((file, fileName) -> - fileName.startsWith("uploadDir")))). - max(Comparator.comparingLong(File::lastModified)); - if (lastUploadedPluginDir.isPresent()) { - filesPermission[0] = Files.getPosixFilePermissions(lastUploadedPluginDir.get().toPath(), LinkOption.NOFOLLOW_LINKS); - Optional pluginFile = Arrays.stream(Objects.requireNonNull( - lastUploadedPluginDir.get().listFiles((file, fileName) -> - fileName.startsWith("uploaded")))). + final Set[] filesPermission = new Set[]{new HashSet<>()}; + await().pollInterval(250, TimeUnit.MILLISECONDS) + .atMost(10, TimeUnit.SECONDS) + .until(() -> { + Optional lastUploadedPluginDir = Arrays.stream(Objects.requireNonNull( + filesTmpDir.listFiles((file, fileName) -> + fileName.startsWith("uploadDir")))). max(Comparator.comparingLong(File::lastModified)); - assertTrue(pluginFile.isPresent()); - return true; - } else { - return false; - } - }); - assertEquals(EnumSet.of(OWNER_EXECUTE, OWNER_READ, OWNER_WRITE), filesPermission[0]); + if (lastUploadedPluginDir.isPresent()) { + filesPermission[0] = Files.getPosixFilePermissions(lastUploadedPluginDir.get().toPath(), LinkOption.NOFOLLOW_LINKS); + Optional pluginFile = Arrays.stream(Objects.requireNonNull( + lastUploadedPluginDir.get().listFiles((file, fileName) -> + fileName.startsWith("uploaded")))). + max(Comparator.comparingLong(File::lastModified)); + assertTrue(pluginFile.isPresent()); + return true; + } else { + return false; + } + }); + assertEquals(EnumSet.of(OWNER_EXECUTE, OWNER_READ, OWNER_WRITE), filesPermission[0]); + }); } static class AlertHandlerImpl implements AlertHandler { @@ -873,4 +961,13 @@ public class PluginManagerTest { } } + private static File newFolder(File root, String... subDirs) throws IOException { + String subFolder = String.join("/", subDirs); + File result = new File(root, subFolder); + if (!result.mkdirs()) { + throw new IOException("Couldn't create folders " + root); + } + return result; + } + } diff --git a/test/src/test/java/hudson/PluginManagerUtil.java b/test/src/test/java/hudson/PluginManagerUtil.java index 584359d20d..8cd5aa96b1 100644 --- a/test/src/test/java/hudson/PluginManagerUtil.java +++ b/test/src/test/java/hudson/PluginManagerUtil.java @@ -26,36 +26,63 @@ package hudson; import java.io.File; import java.io.IOException; +import java.lang.reflect.Method; import java.net.URL; import jenkins.RestartRequiredException; import jenkins.model.Jenkins; import org.apache.commons.io.FileUtils; import org.htmlunit.html.DomElement; import org.htmlunit.html.HtmlPage; +import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.runner.Description; +import org.junit.runners.model.Statement; import org.jvnet.hudson.test.JenkinsRule; -import org.jvnet.hudson.test.RestartableJenkinsRule; +import org.jvnet.hudson.test.junit.jupiter.JenkinsSessionExtension; /** * @author tom.fennelly@gmail.com */ public class PluginManagerUtil { - public static JenkinsRule newJenkinsRule() { - return new JenkinsRule() { - @Override - public void before() throws Throwable { - setPluginManager(null); - super.before(); - } - }; - } + public static JenkinsSessionExtension newJenkinsSessionExtension() { + return new JenkinsSessionExtension() { + private int port; + private Description description; - public static RestartableJenkinsRule newRestartableJenkinsRule() { - return new RestartableJenkinsRule() { @Override - public JenkinsRule createJenkinsRule(Description description) { - return newJenkinsRule(); + public void beforeEach(ExtensionContext context) { + super.beforeEach(context); + description = Description.createTestDescription( + context.getTestClass().map(Class::getName).orElse(null), + context.getTestMethod().map(Method::getName).orElse(null), + context.getTestMethod().map(Method::getAnnotations).orElse(null)); + } + + @Override + public void then(Step s) throws Throwable { + CustomJenkinsRule r = new CustomJenkinsRule(getHome(), port); + r.apply( + new Statement() { + @Override + public void evaluate() throws Throwable { + port = r.getPort(); + s.run(r); + } + }, + description + ).evaluate(); + } + + private static final class CustomJenkinsRule extends JenkinsRule { + CustomJenkinsRule(File home, int port) { + setPluginManager(null); + with(() -> home); + localPort = port; + } + + int getPort() { + return localPort; + } } }; } diff --git a/test/src/test/java/hudson/cli/BuildCommandTest.java b/test/src/test/java/hudson/cli/BuildCommandTest.java index 3d43fb0909..83fb695e56 100644 --- a/test/src/test/java/hudson/cli/BuildCommandTest.java +++ b/test/src/test/java/hudson/cli/BuildCommandTest.java @@ -65,13 +65,12 @@ import java.nio.charset.Charset; import java.util.List; import java.util.concurrent.TimeUnit; import net.sf.json.JSONObject; -import org.junit.experimental.categories.Category; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.jvnet.hudson.test.CaptureEnvironmentBuilder; import org.jvnet.hudson.test.Issue; import org.jvnet.hudson.test.JenkinsRule; -import org.jvnet.hudson.test.SmokeTest; import org.jvnet.hudson.test.TestBuilder; import org.jvnet.hudson.test.TestExtension; import org.jvnet.hudson.test.junit.jupiter.WithJenkins; @@ -118,7 +117,7 @@ class BuildCommandTest { * Tests synchronous execution. */ @Test - @Category(SmokeTest.class) + @Tag("SmokeTest") void sync() throws Exception { FreeStyleProject p = j.createFreeStyleProject(); p.getBuildersList().add(Functions.isWindows() ? new BatchFile("ping 127.0.0.1") : new Shell("sleep 3")); diff --git a/test/src/test/java/hudson/model/ComputerTest.java b/test/src/test/java/hudson/model/ComputerTest.java index 332009d63e..5ec9bf47d5 100644 --- a/test/src/test/java/hudson/model/ComputerTest.java +++ b/test/src/test/java/hudson/model/ComputerTest.java @@ -63,8 +63,8 @@ import org.htmlunit.Page; import org.htmlunit.WebRequest; import org.htmlunit.html.HtmlForm; import org.htmlunit.xml.XmlPage; -import org.junit.experimental.categories.Category; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.jvnet.hudson.test.Issue; import org.jvnet.hudson.test.JenkinsRule; @@ -73,11 +73,10 @@ import org.jvnet.hudson.test.LogRecorder; import org.jvnet.hudson.test.MemoryAssert; import org.jvnet.hudson.test.MockAuthorizationStrategy; import org.jvnet.hudson.test.MockFolder; -import org.jvnet.hudson.test.SmokeTest; import org.jvnet.hudson.test.junit.jupiter.WithJenkins; import org.jvnet.hudson.test.recipes.LocalData; -@Category(SmokeTest.class) +@Tag("SmokeTest") @WithJenkins class ComputerTest { diff --git a/test/src/test/java/hudson/model/QueueCrashTest.java b/test/src/test/java/hudson/model/QueueCrashTest.java index 79a403647d..de52c7ce89 100644 --- a/test/src/test/java/hudson/model/QueueCrashTest.java +++ b/test/src/test/java/hudson/model/QueueCrashTest.java @@ -1,57 +1,66 @@ package hudson.model; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; import hudson.ExtensionList; import java.io.File; import java.io.IOException; import java.util.concurrent.TimeUnit; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.jvnet.hudson.test.JenkinsRule; -import org.jvnet.hudson.test.RestartableJenkinsRule; +import org.jvnet.hudson.test.junit.jupiter.WithJenkins; -public class QueueCrashTest { +@WithJenkins +class QueueCrashTest { + + private JenkinsRule j; + + @BeforeEach + void setUp(JenkinsRule rule) { + j = rule; + } - @Rule public RestartableJenkinsRule rr = new RestartableJenkinsRule(); @Test - public void persistQueueOnCrash() { - rr.thenWithHardShutdown(j -> { - // Speed up the test run by shortening the periodic save interval from 60 seconds to 5 - // seconds. - Queue.Saver.DELAY_SECONDS = 5; + void persistQueueOnCrash() throws Throwable { + // Speed up the test run by shortening the periodic save interval from 60 seconds to 5 + // seconds. + Queue.Saver.DELAY_SECONDS = 5; - scheduleSomeBuild(j); - assertBuildIsScheduled(j); + scheduleSomeBuild(j); + assertBuildIsScheduled(j); - // Wait for the periodic save to complete. - ExtensionList.lookupSingleton(Queue.Saver.class) - .getNextSave() - .get(30, TimeUnit.SECONDS); + // Wait for the periodic save to complete. + ExtensionList.lookupSingleton(Queue.Saver.class) + .getNextSave() + .get(30, TimeUnit.SECONDS); - // Ensure the periodic save process saved the queue, since the cleanup process will not - // run on a crash. - assertTrue(new File(j.jenkins.getRootDir(), "queue.xml").exists()); - }); - rr.then(QueueCrashTest::assertBuildIsScheduled); + // Ensure the periodic save process saved the queue, since the cleanup process will not + // run on a crash. + assertTrue(new File(j.jenkins.getRootDir(), "queue.xml").exists()); + + j.restart(); + + assertBuildIsScheduled(j); } @Test - public void doNotPersistQueueOnCrashBeforeSave() { - rr.thenWithHardShutdown(j -> { - // Avoid periodic save in order to simulate the scenario of a crash before initial save. - Queue.Saver.DELAY_SECONDS = (int) TimeUnit.DAYS.toSeconds(1); + void doNotPersistQueueOnCrashBeforeSave() throws Throwable { + // Avoid periodic save in order to simulate the scenario of a crash before initial save. + Queue.Saver.DELAY_SECONDS = (int) TimeUnit.DAYS.toSeconds(1); - scheduleSomeBuild(j); - assertBuildIsScheduled(j); + scheduleSomeBuild(j); + assertBuildIsScheduled(j); - // Ensure the queue has not been saved in order to test that a crash in this scenario - // results in the queue being lost. - assertFalse(new File(j.jenkins.getRootDir(), "queue.xml").exists()); - }); - rr.then(QueueCrashTest::assertBuildIsNotScheduled); + // Ensure the queue has not been saved in order to test that a crash in this scenario + // results in the queue being lost. + assertFalse(new File(j.jenkins.getRootDir(), "queue.xml").exists()); + + j.restart(); + + assertBuildIsNotScheduled(j); } private static void assertBuildIsScheduled(JenkinsRule j) { diff --git a/test/src/test/java/hudson/model/UpdateCenterCustomTest.java b/test/src/test/java/hudson/model/UpdateCenterCustomTest.java index 2a3a9296c1..f56a92cea3 100644 --- a/test/src/test/java/hudson/model/UpdateCenterCustomTest.java +++ b/test/src/test/java/hudson/model/UpdateCenterCustomTest.java @@ -29,62 +29,110 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.instanceOf; import jakarta.servlet.ServletContext; -import org.junit.Rule; -import org.junit.Test; +import java.io.File; +import java.lang.reflect.Method; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.junit.runner.Description; +import org.junit.runners.model.Statement; import org.jvnet.hudson.test.JenkinsRule; +import org.jvnet.hudson.test.junit.jupiter.JenkinsSessionExtension; /** * Tests of the custom {@link UpdateCenter} implementation. */ -public class UpdateCenterCustomTest { +class UpdateCenterCustomTest { - @Rule - public final JenkinsRule j = new CustomUpdateCenterRule(CustomUpdateCenter.class); + @RegisterExtension + private final JenkinsSessionExtension session = new CustomUpdateCenterExtension(CustomUpdateCenterExtension.CustomUpdateCenter.class); @Test - public void shouldStartupWithCustomUpdateCenter() { - UpdateCenter uc = j.jenkins.getUpdateCenter(); - assertThat("Update Center must be a custom instance", uc, instanceOf(CustomUpdateCenter.class)); + void shouldStartupWithCustomUpdateCenter() throws Throwable { + session.then(j -> { + UpdateCenter uc = j.jenkins.getUpdateCenter(); + assertThat("Update Center must be a custom instance", uc, instanceOf(CustomUpdateCenterExtension.CustomUpdateCenter.class)); + }); } // TODO: move to Jenkins Test Harness - private static final class CustomUpdateCenterRule extends JenkinsRule { + private static final class CustomUpdateCenterExtension extends JenkinsSessionExtension { + + private int port; + private Description description; private final String updateCenterClassName; - private String _oldValue = null; - private static final String PROPERTY_NAME = UpdateCenter.class.getName() + ".className"; - - CustomUpdateCenterRule(Class ucClass) { + CustomUpdateCenterExtension(Class ucClass) { this.updateCenterClassName = ucClass.getName(); } @Override - protected ServletContext createWebServer2() throws Exception { - _oldValue = System.getProperty(PROPERTY_NAME); - System.setProperty(PROPERTY_NAME, updateCenterClassName); - return super.createWebServer2(); + public void beforeEach(ExtensionContext context) { + super.beforeEach(context); + description = Description.createTestDescription( + context.getTestClass().map(Class::getName).orElse(null), + context.getTestMethod().map(Method::getName).orElse(null), + context.getTestMethod().map(Method::getAnnotations).orElse(null)); } @Override - public void after() { - if (_oldValue != null) { - System.setProperty(PROPERTY_NAME, _oldValue); + public void then(Step s) throws Throwable { + CustomJenkinsRule r = new CustomJenkinsRule(updateCenterClassName, getHome(), port); + r.apply( + new Statement() { + @Override + public void evaluate() throws Throwable { + port = r.getPort(); + s.run(r); + } + }, + description + ).evaluate(); + } + + private static final class CustomJenkinsRule extends JenkinsRule { + + private final String updateCenterClassName; + private String _oldValue = null; + + private static final String PROPERTY_NAME = UpdateCenter.class.getName() + ".className"; + + CustomJenkinsRule(final String updateCenterClassName, File home, int port) { + this.updateCenterClassName = updateCenterClassName; + with(() -> home); + localPort = port; + } + + int getPort() { + return localPort; + } + + @Override + protected ServletContext createWebServer2() throws Exception { + _oldValue = System.getProperty(PROPERTY_NAME); + System.setProperty(PROPERTY_NAME, updateCenterClassName); + return super.createWebServer2(); + } + + @Override + public void after() { + if (_oldValue != null) { + System.setProperty(PROPERTY_NAME, _oldValue); + } } } - public String getUpdateCenterClassName() { - return updateCenterClassName; + public static final class CustomUpdateCenter extends UpdateCenter { + + @SuppressWarnings("checkstyle:redundantmodifier") + public CustomUpdateCenter() { + } + + @SuppressWarnings("checkstyle:redundantmodifier") + public CustomUpdateCenter(UpdateCenterConfiguration config) { + super(config); + } + } } - - public static final class CustomUpdateCenter extends UpdateCenter { - - public CustomUpdateCenter() { - } - - public CustomUpdateCenter(UpdateCenterConfiguration config) { - super(config); - } - - } } diff --git a/test/src/test/java/hudson/model/UpdateCenterMigrationTest.java b/test/src/test/java/hudson/model/UpdateCenterMigrationTest.java index 6d002dbcad..ce4cb85c2c 100644 --- a/test/src/test/java/hudson/model/UpdateCenterMigrationTest.java +++ b/test/src/test/java/hudson/model/UpdateCenterMigrationTest.java @@ -1,35 +1,85 @@ package hudson.model; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; -import org.junit.Rule; -import org.junit.Test; +import java.io.File; +import java.lang.reflect.Method; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.junit.runner.Description; +import org.junit.runners.model.Statement; import org.jvnet.hudson.test.Issue; import org.jvnet.hudson.test.JenkinsRule; +import org.jvnet.hudson.test.junit.jupiter.JenkinsSessionExtension; import org.jvnet.hudson.test.recipes.LocalData; -public class UpdateCenterMigrationTest { +class UpdateCenterMigrationTest { - @Rule - public JenkinsRule j = new JenkinsRule() { - @Override - protected void configureUpdateCenter() { - // Avoid reverse proxy - DownloadService.neverUpdate = true; - UpdateSite.neverUpdate = true; - } - }; + @RegisterExtension + private final JenkinsSessionExtension session = new CustomUpdateCenterExtension(); @Issue("JENKINS-73760") @LocalData @Test - public void updateCenterMigration() { - UpdateSite site = j.jenkins.getUpdateCenter().getSites().stream() - .filter(s -> UpdateCenter.PREDEFINED_UPDATE_SITE_ID.equals(s.getId())) - .findFirst() - .orElseThrow(); - assertFalse(site.isLegacyDefault()); - assertEquals(j.jenkins.getUpdateCenter().getDefaultBaseUrl() + "update-center.json", site.getUrl()); + void updateCenterMigration() throws Throwable { + session.then(j -> { + UpdateSite site = j.jenkins.getUpdateCenter().getSites().stream() + .filter(s -> UpdateCenter.PREDEFINED_UPDATE_SITE_ID.equals(s.getId())) + .findFirst() + .orElseThrow(); + assertFalse(site.isLegacyDefault()); + assertEquals(j.jenkins.getUpdateCenter().getDefaultBaseUrl() + "update-center.json", site.getUrl()); + }); + } + + private static final class CustomUpdateCenterExtension extends JenkinsSessionExtension { + + private int port; + private Description description; + + @Override + public void beforeEach(ExtensionContext context) { + super.beforeEach(context); + description = Description.createTestDescription( + context.getTestClass().map(Class::getName).orElse(null), + context.getTestMethod().map(Method::getName).orElse(null), + context.getTestMethod().map(Method::getAnnotations).orElse(null)); + } + + @Override + public void then(Step s) throws Throwable { + CustomJenkinsRule r = new CustomJenkinsRule(getHome(), port); + r.apply( + new Statement() { + @Override + public void evaluate() throws Throwable { + port = r.getPort(); + s.run(r); + } + }, + description + ).evaluate(); + } + + private static final class CustomJenkinsRule extends JenkinsRule { + + CustomJenkinsRule(File home, int port) { + with(() -> home); + localPort = port; + } + + int getPort() { + return localPort; + } + + @Override + protected void configureUpdateCenter() { + // Avoid reverse proxy + DownloadService.neverUpdate = true; + UpdateSite.neverUpdate = true; + } + } } } diff --git a/test/src/test/java/hudson/util/BootFailureTest.java b/test/src/test/java/hudson/util/BootFailureTest.java index 6dced9655e..e1f946972e 100644 --- a/test/src/test/java/hudson/util/BootFailureTest.java +++ b/test/src/test/java/hudson/util/BootFailureTest.java @@ -1,9 +1,9 @@ package hudson.util; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; import hudson.WebAppMain; import hudson.model.Hudson; @@ -12,6 +12,7 @@ import jakarta.servlet.ServletContext; import jakarta.servlet.ServletContextEvent; import java.io.File; import java.io.IOException; +import java.lang.reflect.Method; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; @@ -20,16 +21,20 @@ import java.util.Arrays; import java.util.List; import jenkins.model.Jenkins; import jenkins.util.SystemProperties; -import org.junit.After; -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TemporaryFolder; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.junit.jupiter.api.io.TempDir; +import org.junit.runner.Description; +import org.junit.runners.model.Statement; import org.jvnet.hudson.test.Issue; import org.jvnet.hudson.test.JenkinsRule; import org.jvnet.hudson.test.TestEnvironment; import org.jvnet.hudson.test.TestExtension; +import org.jvnet.hudson.test.junit.jupiter.JenkinsSessionExtension; import org.kohsuke.stapler.WebApp; /** @@ -37,15 +42,23 @@ import org.kohsuke.stapler.WebApp; * * @author Kohsuke Kawaguchi */ -public class BootFailureTest { - @Rule - public TemporaryFolder tmpDir = new TemporaryFolder(); +class BootFailureTest { + + @TempDir + private File tmpDir; static boolean makeBootFail = true; static WebAppMain wa; private static String forceSessionTrackingByCookiePreviousValue; + // to be set by the script + private static Exception problem; + private static List runRecord = new ArrayList<>(); + + @RegisterExtension + private final JenkinsSessionExtension session = new CustomJenkinsSessionExtension(); + /* * TODO use RealJenkinsRule * @@ -54,14 +67,14 @@ public class BootFailureTest { * use RealJenkinsRule, this workaround should be deleted. */ - @BeforeClass - public static void disableSessionTrackingSetting() { + @BeforeAll + static void disableSessionTrackingSetting() { forceSessionTrackingByCookiePreviousValue = SystemProperties.getString(WebAppMain.FORCE_SESSION_TRACKING_BY_COOKIE_PROP); System.setProperty(WebAppMain.FORCE_SESSION_TRACKING_BY_COOKIE_PROP, "false"); } - @AfterClass - public static void resetSessionTrackingSetting() { + @AfterAll + static void resetSessionTrackingSetting() { if (forceSessionTrackingByCookiePreviousValue == null) { System.clearProperty(WebAppMain.FORCE_SESSION_TRACKING_BY_COOKIE_PROP); } else { @@ -69,44 +82,8 @@ public class BootFailureTest { } } - static class CustomRule extends JenkinsRule { - @Override - public void before() { - env = new TestEnvironment(testDescription); - env.pin(); - // don't let Jenkins start automatically - } - - @Override - public Hudson newHudson() throws Exception { - localPort = 0; - ServletContext ws = createWebServer2(); - wa = new WebAppMain() { - @Override - public WebAppMain.FileAndDescription getHomeDir(ServletContextEvent event) { - try { - return new WebAppMain.FileAndDescription(homeLoader.allocate(), "test"); - } catch (Exception x) { - throw new AssertionError(x); - } - } - }; - wa.contextInitialized(new ServletContextEvent(ws)); - wa.joinInit(); - - Object a = WebApp.get(ws).getApp(); - if (a instanceof Hudson) { - return (Hudson) a; - } - return null; // didn't boot - } - } - - @Rule - public CustomRule j = new CustomRule(); - - @After - public void tearDown() { + @AfterEach + void tearDown() { Jenkins j = Jenkins.getInstanceOrNull(); if (j != null) { j.cleanUp(); @@ -125,52 +102,56 @@ public class BootFailureTest { } @Test - public void runBootFailureScript() throws Exception { - final File home = tmpDir.newFolder(); - j.with(() -> home); + void runBootFailureScript() throws Throwable { + session.then(j -> { + final File home = newFolder(tmpDir, "junit"); + j.with(() -> home); - // creates a script - Files.writeString(home.toPath().resolve("boot-failure.groovy"), "hudson.util.BootFailureTest.problem = exception", StandardCharsets.UTF_8); - Path d = home.toPath().resolve("boot-failure.groovy.d"); - Files.createDirectory(d); - Files.writeString(d.resolve("1.groovy"), "hudson.util.BootFailureTest.runRecord << '1'", StandardCharsets.UTF_8); - Files.writeString(d.resolve("2.groovy"), "hudson.util.BootFailureTest.runRecord << '2'", StandardCharsets.UTF_8); + // creates a script + Files.writeString(home.toPath().resolve("boot-failure.groovy"), "hudson.util.BootFailureTest.problem = exception", StandardCharsets.UTF_8); + Path d = home.toPath().resolve("boot-failure.groovy.d"); + Files.createDirectory(d); + Files.writeString(d.resolve("1.groovy"), "hudson.util.BootFailureTest.runRecord << '1'", StandardCharsets.UTF_8); + Files.writeString(d.resolve("2.groovy"), "hudson.util.BootFailureTest.runRecord << '2'", StandardCharsets.UTF_8); - // first failed boot - makeBootFail = true; - assertNull(j.newHudson()); - assertEquals(1, bootFailures(home)); + // first failed boot + makeBootFail = true; + assertNull(((CustomJenkinsSessionExtension.CustomJenkinsRule) j).newHudson()); + assertEquals(1, bootFailures(home)); - // second failed boot - problem = null; - runRecord = new ArrayList<>(); - assertNull(j.newHudson()); - assertEquals(2, bootFailures(home)); - assertEquals(Arrays.asList("1", "2"), runRecord); + // second failed boot + problem = null; + runRecord = new ArrayList<>(); + assertNull(((CustomJenkinsSessionExtension.CustomJenkinsRule) j).newHudson()); + assertEquals(2, bootFailures(home)); + assertEquals(Arrays.asList("1", "2"), runRecord); - // make sure the script has actually run - assertEquals(SeriousError.class, problem.getCause().getClass()); + // make sure the script has actually run + assertEquals(SeriousError.class, problem.getCause().getClass()); - // if it boots well, the failure record should be gone - makeBootFail = false; - assertNotNull(j.newHudson()); - assertFalse(BootFailure.getBootFailureFile(home).exists()); + // if it boots well, the failure record should be gone + makeBootFail = false; + assertNotNull(((CustomJenkinsSessionExtension.CustomJenkinsRule) j).newHudson()); + assertFalse(BootFailure.getBootFailureFile(home).exists()); + }); } - private static int bootFailures(File home) throws IOException { + private static int bootFailures(File home) { return new BootFailure() { }.loadAttempts(home).size(); } @Issue("JENKINS-24696") @Test - public void interruptedStartup() throws Exception { - final File home = tmpDir.newFolder(); - j.with(() -> home); - Path d = home.toPath().resolve("boot-failure.groovy.d"); - Files.createDirectory(d); - Files.writeString(d.resolve("1.groovy"), "hudson.util.BootFailureTest.runRecord << '1'", StandardCharsets.UTF_8); - j.newHudson(); - assertEquals(List.of("1"), runRecord); + void interruptedStartup() throws Throwable { + session.then(j -> { + final File home = newFolder(tmpDir, "junit"); + j.with(() -> home); + Path d = home.toPath().resolve("boot-failure.groovy.d"); + Files.createDirectory(d); + Files.writeString(d.resolve("1.groovy"), "hudson.util.BootFailureTest.runRecord << '1'", StandardCharsets.UTF_8); + ((CustomJenkinsSessionExtension.CustomJenkinsRule) j).newHudson(); + assertEquals(List.of("1"), runRecord); + }); } @TestExtension("interruptedStartup") @@ -181,8 +162,85 @@ public class BootFailureTest { } } - // to be set by the script - public static Exception problem; - public static List runRecord = new ArrayList<>(); + private static File newFolder(File root, String... subDirs) throws IOException { + String subFolder = String.join("/", subDirs); + File result = new File(root, subFolder); + if (!result.mkdirs()) { + throw new IOException("Couldn't create folders " + root); + } + return result; + } + private static class CustomJenkinsSessionExtension extends JenkinsSessionExtension { + + private int port; + private Description description; + + @Override + public void beforeEach(ExtensionContext context) { + super.beforeEach(context); + description = Description.createTestDescription( + context.getTestClass().map(Class::getName).orElse(null), + context.getTestMethod().map(Method::getName).orElse(null), + context.getTestMethod().map(Method::getAnnotations).orElse(null)); + } + + @Override + public void then(Step s) throws Throwable { + CustomJenkinsRule r = new CustomJenkinsRule(getHome(), port); + r.apply( + new Statement() { + @Override + public void evaluate() throws Throwable { + port = r.getPort(); + s.run(r); + } + }, + description + ).evaluate(); + } + + private static final class CustomJenkinsRule extends JenkinsRule { + + CustomJenkinsRule(File home, int port) { + with(() -> home); + localPort = port; + } + + int getPort() { + return localPort; + } + + @Override + public void before() { + env = new TestEnvironment(testDescription); + env.pin(); + // don't let Jenkins start automatically + } + + @Override + public Hudson newHudson() throws Exception { + localPort = 0; + ServletContext ws = createWebServer2(); + wa = new WebAppMain() { + @Override + public WebAppMain.FileAndDescription getHomeDir(ServletContextEvent event) { + try { + return new WebAppMain.FileAndDescription(homeLoader.allocate(), "test"); + } catch (Exception x) { + throw new AssertionError(x); + } + } + }; + wa.contextInitialized(new ServletContextEvent(ws)); + wa.joinInit(); + + Object a = WebApp.get(ws).getApp(); + if (a instanceof Hudson) { + return (Hudson) a; + } + return null; // didn't boot + } + } + } } diff --git a/test/src/test/java/jenkins/bugs/Jenkins64991Test.java b/test/src/test/java/jenkins/bugs/Jenkins64991Test.java index 2a57b1ea6e..7ff2367362 100644 --- a/test/src/test/java/jenkins/bugs/Jenkins64991Test.java +++ b/test/src/test/java/jenkins/bugs/Jenkins64991Test.java @@ -27,54 +27,53 @@ package jenkins.bugs; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsStringIgnoringCase; import static org.hamcrest.Matchers.endsWithIgnoringCase; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; import hudson.model.FreeStyleProject; import hudson.security.Messages; import hudson.security.Permission; import java.io.IOException; -import java.util.Arrays; -import java.util.List; import jenkins.model.Jenkins; import org.htmlunit.Page; import org.htmlunit.html.HtmlFormUtil; import org.htmlunit.html.HtmlPage; import org.htmlunit.html.HtmlPasswordInput; import org.htmlunit.html.HtmlTextInput; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.Parameter; +import org.junit.jupiter.params.ParameterizedClass; +import org.junit.jupiter.params.provider.ValueSource; import org.jvnet.hudson.test.JenkinsRule; import org.jvnet.hudson.test.MockAuthorizationStrategy; +import org.jvnet.hudson.test.junit.jupiter.WithJenkins; import org.xml.sax.SAXException; -@RunWith(Parameterized.class) -public class Jenkins64991Test { - @Parameterized.Parameters - public static List contexts() { - return Arrays.asList("/jenkins", ""); - } +@ParameterizedClass +@ValueSource(strings = { "/jenkins", "" }) +@WithJenkins +class Jenkins64991Test { - public Jenkins64991Test(String context) { - j.contextPath = context; - } + @Parameter + private String contextPath; - @Rule - public JenkinsRule j = new JenkinsRule(); + private JenkinsRule j; - @Before - public void setUp() throws Exception { + @BeforeEach + void setUp(JenkinsRule rule) throws Throwable { + j = rule; j.jenkins.setSecurityRealm(j.createDummySecurityRealm()); j.jenkins.setAuthorizationStrategy(new MockAuthorizationStrategy().grant(Permission.READ).everywhere().toEveryone().grant(Jenkins.ADMINISTER).everywhere().to("alice")); j.createFreeStyleProject("foo bar"); + + j.contextPath = contextPath; + j.restart(); } @Test - public void test403Redirect() throws Exception { + void test403Redirect() throws Exception { final JenkinsRule.WebClient webClient = j.createWebClient().withThrowExceptionOnFailingStatusCode(false); final HtmlPage loginPage = webClient.goTo("manage"); @@ -90,9 +89,8 @@ public class Jenkins64991Test { assertThat(redirectedPage.getWebResponse().getContentAsString(), containsStringIgnoringCase(Messages.GlobalSecurityConfiguration_DisplayName())); } - @Test - public void testRedirect() throws Exception { + void testRedirect() throws Exception { final JenkinsRule.WebClient webClient = j.createWebClient(); final HtmlPage indexPage = webClient.goTo(""); @@ -114,7 +112,7 @@ public class Jenkins64991Test { } @Test - public void withoutFrom() throws Exception { + void withoutFrom() throws Exception { final JenkinsRule.WebClient webClient = j.createWebClient(); final HtmlPage loginPage = webClient.goTo("login"); @@ -129,7 +127,7 @@ public class Jenkins64991Test { } @Test - public void emptyFrom() throws Exception { + void emptyFrom() throws Exception { final JenkinsRule.WebClient webClient = j.createWebClient(); final HtmlPage loginPage = webClient.goTo("login?from="); @@ -144,7 +142,7 @@ public class Jenkins64991Test { } @Test - public void testRedirectToProject() throws Exception { + void testRedirectToProject() throws Exception { FreeStyleProject freeStyleProject = j.jenkins.getItemByFullName("foo bar", FreeStyleProject.class); assertNotNull(freeStyleProject); final JenkinsRule.WebClient webClient = j.createWebClient(); @@ -169,24 +167,24 @@ public class Jenkins64991Test { } @Test - public void absoluteRedirect() throws Exception { + void absoluteRedirect() throws Exception { assertNoOpenRedirect("login?from=https:%2F%2Fjenkins.io"); } @Test - public void protocolRelativeRedirect() throws Exception { + void protocolRelativeRedirect() throws Exception { String loginUrl = "login?from=%2F%2Fjenkins.io"; assertNoOpenRedirect(loginUrl); } @Test - public void hostRelativeRedirect() throws Exception { + void hostRelativeRedirect() throws Exception { String loginUrl = "login?from=%2Fjenkins.io"; assertNoOpenRedirect(loginUrl); } @Test - public void relativeRedirect() throws Exception { + void relativeRedirect() throws Exception { String loginUrl = "login?from=jenkins.io"; assertNoOpenRedirect(loginUrl); } diff --git a/test/src/test/java/jenkins/install/LoadDetachedPluginsTest.java b/test/src/test/java/jenkins/install/LoadDetachedPluginsTest.java index 29c2b7317c..c5e0075bfe 100644 --- a/test/src/test/java/jenkins/install/LoadDetachedPluginsTest.java +++ b/test/src/test/java/jenkins/install/LoadDetachedPluginsTest.java @@ -31,9 +31,9 @@ import static org.hamcrest.Matchers.greaterThan; import static org.hamcrest.Matchers.hasItem; import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.not; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; import hudson.ClassicPluginStrategy; import hudson.ExtensionList; @@ -41,7 +41,6 @@ import hudson.PluginManager; import hudson.PluginManagerUtil; import hudson.PluginWrapper; import hudson.util.VersionNumber; -import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.logging.Level; @@ -49,27 +48,28 @@ import java.util.stream.Collectors; import jenkins.plugins.DetachedPluginsUtil; import jenkins.plugins.DetachedPluginsUtil.DetachedPlugin; import jenkins.security.UpdateSiteWarningsMonitor; -import org.junit.Ignore; -import org.junit.Rule; -import org.junit.Test; -import org.junit.experimental.categories.Category; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import org.jvnet.hudson.test.Issue; import org.jvnet.hudson.test.JenkinsRule; -import org.jvnet.hudson.test.LoggerRule; -import org.jvnet.hudson.test.RestartableJenkinsRule; -import org.jvnet.hudson.test.SmokeTest; +import org.jvnet.hudson.test.LogRecorder; +import org.jvnet.hudson.test.junit.jupiter.JenkinsSessionExtension; import org.jvnet.hudson.test.recipes.LocalData; -@Category(SmokeTest.class) -public class LoadDetachedPluginsTest { +@Tag("SmokeTest") +class LoadDetachedPluginsTest { - @Rule public RestartableJenkinsRule rr = PluginManagerUtil.newRestartableJenkinsRule(); - @Rule public LoggerRule logging = new LoggerRule(); + @RegisterExtension + private final JenkinsSessionExtension rr = PluginManagerUtil.newJenkinsSessionExtension(); + + private final LogRecorder logging = new LogRecorder(); @Issue("JENKINS-48365") @Test @LocalData - public void upgradeFromJenkins1() throws IOException { + void upgradeFromJenkins1() throws Throwable { VersionNumber since = new VersionNumber("1.490"); rr.then(r -> { List detachedPlugins = DetachedPluginsUtil.getDetachedPlugins(since); @@ -82,9 +82,9 @@ public class LoadDetachedPluginsTest { } @Test - @Ignore("Only useful while updating bundled plugins, otherwise new security warnings fail unrelated builds") + @Disabled("Only useful while updating bundled plugins, otherwise new security warnings fail unrelated builds") @LocalData - public void noUpdateSiteWarnings() { + void noUpdateSiteWarnings() throws Throwable { rr.then(r -> { r.jenkins.getUpdateCenter().updateAllSites(); final UpdateSiteWarningsMonitor monitor = ExtensionList.lookupSingleton(UpdateSiteWarningsMonitor.class); @@ -95,7 +95,7 @@ public class LoadDetachedPluginsTest { @Issue("JENKINS-48365") @Test @LocalData - public void upgradeFromJenkins2() { + void upgradeFromJenkins2() throws Throwable { VersionNumber since = new VersionNumber("2.0"); rr.then(r -> { List detachedPlugins = DetachedPluginsUtil.getDetachedPlugins(since); @@ -108,7 +108,7 @@ public class LoadDetachedPluginsTest { } @Test - public void newInstallation() { + void newInstallation() throws Throwable { rr.then(r -> { List detachedPlugins = DetachedPluginsUtil.getDetachedPlugins(); assertThat("Detached plugins should exist", detachedPlugins, not(empty())); @@ -128,7 +128,7 @@ public class LoadDetachedPluginsTest { @Issue("JENKINS-55582") @LocalData @Test - public void installDetachedDependencies() { + void installDetachedDependencies() throws Throwable { logging.record(PluginManager.class, Level.FINE).record(ClassicPluginStrategy.class, Level.FINE); rr.then(r -> { List activePlugins = r.jenkins.getPluginManager().getPlugins().stream().filter(PluginWrapper::isActive).map(PluginWrapper::getShortName).collect(Collectors.toList()); @@ -145,14 +145,14 @@ public class LoadDetachedPluginsTest { private void assertLoader(Class c, String expectedPlugin, JenkinsRule r) { PluginWrapper pw = r.jenkins.pluginManager.whichPlugin(c); - assertNotNull("did not expect to be loading " + c + " from " + c.getClassLoader(), pw); + assertNotNull(pw, "did not expect to be loading " + c + " from " + c.getClassLoader()); assertEquals(expectedPlugin, pw.getShortName()); } @Issue("JENKINS-55582") @LocalData @Test - public void nonstandardFilenames() { + void nonstandardFilenames() throws Throwable { logging.record(PluginManager.class, Level.FINE).record(ClassicPluginStrategy.class, Level.FINE); rr.then(r -> { assertTrue(r.jenkins.pluginManager.getPlugin("build-token-root").isActive()); @@ -170,7 +170,7 @@ public class LoadDetachedPluginsTest { PluginWrapper wrapper = pluginManager.getPlugin(plugin.getShortName()); if (wrapper != null) { installedPlugins.add(wrapper); - assertTrue("Detached plugins should be active if installed", wrapper.isActive()); + assertTrue(wrapper.isActive(), "Detached plugins should be active if installed"); assertThat("Detached plugins should not have dependency errors", wrapper.getDependencyErrors(), empty()); } } diff --git a/test/src/test/java/jenkins/model/ErrorPageTest.java b/test/src/test/java/jenkins/model/ErrorPageTest.java index 939dd20c60..51a76827e3 100644 --- a/test/src/test/java/jenkins/model/ErrorPageTest.java +++ b/test/src/test/java/jenkins/model/ErrorPageTest.java @@ -3,46 +3,49 @@ package jenkins.model; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.not; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertThrows; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; import hudson.ExtensionList; import java.net.URL; import java.nio.charset.StandardCharsets; -import java.util.Arrays; -import java.util.List; import jenkins.security.ResourceDomainConfiguration; import org.htmlunit.FailingHttpStatusCodeException; import org.htmlunit.Page; import org.htmlunit.html.HtmlPage; -import org.junit.Assert; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.Parameter; +import org.junit.jupiter.params.ParameterizedClass; +import org.junit.jupiter.params.provider.ValueSource; import org.jvnet.hudson.test.Issue; import org.jvnet.hudson.test.JenkinsRule; import org.jvnet.hudson.test.MockAuthorizationStrategy; +import org.jvnet.hudson.test.junit.jupiter.WithJenkins; import org.kohsuke.stapler.Dispatcher; -@RunWith(Parameterized.class) -public class ErrorPageTest { +@ParameterizedClass +@ValueSource(strings = { "/jenkins", "" }) +@WithJenkins +class ErrorPageTest { - @Rule - public JenkinsRule j = new JenkinsRule(); + @Parameter + private String contextPath; - @Parameterized.Parameters - public static List contexts() { - return Arrays.asList("/jenkins", ""); - } + private JenkinsRule j; - public ErrorPageTest(String context) { - j.contextPath = context; + @BeforeEach + void setUp(JenkinsRule rule) throws Throwable { + j = rule; + + j.contextPath = contextPath; + j.restart(); } @Test @Issue("JENKINS-71087") - public void nice404ErrorPage() throws Exception { + void nice404ErrorPage() throws Exception { try (JenkinsRule.WebClient wc = j.createWebClient()) { Dispatcher.TRACE = false; @@ -151,11 +154,11 @@ public class ErrorPageTest { @Test @Issue("JENKINS-71087") - public void kindaNice404ErrorPageOnResourceDomain() throws Exception { + void kindaNice404ErrorPageOnResourceDomain() throws Exception { final String resourceRoot; { // Setup stolen from ResourceDomainTest URL root = j.getURL(); // which always will use "localhost", see JenkinsRule#getURL() - Assert.assertTrue(root.toString().contains("localhost")); // to be safe + assertTrue(root.toString().contains("localhost")); // to be safe resourceRoot = root.toString().replace("localhost", "127.0.0.1"); ResourceDomainConfiguration configuration = ExtensionList.lookupSingleton(ResourceDomainConfiguration.class); diff --git a/test/src/test/java/jenkins/model/JenkinsLocationConfigurationTest.java b/test/src/test/java/jenkins/model/JenkinsLocationConfigurationTest.java index 98d9fc2fad..df08cb4e0f 100644 --- a/test/src/test/java/jenkins/model/JenkinsLocationConfigurationTest.java +++ b/test/src/test/java/jenkins/model/JenkinsLocationConfigurationTest.java @@ -3,14 +3,16 @@ package jenkins.model; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.not; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; import hudson.model.FreeStyleProject; import hudson.model.Label; +import java.io.File; import java.io.IOException; +import java.lang.reflect.Method; import java.net.URL; import java.nio.charset.StandardCharsets; import java.nio.file.Files; @@ -22,74 +24,44 @@ import org.htmlunit.html.HtmlForm; import org.htmlunit.html.HtmlFormUtil; import org.htmlunit.html.HtmlInput; import org.htmlunit.html.HtmlPage; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.junit.runner.Description; +import org.junit.runners.model.Statement; import org.jvnet.hudson.test.Issue; import org.jvnet.hudson.test.JenkinsRule; +import org.jvnet.hudson.test.junit.jupiter.JenkinsSessionExtension; import org.jvnet.hudson.test.recipes.LocalData; /** * @author Kohsuke Kawaguchi */ -public class JenkinsLocationConfigurationTest { +class JenkinsLocationConfigurationTest { - private String lastRootUrlReturned; - private boolean lastRootUrlSet; + private static String lastRootUrlReturned; + private static boolean lastRootUrlSet; - @Rule - public JenkinsRule j = new JenkinsRule() { - @Override - public URL getURL() throws IOException { - // first call for the "Running on xxx" log message, Jenkins not being set at that point - // and the second call is to set the rootUrl of the JLC inside the JenkinsRule#init - if (Jenkins.getInstanceOrNull() != null) { - // only useful for doNotAcceptNonHttpBasedRootURL_fromConfigXml - lastRootUrlReturned = JenkinsLocationConfiguration.getOrDie().getUrl(); - lastRootUrlSet = true; - } - return super.getURL(); - } - }; + @RegisterExtension + public JenkinsSessionExtension session = new CustomJenkinsSessionExtension(); /** * Makes sure the use of "localhost" in the Hudson URL reports a warning. */ @Test - public void localhostWarning() throws Exception { - HtmlPage p = j.createWebClient().goTo("configure"); - HtmlInput url = p.getFormByName("config").getInputByName("_.url"); - url.setValue("http://localhost:1234/"); - assertThat(p.getDocumentElement().getTextContent(), containsString("instead of localhost")); + void localhostWarning() throws Throwable { + session.then(j -> { + HtmlPage p = j.createWebClient().goTo("configure"); + HtmlInput url = p.getFormByName("config").getInputByName("_.url"); + url.setValue("http://localhost:1234/"); + assertThat(p.getDocumentElement().getTextContent(), containsString("instead of localhost")); + }); } @Test @Issue("SECURITY-1471") - public void doNotAcceptNonHttpBasedRootURL_fromUI() throws Exception { - // in JenkinsRule, the URL is set to the current URL - JenkinsLocationConfiguration.getOrDie().setUrl(null); - - JenkinsRule.WebClient wc = j.createWebClient(); - - assertNull(JenkinsLocationConfiguration.getOrDie().getUrl()); - - settingRootURL("javascript:alert(123);//"); - - // no impact on the url in memory - assertNull(JenkinsLocationConfiguration.getOrDie().getUrl()); - - Path configFile = j.jenkins.getRootDir().toPath().resolve("jenkins.model.JenkinsLocationConfiguration.xml"); - String configFileContent = Files.readString(configFile, StandardCharsets.UTF_8); - assertThat(configFileContent, containsString("JenkinsLocationConfiguration")); - assertThat(configFileContent, not(containsString("javascript:alert(123);//"))); - } - - @Test - @Issue("SECURITY-1471") - public void escapeHatch_acceptNonHttpBasedRootURL_fromUI() throws Exception { - boolean previousValue = JenkinsLocationConfiguration.DISABLE_URL_VALIDATION; - JenkinsLocationConfiguration.DISABLE_URL_VALIDATION = true; - - try { + void doNotAcceptNonHttpBasedRootURL_fromUI() throws Throwable { + session.then(j -> { // in JenkinsRule, the URL is set to the current URL JenkinsLocationConfiguration.getOrDie().setUrl(null); @@ -97,100 +69,187 @@ public class JenkinsLocationConfigurationTest { assertNull(JenkinsLocationConfiguration.getOrDie().getUrl()); - String expectedUrl = "weirdSchema:somethingAlsoWeird"; - settingRootURL(expectedUrl); + settingRootURL(j, "javascript:alert(123);//"); - // the method ensures there is an trailing slash - assertEquals(expectedUrl + "/", JenkinsLocationConfiguration.getOrDie().getUrl()); + // no impact on the url in memory + assertNull(JenkinsLocationConfiguration.getOrDie().getUrl()); Path configFile = j.jenkins.getRootDir().toPath().resolve("jenkins.model.JenkinsLocationConfiguration.xml"); String configFileContent = Files.readString(configFile, StandardCharsets.UTF_8); assertThat(configFileContent, containsString("JenkinsLocationConfiguration")); - assertThat(configFileContent, containsString(expectedUrl)); - } - finally { - JenkinsLocationConfiguration.DISABLE_URL_VALIDATION = previousValue; - } + assertThat(configFileContent, not(containsString("javascript:alert(123);//"))); + }); + } + + @Test + @Issue("SECURITY-1471") + void escapeHatch_acceptNonHttpBasedRootURL_fromUI() throws Throwable { + session.then(j -> { + boolean previousValue = JenkinsLocationConfiguration.DISABLE_URL_VALIDATION; + JenkinsLocationConfiguration.DISABLE_URL_VALIDATION = true; + + try { + // in JenkinsRule, the URL is set to the current URL + JenkinsLocationConfiguration.getOrDie().setUrl(null); + + JenkinsRule.WebClient wc = j.createWebClient(); + + assertNull(JenkinsLocationConfiguration.getOrDie().getUrl()); + + String expectedUrl = "weirdSchema:somethingAlsoWeird"; + settingRootURL(j, expectedUrl); + + // the method ensures there is an trailing slash + assertEquals(expectedUrl + "/", JenkinsLocationConfiguration.getOrDie().getUrl()); + + Path configFile = j.jenkins.getRootDir().toPath().resolve("jenkins.model.JenkinsLocationConfiguration.xml"); + String configFileContent = Files.readString(configFile, StandardCharsets.UTF_8); + assertThat(configFileContent, containsString("JenkinsLocationConfiguration")); + assertThat(configFileContent, containsString(expectedUrl)); + } finally { + JenkinsLocationConfiguration.DISABLE_URL_VALIDATION = previousValue; + } + }); } @Test @Issue("SECURITY-1471") @LocalData("xssThroughConfigXml") - public void doNotAcceptNonHttpBasedRootURL_fromConfigXml() { - // in JenkinsRule, the URL is set to the current URL, even if coming from LocalData - // so we need to catch the last value before the getUrl from the JenkinsRule that will be used to set the rootUrl - assertNull(lastRootUrlReturned); - assertTrue(lastRootUrlSet); + void doNotAcceptNonHttpBasedRootURL_fromConfigXml() throws Throwable { + session.then(j -> { + // in JenkinsRule, the URL is set to the current URL, even if coming from LocalData + // so we need to catch the last value before the getUrl from the JenkinsRule that will be used to set the rootUrl + assertNull(lastRootUrlReturned); + assertTrue(lastRootUrlSet); - assertThat(JenkinsLocationConfiguration.getOrDie().getUrl(), not(containsString("javascript"))); + assertThat(JenkinsLocationConfiguration.getOrDie().getUrl(), not(containsString("javascript"))); + }); } @Test @Issue("SECURITY-1471") - public void cannotInjectJavaScriptUsingRootUrl_inNewViewLink() throws Exception { - JenkinsRule.WebClient wc = j.createWebClient(); - j.createFreeStyleProject(); + void cannotInjectJavaScriptUsingRootUrl_inNewViewLink() throws Throwable { + session.then(j -> { + JenkinsRule.WebClient wc = j.createWebClient(); + j.createFreeStyleProject(); - settingRootURL("javascript:alert(123);//"); + settingRootURL(j, "javascript:alert(123);//"); - // setup the victim - AtomicReference alertAppeared = new AtomicReference<>(false); - wc.setAlertHandler((page, s) -> alertAppeared.set(true)); - HtmlPage page = wc.goTo(""); + // setup the victim + AtomicReference alertAppeared = new AtomicReference<>(false); + wc.setAlertHandler((page, s) -> alertAppeared.set(true)); + HtmlPage page = wc.goTo(""); - HtmlAnchor newViewLink = page.getDocumentElement().getElementsByTagName("a").stream() - .filter(HtmlAnchor.class::isInstance).map(HtmlAnchor.class::cast) - .filter(a -> a.getHrefAttribute().endsWith("newView")) - .findFirst().orElseThrow(AssertionError::new); + HtmlAnchor newViewLink = page.getDocumentElement().getElementsByTagName("a").stream() + .filter(HtmlAnchor.class::isInstance).map(HtmlAnchor.class::cast) + .filter(a -> a.getHrefAttribute().endsWith("newView")) + .findFirst().orElseThrow(AssertionError::new); - // last verification - assertFalse(alertAppeared.get()); + // last verification + assertFalse(alertAppeared.get()); - HtmlElementUtil.click(newViewLink); + HtmlElementUtil.click(newViewLink); - assertFalse(alertAppeared.get()); + assertFalse(alertAppeared.get()); + }); } @Test @Issue("SECURITY-1471") - public void cannotInjectJavaScriptUsingRootUrl_inLabelAbsoluteLink() throws Exception { - String builtInLabel = "builtin-node"; - j.jenkins.setLabelString(builtInLabel); + void cannotInjectJavaScriptUsingRootUrl_inLabelAbsoluteLink() throws Throwable { + session.then(j -> { + String builtInLabel = "builtin-node"; + j.jenkins.setLabelString(builtInLabel); - JenkinsRule.WebClient wc = j.createWebClient(); + JenkinsRule.WebClient wc = j.createWebClient(); - settingRootURL("javascript:alert(123);//"); + settingRootURL(j, "javascript:alert(123);//"); - // setup the victim - AtomicReference alertAppeared = new AtomicReference<>(false); - wc.setAlertHandler((page, s) -> alertAppeared.set(true)); + // setup the victim + AtomicReference alertAppeared = new AtomicReference<>(false); + wc.setAlertHandler((page, s) -> alertAppeared.set(true)); - FreeStyleProject p = j.createFreeStyleProject(); - p.setAssignedLabel(Label.get(builtInLabel)); + FreeStyleProject p = j.createFreeStyleProject(); + p.setAssignedLabel(Label.get(builtInLabel)); - HtmlPage projectConfigurePage = wc.getPage(p, "/configure"); + HtmlPage projectConfigurePage = wc.getPage(p, "/configure"); - HtmlAnchor labelAnchor = projectConfigurePage.getDocumentElement().getElementsByTagName("a").stream() - .filter(HtmlAnchor.class::isInstance).map(HtmlAnchor.class::cast) - .filter(a -> a.getHrefAttribute().contains("/label/")) - .findFirst().orElseThrow(AssertionError::new); + HtmlAnchor labelAnchor = projectConfigurePage.getDocumentElement().getElementsByTagName("a").stream() + .filter(HtmlAnchor.class::isInstance).map(HtmlAnchor.class::cast) + .filter(a -> a.getHrefAttribute().contains("/label/")) + .findFirst().orElseThrow(AssertionError::new); - assertFalse(alertAppeared.get()); - HtmlElementUtil.click(labelAnchor); - assertFalse(alertAppeared.get()); + assertFalse(alertAppeared.get()); + HtmlElementUtil.click(labelAnchor); + assertFalse(alertAppeared.get()); - String labelHref = labelAnchor.getHrefAttribute(); - assertThat(labelHref, not(containsString("javascript:alert(123)"))); + String labelHref = labelAnchor.getHrefAttribute(); + assertThat(labelHref, not(containsString("javascript:alert(123)"))); - String responseContent = projectConfigurePage.getWebResponse().getContentAsString(); - assertThat(responseContent, not(containsString("javascript:alert(123)"))); + String responseContent = projectConfigurePage.getWebResponse().getContentAsString(); + assertThat(responseContent, not(containsString("javascript:alert(123)"))); + }); } - private void settingRootURL(String desiredRootUrl) throws Exception { + private void settingRootURL(JenkinsRule j, String desiredRootUrl) throws Exception { HtmlPage configurePage = j.createWebClient().goTo("configure"); HtmlForm configForm = configurePage.getFormByName("config"); HtmlInput url = configForm.getInputByName("_.url"); url.setValue(desiredRootUrl); HtmlFormUtil.submit(configForm); } + + private static final class CustomJenkinsSessionExtension extends JenkinsSessionExtension { + + private int port; + private Description description; + + @Override + public void beforeEach(ExtensionContext context) { + super.beforeEach(context); + description = Description.createTestDescription( + context.getTestClass().map(Class::getName).orElse(null), + context.getTestMethod().map(Method::getName).orElse(null), + context.getTestMethod().map(Method::getAnnotations).orElse(null)); + } + + @Override + public void then(Step s) throws Throwable { + CustomJenkinsRule r = new CustomJenkinsRule(getHome(), port); + r.apply( + new Statement() { + @Override + public void evaluate() throws Throwable { + port = r.getPort(); + s.run(r); + } + }, + description + ).evaluate(); + } + + private static final class CustomJenkinsRule extends JenkinsRule { + + CustomJenkinsRule(File home, int port) { + with(() -> home); + localPort = port; + } + + int getPort() { + return localPort; + } + + @Override + public URL getURL() throws IOException { + // first call for the "Running on xxx" log message, Jenkins not being set at that point + // and the second call is to set the rootUrl of the JLC inside the JenkinsRule#init + if (Jenkins.getInstanceOrNull() != null) { + // only useful for doNotAcceptNonHttpBasedRootURL_fromConfigXml + lastRootUrlReturned = JenkinsLocationConfiguration.getOrDie().getUrl(); + lastRootUrlSet = true; + } + return super.getURL(); + } + } + } } diff --git a/test/src/test/java/jenkins/security/Security3501Test.java b/test/src/test/java/jenkins/security/Security3501Test.java index 2128ad3074..080cb40ecc 100644 --- a/test/src/test/java/jenkins/security/Security3501Test.java +++ b/test/src/test/java/jenkins/security/Security3501Test.java @@ -2,47 +2,46 @@ package jenkins.security; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; +import static org.junit.jupiter.api.Assertions.assertThrows; import java.util.List; import jenkins.security.security3501Test.Security3501RootAction; import org.htmlunit.FailingHttpStatusCodeException; -import org.junit.Assert; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.junit.jupiter.params.Parameter; +import org.junit.jupiter.params.ParameterizedClass; +import org.junit.jupiter.params.provider.ValueSource; import org.jvnet.hudson.test.JenkinsRule; -import org.jvnet.hudson.test.RealJenkinsRule; +import org.jvnet.hudson.test.junit.jupiter.RealJenkinsExtension; -@RunWith(Parameterized.class) -public class Security3501Test { - // Workaround for https://github.com/jenkinsci/jenkins-test-harness/issues/933 - private final String contextPath; +@ParameterizedClass +@ValueSource(strings = { "/jenkins", "" }) +class Security3501Test { - @Rule - public RealJenkinsRule jj = new RealJenkinsRule().addSyntheticPlugin(new RealJenkinsRule.SyntheticPlugin(Security3501RootAction.class.getPackage()).shortName("Security3501RootAction")); + @Parameter + private String contextPath; - @Parameterized.Parameters - public static List contexts() { - return List.of("/jenkins", ""); - } + @RegisterExtension + private final RealJenkinsExtension jj = new RealJenkinsExtension().addSyntheticPlugin(new RealJenkinsExtension.SyntheticPlugin(Security3501RootAction.class.getPackage()).shortName("Security3501RootAction")); - public Security3501Test(String contextPath) { + @BeforeEach + void setUp() { jj.withPrefix(contextPath); - this.contextPath = contextPath; } @Test - public void testRedirects() throws Throwable { + void testRedirects() throws Throwable { jj.then(new TestRedirectsStep(contextPath)); } - private record TestRedirectsStep(String context) implements RealJenkinsRule.Step { + private record TestRedirectsStep(String context) implements RealJenkinsExtension.Step { public void run(JenkinsRule j) throws Exception { List prohibitedPaths = List.of("%5C%5Cexample.org", "%5C/example.org", "/%5Cexample.org", "//example.org", "https://example.org", "\\example.org"); for (String path : prohibitedPaths) { try (JenkinsRule.WebClient wc = j.createWebClient().withRedirectEnabled(false)) { - final FailingHttpStatusCodeException fhsce = Assert.assertThrows(FailingHttpStatusCodeException.class, () -> wc.goTo("redirects/content?path=" + path)); + final FailingHttpStatusCodeException fhsce = assertThrows(FailingHttpStatusCodeException.class, () -> wc.goTo("redirects/content?path=" + path)); assertThat(fhsce.getStatusCode(), is(404)); } } @@ -50,7 +49,7 @@ public class Security3501Test { List allowedPaths = List.of("foo", "foo/bar"); for (String path : allowedPaths) { try (JenkinsRule.WebClient wc = j.createWebClient().withRedirectEnabled(false)) { - final FailingHttpStatusCodeException fhsce = Assert.assertThrows(FailingHttpStatusCodeException.class, () -> wc.goTo("redirects/content?path=" + path)); + final FailingHttpStatusCodeException fhsce = assertThrows(FailingHttpStatusCodeException.class, () -> wc.goTo("redirects/content?path=" + path)); assertThat(fhsce.getStatusCode(), is(302)); assertThat(fhsce.getResponse().getResponseHeaderValue("Location"), is(context + "/redirects/" + path)); } diff --git a/test/src/test/java/jenkins/security/SecurityContextExecutorServiceTest.java b/test/src/test/java/jenkins/security/SecurityContextExecutorServiceTest.java index ac9df83a2f..feaa2a7762 100644 --- a/test/src/test/java/jenkins/security/SecurityContextExecutorServiceTest.java +++ b/test/src/test/java/jenkins/security/SecurityContextExecutorServiceTest.java @@ -24,8 +24,8 @@ package jenkins.security; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; import hudson.model.User; import hudson.security.ACL; @@ -35,51 +35,57 @@ import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; import java.util.concurrent.ScheduledThreadPoolExecutor; -import org.junit.Rule; -import org.junit.Test; +import jenkins.model.Jenkins; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.jvnet.hudson.test.JenkinsRule; -import org.jvnet.hudson.test.recipes.PresetData; +import org.jvnet.hudson.test.MockAuthorizationStrategy; +import org.jvnet.hudson.test.junit.jupiter.WithJenkins; import org.springframework.security.core.context.SecurityContext; import org.springframework.security.core.context.SecurityContextHolder; /** * @author Patrick McKeown */ -public class SecurityContextExecutorServiceTest { +@WithJenkins +class SecurityContextExecutorServiceTest { - private final int NUM_THREADS = 10; + private static final int NUM_THREADS = 10; private ExecutorService wrappedService = null; private SecurityContext systemContext = null; private SecurityContext userContext = null; private SecurityContext nullContext = null; - private volatile SecurityContext runnableThreadContext; - @Rule - public JenkinsRule j = new JenkinsRule() { - @Override - public void before() throws Throwable { - setPluginManager(null); - super.before(); + private SecurityContext runnableThreadContext; - ScheduledThreadPoolExecutor service = new ScheduledThreadPoolExecutor(NUM_THREADS); - // Create a system level context with ACL.SYSTEM2 - systemContext = ACL.impersonate2(ACL.SYSTEM2); + private JenkinsRule j; - User u = User.get("bob"); - // Create a sample user context - userContext = new NonSerializableSecurityContext(u.impersonate2()); + @BeforeEach + void setUp(JenkinsRule rule) { + j = rule; - // Create a null context - SecurityContextHolder.clearContext(); - nullContext = SecurityContextHolder.getContext(); + JenkinsRule.DummySecurityRealm realm = j.createDummySecurityRealm(); + j.jenkins.setSecurityRealm(realm); + j.jenkins.setAuthorizationStrategy(new MockAuthorizationStrategy() + .grant(Jenkins.ADMINISTER).everywhere().toAuthenticated()); - // Create a wrapped service - wrappedService = new SecurityContextExecutorService(service); - } - }; + ScheduledThreadPoolExecutor service = new ScheduledThreadPoolExecutor(NUM_THREADS); + // Create a system level context with ACL.SYSTEM2 + systemContext = ACL.impersonate2(ACL.SYSTEM2); + + User u = User.get("bob"); + // Create a sample user context + userContext = new NonSerializableSecurityContext(u.impersonate2()); + + // Create a null context + SecurityContextHolder.clearContext(); + nullContext = SecurityContextHolder.getContext(); + + // Create a wrapped service + wrappedService = new SecurityContextExecutorService(service); + } @Test - @PresetData(PresetData.DataSet.NO_ANONYMOUS_READACCESS) - public void testRunnableAgainstAllContexts() throws Exception { + void testRunnableAgainstAllContexts() throws Exception { Runnable r = () -> runnableThreadContext = SecurityContextHolder.getContext(); SecurityContextHolder.setContext(systemContext); Future systemResult = wrappedService.submit(r); @@ -104,8 +110,7 @@ public class SecurityContextExecutorServiceTest { } @Test - @PresetData(PresetData.DataSet.NO_ANONYMOUS_READACCESS) - public void testCallableAgainstAllContexts() throws Exception { + void testCallableAgainstAllContexts() throws Exception { Callable c = SecurityContextHolder::getContext; SecurityContextHolder.setContext(systemContext); Future result = wrappedService.submit(c); @@ -124,8 +129,7 @@ public class SecurityContextExecutorServiceTest { } @Test - @PresetData(PresetData.DataSet.NO_ANONYMOUS_READACCESS) - public void testCallableCollectionAgainstAllContexts() throws Exception { + void testCallableCollectionAgainstAllContexts() throws Exception { Collection> callables = new ArrayList<>(); Callable c = SecurityContextHolder::getContext; callables.add(c); @@ -156,8 +160,7 @@ public class SecurityContextExecutorServiceTest { } @Test - @PresetData(PresetData.DataSet.NO_ANONYMOUS_READACCESS) - public void testFailedRunnableResetsContext() { + void testFailedRunnableResetsContext() { Runnable r = () -> { SecurityContextHolder.setContext(nullContext); throw new RuntimeException("Simulate a failure"); diff --git a/test/src/test/java/jenkins/slaves/OldRemotingAgentTest.java b/test/src/test/java/jenkins/slaves/OldRemotingAgentTest.java index 8362ed27cc..186ae014a8 100644 --- a/test/src/test/java/jenkins/slaves/OldRemotingAgentTest.java +++ b/test/src/test/java/jenkins/slaves/OldRemotingAgentTest.java @@ -57,80 +57,88 @@ import java.net.URISyntaxException; import java.util.Collection; import jenkins.security.MasterToSlaveCallable; import org.apache.commons.io.FileUtils; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TemporaryFolder; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.junit.jupiter.api.io.TempDir; +import org.junit.runner.Description; +import org.junit.runners.model.Statement; import org.jvnet.hudson.test.Issue; import org.jvnet.hudson.test.JenkinsRule; import org.jvnet.hudson.test.SimpleCommandLauncher; import org.jvnet.hudson.test.TestBuilder; import org.jvnet.hudson.test.TestExtension; +import org.jvnet.hudson.test.junit.jupiter.JenkinsSessionExtension; /** * Tests for old Remoting agent versions */ -public class OldRemotingAgentTest { +class OldRemotingAgentTest { - @Rule - public JenkinsRule j = new JenkinsRuleWithOldAgent(); + @RegisterExtension + private final JenkinsSessionExtension session = new JenkinsExtensionWithOldAgent(); - @Rule - public TemporaryFolder tmpDir = new TemporaryFolder(); + @TempDir + private File tmpDir; - private File agentJar; + private static File agentJar; - @Before - public void extractAgent() throws Exception { - agentJar = new File(tmpDir.getRoot(), "old-agent.jar"); + @BeforeEach + void extractAgent() throws Exception { + agentJar = new File(tmpDir, "old-agent.jar"); FileUtils.copyURLToFile(OldRemotingAgentTest.class.getResource("/old-remoting/remoting-minimum-supported.jar"), agentJar); } @Test @Issue("JENKINS-48761") - public void shouldBeAbleToConnectAgentWithMinimumSupportedVersion() throws Exception { - Label agentLabel = new LabelAtom("old-agent"); - Slave agent = j.createOnlineSlave(agentLabel); - boolean isUnix = agent.getComputer().isUnix(); - assertThat("Received wrong agent version. A minimum supported version is expected", - agent.getComputer().getSlaveVersion(), - equalTo(RemotingVersionInfo.getMinimumSupportedVersion().toString())); + void shouldBeAbleToConnectAgentWithMinimumSupportedVersion() throws Throwable { + session.then(j -> { + Label agentLabel = new LabelAtom("old-agent"); + Slave agent = j.createOnlineSlave(agentLabel); + boolean isUnix = agent.getComputer().isUnix(); + assertThat("Received wrong agent version. A minimum supported version is expected", + agent.getComputer().getSlaveVersion(), + equalTo(RemotingVersionInfo.getMinimumSupportedVersion().toString())); - // Just ensure we are able to run something on the agent - FreeStyleProject project = j.createFreeStyleProject("foo"); - project.setAssignedLabel(agentLabel); - project.getBuildersList().add(isUnix ? new Shell("echo Hello") : new BatchFile("echo 'hello'")); - j.buildAndAssertSuccess(project); + // Just ensure we are able to run something on the agent + FreeStyleProject project = j.createFreeStyleProject("foo"); + project.setAssignedLabel(agentLabel); + project.getBuildersList().add(isUnix ? new Shell("echo Hello") : new BatchFile("echo 'hello'")); + j.buildAndAssertSuccess(project); - // Run agent monitors - NodeMonitorAssert.assertMonitors(NodeMonitor.getAll(), agent.getComputer()); + // Run agent monitors + NodeMonitorAssert.assertMonitors(NodeMonitor.getAll(), agent.getComputer()); + }); } @Issue("JENKINS-55257") @Test - public void remoteConsoleNote() throws Exception { - Slave agent = j.createOnlineSlave(); - FreeStyleProject project = j.createFreeStyleProject(); - project.setAssignedLabel(agent.getSelfLabel()); - project.getBuildersList().add(new TestBuilder() { - @Override - public boolean perform(AbstractBuild build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException { - build.getWorkspace().act(new RemoteConsoleNotePrinter(listener)); - return true; + void remoteConsoleNote() throws Throwable { + session.then(j -> { + Slave agent = j.createOnlineSlave(); + FreeStyleProject project = j.createFreeStyleProject(); + project.setAssignedLabel(agent.getSelfLabel()); + project.getBuildersList().add(new TestBuilder() { + @Override + public boolean perform(AbstractBuild build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException { + build.getWorkspace().act(new RemoteConsoleNotePrinter(listener)); + return true; + } + }); + FreeStyleBuild b = j.buildAndAssertSuccess(project); + StringWriter sw = new StringWriter(); + // The note will not actually work by default; we just want to ensure that the attempt is ignored without breaking the build. + // But for purposes of testing, check that the note really made it into the log. + boolean insecureOriginal = ConsoleNote.INSECURE; + ConsoleNote.INSECURE = true; + try { + b.getLogText().writeHtmlTo(0, sw); + } finally { + ConsoleNote.INSECURE = insecureOriginal; } + assertThat(sw.toString(), containsString("@@@ANNOTATED@@@")); }); - FreeStyleBuild b = j.buildAndAssertSuccess(project); - StringWriter sw = new StringWriter(); - // The note will not actually work by default; we just want to ensure that the attempt is ignored without breaking the build. - // But for purposes of testing, check that the note really made it into the log. - boolean insecureOriginal = ConsoleNote.INSECURE; - ConsoleNote.INSECURE = true; - try { - b.getLogText().writeHtmlTo(0, sw); - } finally { - ConsoleNote.INSECURE = insecureOriginal; - } - assertThat(sw.toString(), containsString("@@@ANNOTATED@@@")); } private static final class RemoteConsoleNotePrinter extends MasterToSlaveCallable { @@ -160,17 +168,56 @@ public class OldRemotingAgentTest { } //TODO: move the logic to JTH - private class JenkinsRuleWithOldAgent extends JenkinsRule { + private static final class JenkinsExtensionWithOldAgent extends JenkinsSessionExtension { + + private int port; + private Description description; @Override - public ComputerLauncher createComputerLauncher(EnvVars env) throws URISyntaxException, IOException { + public void beforeEach(ExtensionContext context) { + super.beforeEach(context); + description = Description.createTestDescription( + context.getTestClass().map(Class::getName).orElse(null), + context.getTestMethod().map(Method::getName).orElse(null), + context.getTestMethod().map(Method::getAnnotations).orElse(null)); + } - // EnvVars are ignored, simple Command Launcher does not offer this API in public - int sz = this.jenkins.getNodes().size(); - return new SimpleCommandLauncher(String.format("\"%s/bin/java\" %s -jar \"%s\"", - System.getProperty("java.home"), - SLAVE_DEBUG_PORT > 0 ? " -Xdebug -Xrunjdwp:transport=dt_socket,server=y,address=" + (SLAVE_DEBUG_PORT + sz) : "", - agentJar.getAbsolutePath())); + @Override + public void then(Step s) throws Throwable { + CustomJenkinsRule r = new CustomJenkinsRule(getHome(), port); + r.apply( + new Statement() { + @Override + public void evaluate() throws Throwable { + port = r.getPort(); + s.run(r); + } + }, + description + ).evaluate(); + } + + private static final class CustomJenkinsRule extends JenkinsRule { + + CustomJenkinsRule(File home, int port) { + with(() -> home); + localPort = port; + } + + int getPort() { + return localPort; + } + + @Override + public ComputerLauncher createComputerLauncher(EnvVars env) throws URISyntaxException, IOException { + + // EnvVars are ignored, simple Command Launcher does not offer this API in public + int sz = this.jenkins.getNodes().size(); + return new SimpleCommandLauncher(String.format("\"%s/bin/java\" %s -jar \"%s\"", + System.getProperty("java.home"), + SLAVE_DEBUG_PORT > 0 ? " -Xdebug -Xrunjdwp:transport=dt_socket,server=y,address=" + (SLAVE_DEBUG_PORT + sz) : "", + agentJar.getAbsolutePath())); + } } } diff --git a/test/src/test/java/jenkins/slaves/UnsupportedRemotingAgentEscapeHatchTest.java b/test/src/test/java/jenkins/slaves/UnsupportedRemotingAgentEscapeHatchTest.java index b8ccb33b80..e1d5bd277d 100644 --- a/test/src/test/java/jenkins/slaves/UnsupportedRemotingAgentEscapeHatchTest.java +++ b/test/src/test/java/jenkins/slaves/UnsupportedRemotingAgentEscapeHatchTest.java @@ -12,69 +12,124 @@ import hudson.tasks.BatchFile; import hudson.tasks.Shell; import java.io.File; import java.io.IOException; +import java.lang.reflect.Method; import java.net.URISyntaxException; import org.apache.commons.io.FileUtils; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TemporaryFolder; -import org.junit.rules.TestRule; -import org.jvnet.hudson.test.FlagRule; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.junit.jupiter.api.io.TempDir; +import org.junit.runner.Description; +import org.junit.runners.model.Statement; import org.jvnet.hudson.test.Issue; import org.jvnet.hudson.test.JenkinsRule; import org.jvnet.hudson.test.SimpleCommandLauncher; +import org.jvnet.hudson.test.junit.jupiter.JenkinsSessionExtension; /** * Test for the escape hatch for unsupported Remoting agent versions */ -public class UnsupportedRemotingAgentEscapeHatchTest { +class UnsupportedRemotingAgentEscapeHatchTest { - @Rule public JenkinsRule j = new JenkinsRuleWithUnsupportedAgent(); + @RegisterExtension + private final JenkinsSessionExtension session = new JenkinsExtensionWithUnsupportedAgent(); - @Rule public TemporaryFolder tmpDir = new TemporaryFolder(); + @TempDir + private File tmpDir; - @Rule - public TestRule allowUnsupportedRemotingVersions = FlagRule.systemProperty( - SlaveComputer.class.getName() + ".allowUnsupportedRemotingVersions", - Boolean.toString(true)); + private String allowUnsupportedRemotingVersions; - private File agentJar; + private static File agentJar; - @Before - public void extractAgent() throws Exception { - agentJar = new File(tmpDir.getRoot(), "unsupported-agent.jar"); + @BeforeEach + void setUp() throws Exception { + allowUnsupportedRemotingVersions = System.setProperty(SlaveComputer.class.getName() + ".allowUnsupportedRemotingVersions", "true"); + agentJar = new File(tmpDir, "unsupported-agent.jar"); FileUtils.copyURLToFile(UnsupportedRemotingAgentEscapeHatchTest.class.getResource("/old-remoting/remoting-unsupported.jar"), agentJar); } + @AfterEach + void tearDown() { + if (allowUnsupportedRemotingVersions != null) { + System.setProperty(SlaveComputer.class.getName() + ".allowUnsupportedRemotingVersions", allowUnsupportedRemotingVersions); + } else { + System.clearProperty(SlaveComputer.class.getName() + ".allowUnsupportedRemotingVersions"); + } + } + @Issue("JENKINS-50211") @Test - public void shouldBeAbleToConnectAgentWithUnsupportedVersionWithEscapeHatch() throws Exception { - Slave agent = j.createOnlineSlave(); - assertThat(agent.toComputer().getLog(), containsString("The Remoting version is older than the minimum required version")); - assertThat(agent.toComputer().getLog(), containsString("The connection will be allowed, but compatibility is NOT guaranteed")); + void shouldBeAbleToConnectAgentWithUnsupportedVersionWithEscapeHatch() throws Throwable { + session.then(j -> { + Slave agent = j.createOnlineSlave(); + assertThat(agent.toComputer().getLog(), containsString("The Remoting version is older than the minimum required version")); + assertThat(agent.toComputer().getLog(), containsString("The connection will be allowed, but compatibility is NOT guaranteed")); - // Ensure we are able to run something on the agent - FreeStyleProject project = j.createFreeStyleProject("foo"); - project.setAssignedLabel(agent.getSelfLabel()); - project.getBuildersList().add(agent.getComputer().isUnix() - ? new Shell("echo Hello") - : new BatchFile("echo 'hello'")); - j.buildAndAssertSuccess(project); + // Ensure we are able to run something on the agent + FreeStyleProject project = j.createFreeStyleProject("foo"); + project.setAssignedLabel(agent.getSelfLabel()); + project.getBuildersList().add(agent.getComputer().isUnix() + ? new Shell("echo Hello") + : new BatchFile("echo 'hello'")); + j.buildAndAssertSuccess(project); + }); } - private class JenkinsRuleWithUnsupportedAgent extends JenkinsRule { + private static class JenkinsExtensionWithUnsupportedAgent extends JenkinsSessionExtension { + + private int port; + private Description description; + @Override - public ComputerLauncher createComputerLauncher(EnvVars env) throws URISyntaxException, IOException { - int sz = this.jenkins.getNodes().size(); - return new SimpleCommandLauncher( - String.format( - "\"%s/bin/java\" %s -jar \"%s\"", - System.getProperty("java.home"), - SLAVE_DEBUG_PORT > 0 - ? " -Xdebug -Xrunjdwp:transport=dt_socket,server=y,address=" - + (SLAVE_DEBUG_PORT + sz) - : "", - agentJar.getAbsolutePath())); + public void beforeEach(ExtensionContext context) { + super.beforeEach(context); + description = Description.createTestDescription( + context.getTestClass().map(Class::getName).orElse(null), + context.getTestMethod().map(Method::getName).orElse(null), + context.getTestMethod().map(Method::getAnnotations).orElse(null)); + } + + @Override + public void then(Step s) throws Throwable { + CustomJenkinsRule r = new CustomJenkinsRule(getHome(), port); + r.apply( + new Statement() { + @Override + public void evaluate() throws Throwable { + port = r.getPort(); + s.run(r); + } + }, + description + ).evaluate(); + } + + private static final class CustomJenkinsRule extends JenkinsRule { + + CustomJenkinsRule(File home, int port) { + with(() -> home); + localPort = port; + } + + int getPort() { + return localPort; + } + + @Override + public ComputerLauncher createComputerLauncher(EnvVars env) throws URISyntaxException, IOException { + int sz = this.jenkins.getNodes().size(); + return new SimpleCommandLauncher( + String.format( + "\"%s/bin/java\" %s -jar \"%s\"", + System.getProperty("java.home"), + SLAVE_DEBUG_PORT > 0 + ? " -Xdebug -Xrunjdwp:transport=dt_socket,server=y,address=" + + (SLAVE_DEBUG_PORT + sz) + : "", + agentJar.getAbsolutePath())); + } } } } diff --git a/test/src/test/java/jenkins/slaves/UnsupportedRemotingAgentTest.java b/test/src/test/java/jenkins/slaves/UnsupportedRemotingAgentTest.java index feb6d6e84b..b5f2d68415 100644 --- a/test/src/test/java/jenkins/slaves/UnsupportedRemotingAgentTest.java +++ b/test/src/test/java/jenkins/slaves/UnsupportedRemotingAgentTest.java @@ -3,64 +3,113 @@ package jenkins.slaves; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.instanceOf; -import static org.junit.Assert.assertThrows; +import static org.junit.jupiter.api.Assertions.assertThrows; import hudson.EnvVars; import hudson.model.Slave; import hudson.slaves.ComputerLauncher; import java.io.File; import java.io.IOException; +import java.lang.reflect.Method; import java.net.URISyntaxException; import java.util.concurrent.ExecutionException; import org.apache.commons.io.FileUtils; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TemporaryFolder; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.junit.jupiter.api.io.TempDir; +import org.junit.runner.Description; +import org.junit.runners.model.Statement; import org.jvnet.hudson.test.Issue; import org.jvnet.hudson.test.JenkinsRule; import org.jvnet.hudson.test.SimpleCommandLauncher; +import org.jvnet.hudson.test.junit.jupiter.JenkinsSessionExtension; /** * Test for unsupported Remoting agent versions */ -public class UnsupportedRemotingAgentTest { +class UnsupportedRemotingAgentTest { - @Rule public JenkinsRule j = new JenkinsRuleWithUnsupportedAgent(); + @RegisterExtension + private final JenkinsSessionExtension session = new JenkinsExtensionWithUnsupportedAgent(); - @Rule public TemporaryFolder tmpDir = new TemporaryFolder(); + @TempDir + private File tmpDir; - private File agentJar; + private static File agentJar; - @Before - public void extractAgent() throws Exception { - agentJar = new File(tmpDir.getRoot(), "unsupported-agent.jar"); + @BeforeEach + void extractAgent() throws Exception { + agentJar = new File(tmpDir, "unsupported-agent.jar"); FileUtils.copyURLToFile(UnsupportedRemotingAgentTest.class.getResource("/old-remoting/remoting-unsupported.jar"), agentJar); } @Issue("JENKINS-50211") @Test - public void shouldNotBeAbleToConnectAgentWithUnsupportedVersion() throws Exception { - Slave agent = j.createSlave(); - ExecutionException e = assertThrows(ExecutionException.class, () -> agent.toComputer().connect(false).get()); - assertThat(e.getCause(), instanceOf(IOException.class)); - assertThat(e.getMessage(), containsString("Agent failed to connect")); - assertThat(agent.toComputer().getLog(), containsString("Rejecting the connection because the Remoting version is older than the minimum required version")); + void shouldNotBeAbleToConnectAgentWithUnsupportedVersion() throws Throwable { + session.then(j -> { + Slave agent = j.createSlave(); + ExecutionException e = assertThrows(ExecutionException.class, () -> agent.toComputer().connect(false).get()); + assertThat(e.getCause(), instanceOf(IOException.class)); + assertThat(e.getMessage(), containsString("Agent failed to connect")); + assertThat(agent.toComputer().getLog(), containsString("Rejecting the connection because the Remoting version is older than the minimum required version")); + }); } - private class JenkinsRuleWithUnsupportedAgent extends JenkinsRule { + private static class JenkinsExtensionWithUnsupportedAgent extends JenkinsSessionExtension { + + private int port; + private Description description; + @Override - public ComputerLauncher createComputerLauncher(EnvVars env) throws URISyntaxException, IOException { - int sz = this.jenkins.getNodes().size(); - return new SimpleCommandLauncher( - String.format( - "\"%s/bin/java\" %s -jar \"%s\"", - System.getProperty("java.home"), - SLAVE_DEBUG_PORT > 0 - ? " -Xdebug -Xrunjdwp:transport=dt_socket,server=y,address=" - + (SLAVE_DEBUG_PORT + sz) - : "", - agentJar.getAbsolutePath())); + public void beforeEach(ExtensionContext context) { + super.beforeEach(context); + description = Description.createTestDescription( + context.getTestClass().map(Class::getName).orElse(null), + context.getTestMethod().map(Method::getName).orElse(null), + context.getTestMethod().map(Method::getAnnotations).orElse(null)); + } + + @Override + public void then(Step s) throws Throwable { + CustomJenkinsRule r = new CustomJenkinsRule(getHome(), port); + r.apply( + new Statement() { + @Override + public void evaluate() throws Throwable { + port = r.getPort(); + s.run(r); + } + }, + description + ).evaluate(); + } + + private static final class CustomJenkinsRule extends JenkinsRule { + + CustomJenkinsRule(File home, int port) { + with(() -> home); + localPort = port; + } + + int getPort() { + return localPort; + } + + @Override + public ComputerLauncher createComputerLauncher(EnvVars env) throws URISyntaxException, IOException { + int sz = this.jenkins.getNodes().size(); + return new SimpleCommandLauncher( + String.format( + "\"%s/bin/java\" %s -jar \"%s\"", + System.getProperty("java.home"), + SLAVE_DEBUG_PORT > 0 + ? " -Xdebug -Xrunjdwp:transport=dt_socket,server=y,address=" + + (SLAVE_DEBUG_PORT + sz) + : "", + agentJar.getAbsolutePath())); + } } } } diff --git a/test/src/test/java/lib/form/NameRefTest.java b/test/src/test/java/lib/form/NameRefTest.java index b198074593..06d1cf7d53 100644 --- a/test/src/test/java/lib/form/NameRefTest.java +++ b/test/src/test/java/lib/form/NameRefTest.java @@ -24,13 +24,16 @@ package lib.form; -import static org.junit.Assert.assertEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import hudson.model.RootAction; import net.sf.json.JSONObject; import org.htmlunit.html.HtmlPage; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.jvnet.hudson.test.JenkinsRule; +import org.jvnet.hudson.test.TestExtension; +import org.jvnet.hudson.test.junit.jupiter.WithJenkins; import org.kohsuke.stapler.HttpResponse; import org.kohsuke.stapler.HttpResponses; import org.kohsuke.stapler.StaplerRequest2; @@ -38,17 +41,25 @@ import org.kohsuke.stapler.StaplerRequest2; /** * Tests the handling of @nameRef in the form tree. */ -public class NameRefTest { +@WithJenkins +class NameRefTest { - @Rule public JenkinsRule r = new JenkinsRuleWithJelly(); + private JenkinsRule r; - @Test public void test() throws Exception { + @BeforeEach + void setUp(JenkinsRule rule) { + r = rule; + } + + @Test + void test() throws Exception { r.jenkins.setCrumbIssuer(null); HtmlPage p = r.createWebClient().goTo("self/test1"); r.submit(p.getFormByName("config")); } - public static class JenkinsRuleWithJelly extends JenkinsRule { + @TestExtension + public static class RootActionImpl implements RootAction { public HttpResponse doSubmitTest1(StaplerRequest2 req) throws Exception { JSONObject f = req.getSubmittedForm(); @@ -58,6 +69,20 @@ public class NameRefTest { return HttpResponses.ok(); } + @Override + public String getIconFileName() { + return null; + } + + @Override + public String getDisplayName() { + return null; + } + + @Override + public String getUrlName() { + return "self"; + } } } diff --git a/test/src/test/java/org/kohsuke/stapler/BindTest.java b/test/src/test/java/org/kohsuke/stapler/BindTest.java index 8ea7ab3d92..6d2eade0c8 100644 --- a/test/src/test/java/org/kohsuke/stapler/BindTest.java +++ b/test/src/test/java/org/kohsuke/stapler/BindTest.java @@ -5,42 +5,46 @@ import static org.hamcrest.CoreMatchers.endsWith; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.startsWith; import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.Assert.assertThrows; +import static org.junit.jupiter.api.Assertions.assertThrows; import hudson.ExtensionList; import hudson.model.InvisibleAction; import hudson.model.RootAction; -import java.util.Arrays; -import java.util.List; import org.apache.commons.lang3.StringUtils; import org.htmlunit.Page; import org.htmlunit.ScriptException; import org.htmlunit.html.HtmlPage; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.Parameter; +import org.junit.jupiter.params.ParameterizedClass; +import org.junit.jupiter.params.provider.ValueSource; import org.jvnet.hudson.test.JenkinsRule; import org.jvnet.hudson.test.TestExtension; +import org.jvnet.hudson.test.junit.jupiter.WithJenkins; import org.kohsuke.stapler.bind.JavaScriptMethod; import org.kohsuke.stapler.bind.WithWellKnownURL; -@RunWith(Parameterized.class) -public class BindTest { - @Rule - public JenkinsRule j = new JenkinsRule(); +@ParameterizedClass +@ValueSource(strings = { "/jenkins", "" }) +@WithJenkins +class BindTest { - @Parameterized.Parameters - public static List contexts() { - return Arrays.asList("/jenkins", ""); - } + @Parameter + private String contextPath; + + private JenkinsRule j; + + @BeforeEach + void setUp(JenkinsRule rule) throws Throwable { + j = rule; - public BindTest(String contextPath) { j.contextPath = contextPath; + j.restart(); } @Test - public void bindNormal() throws Exception { + void bindNormal() throws Exception { final RootActionImpl root = ExtensionList.lookupSingleton(RootActionImpl.class); try (JenkinsRule.WebClient wc = j.createWebClient()) { final HtmlPage htmlPage = wc.goTo(root.getUrlName()); @@ -61,7 +65,7 @@ public class BindTest { } @Test - public void bindWithWellKnownURL() throws Exception { + void bindWithWellKnownURL() throws Exception { final RootActionWithWellKnownURL root = ExtensionList.lookupSingleton(RootActionWithWellKnownURL.class); try (JenkinsRule.WebClient wc = j.createWebClient()) { final HtmlPage htmlPage = wc.goTo(root.getUrlName()); @@ -80,7 +84,7 @@ public class BindTest { } @Test - public void bindWithWellKnownURLWithQuotes() throws Exception { + void bindWithWellKnownURLWithQuotes() throws Exception { final RootActionWithWellKnownURLWithQuotes root = ExtensionList.lookupSingleton(RootActionWithWellKnownURLWithQuotes.class); try (JenkinsRule.WebClient wc = j.createWebClient()) { final HtmlPage htmlPage = wc.goTo(root.getUrlName()); @@ -99,7 +103,7 @@ public class BindTest { } @Test - public void bindNull() throws Exception { + void bindNull() throws Exception { final RootActionImpl root = ExtensionList.lookupSingleton(RootActionImpl.class); try (JenkinsRule.WebClient wc = j.createWebClient()) { final ScriptException exception = assertThrows(ScriptException.class, () -> wc.goTo(root.getUrlName() + "/null")); @@ -118,7 +122,7 @@ public class BindTest { } @Test - public void bindUnsafe() throws Exception { + void bindUnsafe() throws Exception { final RootActionImpl root = ExtensionList.lookupSingleton(RootActionImpl.class); try (JenkinsRule.WebClient wc = j.createWebClient()) { final HtmlPage htmlPage = wc.goTo(root.getUrlName() + "/unsafe-var"); @@ -137,7 +141,7 @@ public class BindTest { } @Test - public void bindInlineNull() throws Exception { + void bindInlineNull() throws Exception { final RootActionImpl root = ExtensionList.lookupSingleton(RootActionImpl.class); try (JenkinsRule.WebClient wc = j.createWebClient()) { final HtmlPage htmlPage = wc.goTo(root.getUrlName() + "/inline-null"); diff --git a/test/src/test/resources/lib/form/NameRefTest/JenkinsRuleWithJelly/test1.jelly b/test/src/test/resources/lib/form/NameRefTest/RootActionImpl/test1.jelly similarity index 100% rename from test/src/test/resources/lib/form/NameRefTest/JenkinsRuleWithJelly/test1.jelly rename to test/src/test/resources/lib/form/NameRefTest/RootActionImpl/test1.jelly