Migrate tests to JUnit5 (#10895)
Changelog Drafter / update_draft_release (push) Waiting to run Details
Changelog Drafter / jenkins_io_draft (push) Waiting to run Details
Label conflicting PRs / main (push) Waiting to run Details

This commit is contained in:
Kris Stern 2025-08-03 08:53:53 +08:00 committed by GitHub
commit f036fa8e03
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
76 changed files with 3168 additions and 2386 deletions

View File

@ -442,7 +442,7 @@ THE SOFTWARE.
<artifactId>maven-surefire-plugin</artifactId>
<!-- Version specified in grandparent POM -->
<configuration>
<groups>org.jvnet.hudson.test.SmokeTest</groups>
<groups>SmokeTest</groups>
</configuration>
</plugin>
</plugins>

View File

@ -25,34 +25,149 @@
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 {
@RegisterExtension
private final JenkinsSessionExtension session = new CustomPluginManagerExtension();
/**
* Test finding resources via DependencyClassLoader.
*/
@LocalData
@Test
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<URL> 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");
});
}
/**
* Test finding resources via DependencyClassLoader.
* Check transitive dependency exclude disabled plugins
*/
@LocalData
@Issue("JENKINS-18654")
@Test
void testDisabledDependencyClassLoader() throws Throwable {
session.then(j -> {
PluginWrapper p = j.jenkins.getPluginManager().getPlugin("foo4");
Enumeration<URL> 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");
}
});
}
/**
* Test finding resources under masking.
* "foo1" plugin contains attribute of Mask-Classes: org.apache.http.
*/
@LocalData
@Issue("JENKINS-27289")
@Test
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;
}
@Rule
public JenkinsRule j = new JenkinsRule() {
@Override
protected Hudson newHudson() throws Exception {
File home = homeLoader.allocate();
@ -73,69 +188,6 @@ public class ClassicPluginStrategyTest {
setPluginManager(pluginManager);
return new Hudson(home, createWebServer2(), pluginManager);
}
};
/**
* 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;
// 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<URL> 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/"));
}
/**
* Test finding resources via DependencyClassLoader.
* Check transitive dependency exclude disabled plugins
*/
@LocalData
@Issue("JENKINS-18654")
@Test
public void testDisabledDependencyClassLoader() throws Exception {
PluginWrapper p = j.jenkins.getPluginManager().getPlugin("foo4");
Enumeration<URL> 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");
}
}
/**
* Test finding resources under masking.
* "foo1" plugin contains attribute of Mask-Classes: org.apache.http.
*/
@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"));
}
}

View File

@ -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<? extends CustomPluginManager> klass) {
assertTrue("Correct plugin manager installed", klass.isAssignableFrom(r.getPluginManager().getClass()));
assertNotNull("Plugin 'htmlpublisher' installed", r.jenkins.getPlugin("htmlpublisher"));
private void check(Class<? extends CustomPluginManager> 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);
}

View File

@ -24,22 +24,24 @@
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 <a href="mailto:tom.fennelly@gmail.com">tom.fennelly@gmail.com</a>
*/
public class ExtensionListListenerTest {
class ExtensionListListenerTest {
@Rule
public JenkinsRule r = PluginManagerUtil.newJenkinsRule();
@RegisterExtension
public JenkinsSessionExtension session = PluginManagerUtil.newJenkinsSessionExtension();
@Test
public void test_onChange() throws Exception {
void test_onChange() throws Throwable {
session.then(r -> {
ExtensionList<TransientActionFactory> extensionList = ExtensionList.lookup(TransientActionFactory.class);
// force ExtensionList.ensureLoaded, otherwise the refresh will be ignored because
@ -54,7 +56,8 @@ public class ExtensionListListenerTest {
// 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 {

View File

@ -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"));
@ -58,7 +59,7 @@ public class ExtensionListRjrTest {
@Test
@Issue({"JENKINS-50336", "JENKINS-60449"})
public void installDependedOptionalPluginWithoutRestart() throws Throwable {
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"));

View File

@ -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,48 +43,30 @@ 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 <a href="mailto:tom.fennelly@gmail.com">tom.fennelly@gmail.com</a>
*/
public class PluginManagerInstalledGUITest {
class PluginManagerInstalledGUITest {
@Rule
public JenkinsRule jenkinsRule = new JenkinsRule() {
@Override
public PluginManager getPluginManager() {
try {
return new TestPluginManager() {
@Override
protected Collection<String> 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");
@ -140,13 +128,14 @@ public class PluginManagerInstalledGUITest {
matrixAuthPlugin.assertNotEnabled();
matrixAuthPlugin.assertEnabledStateChangeable();
matrixAuthPlugin.assertUninstallable();
});
}
private class InstalledPlugins {
private static class InstalledPlugins {
private final List<InstalledPlugin> 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<String> 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());
}
}
}
}
}

View File

@ -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,34 +114,51 @@ 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<Boolean> signatureCheck = new FlagRule<>(() -> DownloadService.signatureCheck, x -> DownloadService.signatureCheck = x);
@RegisterExtension
private final JenkinsSessionExtension session = PluginManagerUtil.newJenkinsSessionExtension();
@TempDir
private File tmp;
private boolean signatureCheck;
@BeforeEach
void setUp() {
signatureCheck = DownloadService.signatureCheck;
}
@AfterEach
void tearDown() {
DownloadService.signatureCheck = signatureCheck;
}
/**
* Manual submission form.
*/
@Test public void uploadJpi() throws Exception {
@Test
void uploadJpi() throws Throwable {
session.then(r -> {
HtmlPage page = r.createWebClient().goTo("pluginManager/advanced");
HtmlForm f = page.getFormByName("uploadPlugin");
File dir = tmp.newFolder();
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);
assertTrue(new File(r.jenkins.getRootDir(), "plugins/htmlpublisher.jpi").exists());
});
}
/**
* Manual submission form.
*/
@Test public void uploadHpi() throws Exception {
@Test
void uploadHpi() throws Throwable {
session.then(r -> {
HtmlPage page = r.createWebClient().goTo("pluginManager/advanced");
HtmlForm f = page.getFormByName("uploadPlugin");
File dir = tmp.newFolder();
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());
@ -148,15 +166,19 @@ public class PluginManagerTest {
// uploaded legacy plugins get renamed to *.jpi
assertTrue(new File(r.jenkins.getRootDir(), "plugins/legacy.jpi").exists());
});
}
@Test public void deployJpiFromUrl() throws Exception {
@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,7 +269,9 @@ 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 {
@Test
void uberClassLoaderDoesntUseContextClassLoader() throws Throwable {
session.then(r -> {
Thread t = Thread.currentThread();
URLClassLoader ucl = new URLClassLoader(new URL[0], r.jenkins.pluginManager.uberClassLoader);
@ -257,9 +285,12 @@ public class PluginManagerTest {
} finally {
t.setContextClassLoader(old);
}
});
}
@Test public void installWithoutRestart() throws Exception {
@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);
@ -267,10 +298,13 @@ public class PluginManagerTest {
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());
@Test
void prevalidateConfig() throws Throwable {
session.then(r -> {
assumeFalse(Functions.isWindows(), "TODO: Implement this test on Windows");
PersistedList<UpdateSite> sites = r.jenkins.getUpdateCenter().getSites();
sites.clear();
URL url = PluginManagerTest.class.getResource("/plugins/htmlpublisher-update-center.json");
@ -290,6 +324,7 @@ public class PluginManagerTest {
// 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 {
@Test
void installDependingPluginWithoutRestart() throws Throwable {
session.then(r -> {
// Load dependee.
{
dynamicLoad("dependee.hpi");
dynamicLoad(r, "dependee.hpi");
}
// before load depender, of course failed to call Depender.getValue()
assertThrows(ClassNotFoundException.class, this::callDependerValue);
assertThrows(ClassNotFoundException.class, () -> callDependerValue(r));
// No extensions exist.
assertTrue(r.jenkins.getExtensionList("org.jenkinsci.plugins.dependencytest.dependee.DependeeExtensionPoint").isEmpty());
// Load depender.
{
dynamicLoad("depender.hpi");
dynamicLoad(r, "depender.hpi");
}
// depender successfully accesses to dependee.
assertEquals("dependee", callDependerValue());
assertEquals("dependee", callDependerValue(r));
// Extension in depender is loaded.
assertFalse(r.jenkins.getExtensionList("org.jenkinsci.plugins.dependencytest.dependee.DependeeExtensionPoint").isEmpty());
});
}
/**
@ -361,14 +399,16 @@ public class PluginManagerTest {
* Asserts that "depender" can access to "dependee".
*/
@Issue("JENKINS-19976")
@Test public void installDependedPluginWithoutRestart() throws Exception {
@Test
void installDependedPluginWithoutRestart() throws Throwable {
session.then(r -> {
// Load depender.
{
dynamicLoad("depender.hpi");
dynamicLoad(r, "depender.hpi");
}
// before load dependee, depender does not access to dependee.
assertEquals("depender", callDependerValue());
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"));
@ -377,58 +417,70 @@ public class PluginManagerTest {
// Load dependee.
{
dynamicLoad("dependee.hpi");
dynamicLoad(r, "dependee.hpi");
}
// (MUST) Not throws an exception
// (SHOULD) depender successfully accesses to dependee.
assertEquals("dependee", callDependerValue());
assertEquals("dependee", callDependerValue(r));
// 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 {
@Test
void installPluginWithObsoleteDependencyFails() throws Throwable {
session.then(r -> {
// Load dependee 0.0.1.
{
dynamicLoad("dependee.hpi");
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"));
assertThrows(IOException.class, () -> dynamicLoad(r, "mandatory-depender-0.0.2.hpi"));
});
}
@Issue("JENKINS-21486")
@Test public void installPluginWithDisabledOptionalDependencySucceeds() throws Exception {
@Test
void installPluginWithDisabledOptionalDependencySucceeds() throws Throwable {
session.then(r -> {
// Load dependee 0.0.2.
{
dynamicLoadAndDisable("dependee-0.0.2.hpi");
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");
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"));
});
}
@Issue("JENKINS-21486")
@Test public void installPluginWithDisabledDependencyFails() throws Exception {
@Test
void installPluginWithDisabledDependencyFails() throws Throwable {
session.then(r -> {
// Load dependee 0.0.2.
{
dynamicLoadAndDisable("dependee-0.0.2.hpi");
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"));
assertThrows(IOException.class, () -> dynamicLoad(r, "mandatory-depender-0.0.2.hpi"));
});
}
@Issue("JENKINS-68194")
@WithPlugin("dependee.hpi")
@Test public void clearDisabledStatusAfterUninstall() throws Exception {
@Test
void clearDisabledStatusAfterUninstall() throws Throwable {
session.then(r -> {
PluginWrapper pw = r.jenkins.pluginManager.getPlugin("dependee");
assertNotNull(pw);
@ -437,22 +489,28 @@ public class PluginManagerTest {
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 {
@Test
void installPluginWithObsoleteOptionalDependencyFails() throws Throwable {
session.then(r -> {
// Load dependee 0.0.1.
{
dynamicLoad("dependee.hpi");
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"));
assertThrows(IOException.class, () -> dynamicLoad(r, "depender-0.0.2.hpi"));
});
}
@Issue("JENKINS-12753")
@WithPlugin("htmlpublisher.jpi")
@Test public void dynamicLoadRestartRequiredException() throws Exception {
@Test
void dynamicLoadRestartRequiredException() throws Throwable {
session.then(r -> {
File jpi = new File(r.jenkins.getRootDir(), "plugins/htmlpublisher.jpi");
assertTrue(jpi.isFile());
FileUtils.touch(jpi);
@ -460,11 +518,14 @@ public class PluginManagerTest {
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());
assertEquals(lastMod, timestamp.lastModified(), "should not have tried to delete & unpack");
});
}
@WithPlugin("htmlpublisher.jpi")
@Test public void pluginListJSONApi() throws IOException {
@Test
void pluginListJSONApi() throws Throwable {
session.then(r -> {
JSONObject response = r.getJSON("pluginManager/plugins").getJSONObject();
// Check that the basic API endpoint invocation works.
@ -478,53 +539,61 @@ public class PluginManagerTest {
assertNotNull(pluginInfo.getString("name"));
assertNotNull(pluginInfo.getString("title"));
assertNotNull(pluginInfo.getString("dependencies"));
});
}
@Issue("JENKINS-41684")
@Test
public void requireSystemDuringLoad() throws Exception {
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("require-system-during-load.hpi");
dynamicLoad(r, "require-system-during-load.hpi");
}
});
}
@Test
@Issue("JENKINS-59775")
public void requireSystemDuringStart() throws Exception {
void requireSystemDuringStart() throws Throwable {
session.then(r -> {
r.jenkins.setSecurityRealm(r.createDummySecurityRealm());
r.jenkins.setAuthorizationStrategy(new MockAuthorizationStrategy());
String pluginShortName = "require-system-during-load";
dynamicLoad(pluginShortName + ".hpi");
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 {
void requireSystemInInitializer() throws Throwable {
session.then(r -> {
r.jenkins.setSecurityRealm(r.createDummySecurityRealm());
r.jenkins.setAuthorizationStrategy(new MockAuthorizationStrategy());
String pluginShortName = "require-system-in-initializer";
dynamicLoad(pluginShortName + ".jpi");
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());
@Test
void uploadDependencyResolution() throws Throwable {
session.then(r -> {
assumeFalse(Functions.isWindows(), "TODO: Implement this test for Windows");
PersistedList<UpdateSite> sites = r.jenkins.getUpdateCenter().getSites();
sites.clear();
URL url = PluginManagerTest.class.getResource("/plugins/upload-test-update-center.json");
@ -540,7 +609,7 @@ public class PluginManagerTest {
HtmlPage page = r.createWebClient().goTo("pluginManager/advanced");
HtmlForm f = page.getFormByName("uploadPlugin");
File dir = tmp.newFolder();
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());
@ -570,12 +639,14 @@ public class PluginManagerTest {
// 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() {
void findResourceForPluginFirstClassLoader() throws Throwable {
session.then(r -> {
PluginWrapper w = r.jenkins.getPluginManager().getPlugin("plugin-first");
assertNotNull(w);
@ -586,33 +657,41 @@ public class PluginManagerTest {
URL fromToolkit = ClassLoaderReflectionToolkit._findResource(w.classLoader, "org/jenkinsci/plugins/pluginfirst/HelloWorldBuilder/config.jelly");
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 {
void getPluginsSortedByTitle() throws Throwable {
session.then(r -> {
List<String> installedPlugins = r.jenkins.getPluginManager().getPluginsSortedByTitle()
.stream()
.map(PluginWrapper::getDisplayName)
.collect(Collectors.toUnmodifiableList());
.toList();
assertThat(installedPlugins, containsInRelativeOrder("dependee", "depender", "mandatory-depender"));
});
}
@Issue("JENKINS-62622")
@Test
@WithPlugin("legacy.hpi")
public void doNotThrowWithUnknownPlugins() throws Exception {
void doNotThrowWithUnknownPlugins() throws Throwable {
session.then(r -> {
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"));
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);
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());
@Test
@Issue("JENKINS-64840")
void searchMultipleUpdateSites() throws Throwable {
session.then(r -> {
assumeFalse(Functions.isWindows(), "TODO: Implement this test for Windows");
PersistedList<UpdateSite> sites = r.jenkins.getUpdateCenter().getSites();
sites.clear();
URL url = PluginManagerTest.class.getResource("/plugins/search-test-update-center1.json");
@ -634,26 +713,28 @@ public class PluginManagerTest {
JSONObject json = response.getJSONObject();
assertTrue(json.has("data"));
JSONArray data = json.getJSONArray("data");
assertEquals("Should be one search hit for dummy", 1, data.size());
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());
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());
assertEquals(2, data.size(), "Should be two search hits for hello");
});
}
@Issue("JENKINS-70599")
@Test
public void installNecessaryPluginsTest() throws Exception {
void installNecessaryPluginsTest() throws Throwable {
session.then(r -> {
String jenkinsUrl = r.getURL().toString();
// Define a cookie handler
@ -680,9 +761,9 @@ public class PluginManagerTest {
.connectTimeout(Duration.ofSeconds(2))
.build();
HttpResponse<String> responseGet = clientGet.send(httpGet, HttpResponse.BodyHandlers.ofString());
assertEquals("Bad response for crumb issuer", 200, responseGet.statusCode());
assertEquals(200, responseGet.statusCode(), "Bad response for crumb issuer");
String body = responseGet.body();
assertTrue("crumbRequestField not in response", body.contains("crumbRequestField"));
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");
@ -707,17 +788,19 @@ public class PluginManagerTest {
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
// Redirect reported 404 before bug was fixed
assertEquals("Bad response for installNecessaryPlugins", 200, response.statusCode());
assertEquals(200, response.statusCode(), "Bad response for installNecessaryPlugins");
});
}
@Test
@Issue("SECURITY-2823")
public void verifyUploadedPluginPermission() throws Exception {
void verifyUploadedPluginPermission() throws Throwable {
assumeFalse(Functions.isWindows());
session.then(r -> {
HtmlPage page = r.createWebClient().goTo("pluginManager/advanced");
HtmlForm f = page.getFormByName("uploadPlugin");
File dir = tmp.newFolder();
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());
@ -748,11 +831,13 @@ public class PluginManagerTest {
}
});
assertEquals(EnumSet.of(OWNER_EXECUTE, OWNER_READ, OWNER_WRITE), filesPermission[0]);
});
}
@Test
@Issue("SECURITY-3037")
public void noInjectionOnAvailablePluginsPage() throws Exception {
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");
@ -775,13 +860,15 @@ public class PluginManagerTest {
wc.waitForBackgroundJavaScript(100);
assertTrue(alertHandler.messages.isEmpty());
}
});
}
@Test
@Issue("SECURITY-3072")
public void verifyUploadedPluginFromURLPermission() throws Exception {
void verifyUploadedPluginFromURLPermission() throws Throwable {
assumeFalse(Functions.isWindows());
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");
@ -812,6 +899,7 @@ public class PluginManagerTest {
}
});
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;
}
}

View File

@ -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 <a href="mailto:tom.fennelly@gmail.com">tom.fennelly@gmail.com</a>
*/
public class PluginManagerUtil {
public static JenkinsRule newJenkinsRule() {
return new JenkinsRule() {
public static JenkinsSessionExtension newJenkinsSessionExtension() {
return new JenkinsSessionExtension() {
private int port;
private Description description;
@Override
public void before() throws Throwable {
setPluginManager(null);
super.before();
}
};
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));
}
public static RestartableJenkinsRule newRestartableJenkinsRule() {
return new RestartableJenkinsRule() {
@Override
public JenkinsRule createJenkinsRule(Description description) {
return newJenkinsRule();
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;
}
}
};
}

View File

@ -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);

View File

@ -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());

View File

@ -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"));

View File

@ -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());
}
}

View File

@ -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

View File

@ -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,54 +32,32 @@ 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();
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();
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");
@ -87,50 +65,31 @@ public class ReverseProxySetupMonitorTest {
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();
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();
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);
JenkinsRule.WebClient wc = rr.j.createWebClient();
JenkinsRule.WebClient wc = j.createWebClient();
WebRequest request = new WebRequest(new URL(j.getURL(), getAdminMonitorTestUrl(j)));
request.setAdditionalHeader("Referer", j.getURL() + "manage");
@ -141,21 +100,14 @@ public class ReverseProxySetupMonitorTest {
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);
JenkinsRule.WebClient wc = rr.j.createWebClient();
JenkinsRule.WebClient wc = j.createWebClient();
WebRequest request = new WebRequest(new URL(j.getURL(), getAdminMonitorTestUrl(j)));
request.setAdditionalHeader("Referer", j.getURL() + "manage");
@ -164,18 +116,14 @@ public class ReverseProxySetupMonitorTest {
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();
j.restart();
JenkinsRule.WebClient wc = j.createWebClient();
WebRequest request = new WebRequest(new URL(j.getURL(), getAdminMonitorTestUrl(j)));
request.setAdditionalHeader("Referer", j.getURL() + "manage");
@ -185,44 +133,26 @@ public class ReverseProxySetupMonitorTest {
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();
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();
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();
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");
@ -231,39 +161,26 @@ public class ReverseProxySetupMonitorTest {
// 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;
void withRootURL_usingIp_withRefererIp() throws Exception {
JenkinsLocationConfiguration.get().setUrl(getRootUrlWithIp(j).toString());
JenkinsRule.WebClient wc = rr.j.createWebClient();
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);
}
});
}
@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);
JenkinsRule.WebClient wc = rr.j.createWebClient();
JenkinsRule.WebClient wc = j.createWebClient();
WebRequest request = new WebRequest(new URL(getRootUrlWithIp(j), getAdminMonitorTestUrl(j)));
// referer using IP
request.setAdditionalHeader("Referer", getRootUrlWithIp(j) + "manage");
@ -275,8 +192,6 @@ public class ReverseProxySetupMonitorTest {
request.setRequestParameters(List.of(new NameValuePair("testWithContext", "true")));
wc.getPage(request);
}
});
}
private String getAdminMonitorTestUrl(JenkinsRule j) {
return j.jenkins.getAdministrativeMonitor(ReverseProxySetupMonitor.class.getName()).getUrl() + "/test";

View File

@ -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);
}

View File

@ -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");

View File

@ -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());
}

View File

@ -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 {

View File

@ -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();

View File

@ -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

View File

@ -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<FreeStyleBuild> 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:<NONE> but was:<INCOMPARABLE>")
@Disabled("randomly failed: Project should have polling result no change expected:<NONE> but was:<INCOMPARABLE>")
@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<Integer, Fingerprint.RangeSet> 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 {
}

View File

@ -1,24 +1,30 @@
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 -> {
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;
@ -34,13 +40,14 @@ public class QueueCrashTest {
// 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);
j.restart();
assertBuildIsScheduled(j);
}
@Test
public void doNotPersistQueueOnCrashBeforeSave() {
rr.thenWithHardShutdown(j -> {
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);
@ -50,8 +57,10 @@ public class QueueCrashTest {
// 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);
j.restart();
assertBuildIsNotScheduled(j);
}
private static void assertBuildIsScheduled(JenkinsRule j) {

View File

@ -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));

View File

@ -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);

View File

@ -29,33 +29,82 @@ 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() {
void shouldStartupWithCustomUpdateCenter() throws Throwable {
session.then(j -> {
UpdateCenter uc = j.jenkins.getUpdateCenter();
assertThat("Update Center must be a custom instance", uc, instanceOf(CustomUpdateCenter.class));
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;
CustomUpdateCenterExtension(Class<?> ucClass) {
this.updateCenterClassName = ucClass.getName();
}
@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(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";
CustomUpdateCenterRule(Class<?> ucClass) {
this.updateCenterClassName = ucClass.getName();
CustomJenkinsRule(final String updateCenterClassName, File home, int port) {
this.updateCenterClassName = updateCenterClassName;
with(() -> home);
localPort = port;
}
int getPort() {
return localPort;
}
@Override
@ -71,20 +120,19 @@ public class UpdateCenterCustomTest {
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);
}
}
}
}

View File

@ -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() {
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;
}
}
}
}

View File

@ -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));

View File

@ -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();

View File

@ -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);
}

View File

@ -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);

View File

@ -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<String> 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);
}
}

View File

@ -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;

View File

@ -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<Callable<Void>> 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) {

View File

@ -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);
}

View File

@ -75,7 +75,7 @@ import org.springframework.security.core.Authentication;
import org.xml.sax.SAXException;
@WithJenkins
public class BuildTriggerTest {
class BuildTriggerTest {
private JenkinsRule j;

View File

@ -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());
}
}

View File

@ -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<String> 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,7 +82,135 @@ public class BootFailureTest {
}
}
static class CustomRule extends JenkinsRule {
@AfterEach
void tearDown() {
Jenkins j = Jenkins.getInstanceOrNull();
if (j != null) {
j.cleanUp();
}
}
public static class SeriousError extends Error {}
@TestExtension("runBootFailureScript")
public static class InduceBootFailure extends ItemListener {
@Override
public void onLoaded() {
if (makeBootFail)
throw new SeriousError();
}
}
@Test
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);
// first failed boot
makeBootFail = true;
assertNull(((CustomJenkinsSessionExtension.CustomJenkinsRule) j).newHudson());
assertEquals(1, bootFailures(home));
// 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());
// 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) {
return new BootFailure() { }.loadAttempts(home).size();
}
@Issue("JENKINS-24696")
@Test
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")
public static class PauseBoot extends ItemListener {
@Override
public void onLoaded() {
wa.contextDestroyed(null);
}
}
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);
@ -101,88 +242,5 @@ public class BootFailureTest {
return null; // didn't boot
}
}
@Rule
public CustomRule j = new CustomRule();
@After
public void tearDown() {
Jenkins j = Jenkins.getInstanceOrNull();
if (j != null) {
j.cleanUp();
}
}
public static class SeriousError extends Error {}
@TestExtension("runBootFailureScript")
public static class InduceBootFailure extends ItemListener {
@Override
public void onLoaded() {
if (makeBootFail)
throw new SeriousError();
}
}
@Test
public void runBootFailureScript() throws Exception {
final File home = tmpDir.newFolder();
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);
// first failed boot
makeBootFail = true;
assertNull(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);
// 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());
}
private static int bootFailures(File home) throws IOException {
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);
}
@TestExtension("interruptedStartup")
public static class PauseBoot extends ItemListener {
@Override
public void onLoaded() {
wa.contextDestroyed(null);
}
}
// to be set by the script
public static Exception problem;
public static List<String> runRecord = new ArrayList<>();
}

View File

@ -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);
}

View File

@ -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();

View File

@ -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());

View File

@ -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);

View File

@ -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()));

View File

@ -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<String> 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);
}

View File

@ -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<DetachedPlugin> 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<DetachedPlugin> detachedPlugins = DetachedPluginsUtil.getDetachedPlugins(since);
@ -108,7 +108,7 @@ public class LoadDetachedPluginsTest {
}
@Test
public void newInstallation() {
void newInstallation() throws Throwable {
rr.then(r -> {
List<DetachedPlugin> 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<String> 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());
}
}

View File

@ -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");
});
}

View File

@ -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

View File

@ -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<String> 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);

View File

@ -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.
* <p>
* 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<String> 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<String> 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<String> 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;
}
}

View File

@ -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,49 +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 {
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 {
void doNotAcceptNonHttpBasedRootURL_fromUI() throws Throwable {
session.then(j -> {
// in JenkinsRule, the URL is set to the current URL
JenkinsLocationConfiguration.getOrDie().setUrl(null);
@ -72,7 +69,7 @@ public class JenkinsLocationConfigurationTest {
assertNull(JenkinsLocationConfiguration.getOrDie().getUrl());
settingRootURL("javascript:alert(123);//");
settingRootURL(j, "javascript:alert(123);//");
// no impact on the url in memory
assertNull(JenkinsLocationConfiguration.getOrDie().getUrl());
@ -81,11 +78,13 @@ public class JenkinsLocationConfigurationTest {
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 {
void escapeHatch_acceptNonHttpBasedRootURL_fromUI() throws Throwable {
session.then(j -> {
boolean previousValue = JenkinsLocationConfiguration.DISABLE_URL_VALIDATION;
JenkinsLocationConfiguration.DISABLE_URL_VALIDATION = true;
@ -98,7 +97,7 @@ public class JenkinsLocationConfigurationTest {
assertNull(JenkinsLocationConfiguration.getOrDie().getUrl());
String expectedUrl = "weirdSchema:somethingAlsoWeird";
settingRootURL(expectedUrl);
settingRootURL(j, expectedUrl);
// the method ensures there is an trailing slash
assertEquals(expectedUrl + "/", JenkinsLocationConfiguration.getOrDie().getUrl());
@ -107,31 +106,34 @@ public class JenkinsLocationConfigurationTest {
String configFileContent = Files.readString(configFile, StandardCharsets.UTF_8);
assertThat(configFileContent, containsString("JenkinsLocationConfiguration"));
assertThat(configFileContent, containsString(expectedUrl));
}
finally {
} finally {
JenkinsLocationConfiguration.DISABLE_URL_VALIDATION = previousValue;
}
});
}
@Test
@Issue("SECURITY-1471")
@LocalData("xssThroughConfigXml")
public void doNotAcceptNonHttpBasedRootURL_fromConfigXml() {
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")));
});
}
@Test
@Issue("SECURITY-1471")
public void cannotInjectJavaScriptUsingRootUrl_inNewViewLink() throws Exception {
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<Boolean> alertAppeared = new AtomicReference<>(false);
@ -149,17 +151,19 @@ public class JenkinsLocationConfigurationTest {
HtmlElementUtil.click(newViewLink);
assertFalse(alertAppeared.get());
});
}
@Test
@Issue("SECURITY-1471")
public void cannotInjectJavaScriptUsingRootUrl_inLabelAbsoluteLink() throws Exception {
void cannotInjectJavaScriptUsingRootUrl_inLabelAbsoluteLink() throws Throwable {
session.then(j -> {
String builtInLabel = "builtin-node";
j.jenkins.setLabelString(builtInLabel);
JenkinsRule.WebClient wc = j.createWebClient();
settingRootURL("javascript:alert(123);//");
settingRootURL(j, "javascript:alert(123);//");
// setup the victim
AtomicReference<Boolean> alertAppeared = new AtomicReference<>(false);
@ -184,13 +188,68 @@ public class JenkinsLocationConfigurationTest {
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();
}
}
}
}

View File

@ -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<LogRecord> logRecords = Jenkins.logRecords;
assertThat(logRecords, not(empty()));
assertThat("Records are displayed in reverse order",

View File

@ -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() {
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");

View File

@ -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<Slave> 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(), "<broken");
@ -782,4 +792,13 @@ public class JenkinsTest {
assertThat(j.jenkins.getViews(), contains(isA(AllView.class)));
}
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;
}
}

View File

@ -2,27 +2,31 @@ package jenkins.model;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasSize;
import static org.junit.Assert.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import edu.umd.cs.findbugs.annotations.NonNull;
import hudson.model.Descriptor;
import hudson.model.Slave;
import hudson.slaves.ComputerLauncher;
import java.io.IOException;
import org.junit.Rule;
import org.junit.Test;
import org.jvnet.hudson.test.JenkinsSessionRule;
import java.io.Serial;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
import org.jvnet.hudson.test.junit.jupiter.JenkinsSessionExtension;
public class NodesRestartTest {
@Rule
public JenkinsSessionRule s = new JenkinsSessionRule();
class NodesRestartTest {
@RegisterExtension
private final JenkinsSessionExtension s = new JenkinsSessionExtension();
// The point of this implementation is to override readResolve so that Slave#readResolve doesn't get called.
public static class DummyAgent extends Slave {
@SuppressWarnings(value = "checkstyle:redundantmodifier")
public DummyAgent(@NonNull String name, String remoteFS, ComputerLauncher launcher) throws Descriptor.FormException, IOException {
super(name, remoteFS, launcher);
}
@Serial
@Override
protected Object readResolve() {
return this;
@ -30,7 +34,7 @@ public class NodesRestartTest {
}
@Test
public void checkNodeRestart() throws Throwable {
void checkNodeRestart() throws Throwable {
s.then(r -> {
assertThat(r.jenkins.getNodes(), hasSize(0));
var node = new DummyAgent("my-node", "temp", r.createComputerLauncher(null));

View File

@ -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<String> 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<String> token = new AtomicReference<>();
sessions.then(j -> {
enableLegacyTokenGenerationOnUserCreation();

View File

@ -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);
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);
() -> 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");
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);
},
() -> 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;
}
}

View File

@ -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<String, String> FLAG_TO_SAMESITE_COOKIE = new HashMap<>() {{
put("", null);
@ -25,27 +31,40 @@ public class JettySameSiteCookieSetupTest {
put(null, "lax");
}};
@Rule
public JenkinsRule j = new JenkinsRule();
@RegisterExtension
private final JenkinsSessionExtension session = new JenkinsSessionExtension();
@Rule
public FlagRule<String> 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<String> sameSite() {
static Set<String> sameSite() {
return FLAG_TO_SAMESITE_COOKIE.keySet();
}
@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
public void testJettyFlagSetsSameSiteCookieProperty() throws Exception {
String expected = FLAG_TO_SAMESITE_COOKIE.get(this.sameSiteValue);
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"));
@ -55,5 +74,6 @@ public class JettySameSiteCookieSetupTest {
assertThat(wc.getCookieManager().getCookie("JSESSIONID").getSameSite(), is(expected));
assertThat(wc.getCookieManager().getCookie("remember-me").getSameSite(), is(expected));
}
});
}
}

View File

@ -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()));
}

View File

@ -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;
}
}

View File

@ -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<String> 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<String> 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<String> 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));
}

View File

@ -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<URL> urlSet;
@SuppressWarnings(value = "checkstyle:redundantmodifier")
public URLJobProperty(URL... urls) {
this.urlSet = new HashSet<>();
Collections.addAll(urlSet, urls);

View File

@ -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,30 +35,38 @@ 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;
private JenkinsRule j;
@BeforeEach
void setUp(JenkinsRule rule) {
j = rule;
JenkinsRule.DummySecurityRealm realm = j.createDummySecurityRealm();
j.jenkins.setSecurityRealm(realm);
j.jenkins.setAuthorizationStrategy(new MockAuthorizationStrategy()
.grant(Jenkins.ADMINISTER).everywhere().toAuthenticated());
ScheduledThreadPoolExecutor service = new ScheduledThreadPoolExecutor(NUM_THREADS);
// Create a system level context with ACL.SYSTEM2
@ -75,11 +83,9 @@ public class SecurityContextExecutorServiceTest {
// 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<SecurityContext> c = SecurityContextHolder::getContext;
SecurityContextHolder.setContext(systemContext);
Future<SecurityContext> 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<Callable<SecurityContext>> callables = new ArrayList<>();
Callable<SecurityContext> 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");

View File

@ -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<String> tokenValue = new AtomicReference<>();
AtomicReference<String> 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());
}

View File

@ -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<String> 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<String> initialSeedRef = new AtomicReference<>();
AtomicReference<String> seedRef = new AtomicReference<>();

View File

@ -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", "");

View File

@ -57,38 +57,43 @@ 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 {
void shouldBeAbleToConnectAgentWithMinimumSupportedVersion() throws Throwable {
session.then(j -> {
Label agentLabel = new LabelAtom("old-agent");
Slave agent = j.createOnlineSlave(agentLabel);
boolean isUnix = agent.getComputer().isUnix();
@ -104,11 +109,13 @@ public class OldRemotingAgentTest {
// Run agent monitors
NodeMonitorAssert.assertMonitors(NodeMonitor.getAll(), agent.getComputer());
});
}
@Issue("JENKINS-55257")
@Test
public void remoteConsoleNote() throws Exception {
void remoteConsoleNote() throws Throwable {
session.then(j -> {
Slave agent = j.createOnlineSlave();
FreeStyleProject project = j.createFreeStyleProject();
project.setAssignedLabel(agent.getSelfLabel());
@ -131,6 +138,7 @@ public class OldRemotingAgentTest {
ConsoleNote.INSECURE = insecureOriginal;
}
assertThat(sw.toString(), containsString("@@@ANNOTATED@@@"));
});
}
private static final class RemoteConsoleNotePrinter extends MasterToSlaveCallable<Void, IOException> {
@ -160,7 +168,45 @@ 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 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 {
@ -173,6 +219,7 @@ public class OldRemotingAgentTest {
agentJar.getAbsolutePath()));
}
}
}
private static class NodeMonitorAssert extends NodeMonitor {

View File

@ -12,43 +12,57 @@ 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 {
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"));
@ -60,9 +74,49 @@ public class UnsupportedRemotingAgentEscapeHatchTest {
? new Shell("echo Hello")
: new BatchFile("echo 'hello'"));
j.buildAndAssertSuccess(project);
});
}
private static class JenkinsExtensionWithUnsupportedAgent 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;
}
private class JenkinsRuleWithUnsupportedAgent extends JenkinsRule {
@Override
public ComputerLauncher createComputerLauncher(EnvVars env) throws URISyntaxException, IOException {
int sz = this.jenkins.getNodes().size();
@ -78,3 +132,4 @@ public class UnsupportedRemotingAgentEscapeHatchTest {
}
}
}
}

View File

@ -3,52 +3,100 @@ 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 {
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 static class JenkinsExtensionWithUnsupportedAgent 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;
}
private class JenkinsRuleWithUnsupportedAgent extends JenkinsRule {
@Override
public ComputerLauncher createComputerLauncher(EnvVars env) throws URISyntaxException, IOException {
int sz = this.jenkins.getNodes().size();
@ -64,3 +112,4 @@ public class UnsupportedRemotingAgentTest {
}
}
}
}

View File

@ -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();
}

View File

@ -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";

View File

@ -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);
}

View File

@ -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());

View File

@ -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";
}
}
}

View File

@ -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;

View File

@ -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);
}

View File

@ -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<String> 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");