Skip to content

Commit

Permalink
Add support for custom prefix
Browse files Browse the repository at this point in the history
Fixes #917
  • Loading branch information
Vlatombe committed Feb 20, 2025
1 parent 256947e commit ca99b6f
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 4 deletions.
42 changes: 39 additions & 3 deletions src/main/java/org/jvnet/hudson/test/RealJenkinsRule.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import hudson.Extension;
import hudson.ExtensionList;
import hudson.Util;
import hudson.model.UnprotectedRootAction;
import hudson.security.ACL;
import hudson.security.ACLContext;
Expand Down Expand Up @@ -243,6 +244,8 @@ public final class RealJenkinsRule implements TestRule {
private SSLSocketFactory sslSocketFactory;
private X509Certificate rootCA;

private String prefix = "/jenkins";

public RealJenkinsRule() {
home = new AtomicReference<>();
}
Expand Down Expand Up @@ -390,6 +393,37 @@ public RealJenkinsRule withHost(String host) {
return this;
}

/**
* Removes the prefix from the Jenkins root URL.
* @see #withPrefix(String)
*/
public RealJenkinsRule noPrefix() {
this.prefix = null;
return this;
}

/**
* Sets a custom prefix for the Jenkins root URL.
* <p>
* By default, the prefix defaults to {@code /jenkins}.
* <p>
* Use {@link #noPrefix()} to remove the prefix, or provide another prefix of your choice as long as it starts with / and doesn't end with /.
*/
public RealJenkinsRule withPrefix(@NonNull String prefix) {
var sanitized = Util.fixEmpty(prefix);
if (sanitized == null) {
throw new IllegalStateException("Use noPrefix() to remove the prefix.");
}
if (!sanitized.startsWith("/")) {
throw new IllegalStateException("Prefix must start with a leading slash.");
}
if (sanitized.endsWith("/")) {
throw new IllegalStateException("Prefix must not end with a trailing slash.");
}
this.prefix = sanitized;
return this;
}

/**
* Sets a custom WAR file to be used by the rule instead of the one in the path or {@code war/target/jenkins.war} in case of core.
*/
Expand Down Expand Up @@ -825,7 +859,7 @@ public URL getUrl() throws MalformedURLException {
if (port == 0) {
throw new IllegalStateException("This method must be called after calling #startJenkins.");
}
return new URL(https ? "https" : "http", host, port, "/jenkins/");
return new URL(https ? "https" : "http", host, port, prefix == null ? "" : prefix + "/");
}

/**
Expand Down Expand Up @@ -1008,8 +1042,10 @@ public void startJenkins() throws Throwable {
argv.addAll(List.of(
"-jar", war.getAbsolutePath(),
"--enable-future-java",
"--httpListenAddress=" + httpListenAddress,
"--prefix=/jenkins"));
"--httpListenAddress=" + httpListenAddress));
if (prefix != null) {
argv.add("--prefix=" + prefix);
}
argv.addAll(getPortOptions());
if (https) {
argv.add("--httpsKeyStore=" + keyStoreManager.getPath().toAbsolutePath());
Expand Down
14 changes: 13 additions & 1 deletion src/test/java/org/jvnet/hudson/test/RealJenkinsRuleTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.arrayContainingInAnyOrder;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.emptyString;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.is;
Expand All @@ -36,6 +38,7 @@
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
Expand Down Expand Up @@ -75,7 +78,6 @@
import javax.servlet.ServletResponse;
import jenkins.model.Jenkins;
import jenkins.model.JenkinsLocationConfiguration;
import static org.junit.Assume.assumeThat;
import org.junit.AssumptionViolatedException;
import org.junit.Ignore;
import org.junit.Rule;
Expand Down Expand Up @@ -103,6 +105,16 @@ private static void _smokes(JenkinsRule r) throws Throwable {
assertEquals(rr.getUrl().toExternalForm(), rr.runRemotely(RealJenkinsRuleTest::_getJenkinsUrlFromRemote));
}

@Test public void customPrefix() throws Throwable {
rr.withPrefix("/foo").startJenkins();
assertThat(rr.getUrl().getPath(), equalTo("/foo/"));
}

@Test public void noPrefix() throws Throwable {
rr.noPrefix().startJenkins();
assertThat(rr.getUrl().getPath(), emptyString());
}

@Test public void ipv6() throws Throwable {
// Use -Djava.net.preferIPv6Addresses=true if dualstack
assumeThat(InetAddress.getLoopbackAddress(), instanceOf(Inet6Address.class));
Expand Down

0 comments on commit ca99b6f

Please sign in to comment.