Skip to content

Commit 769d733

Browse files
committed
[test] Jetty follow-ups: Windows IT, logging, ClassRule, docs
- WindowsPathResourceIT in exist-webdav (Windows CI) - Public WindowsPathResource for cross-module test access - org.exist.jetty WARN logging in integration test log4j2 - ExistWebServer javadoc; ControllerTest @ClassRule - Remove redundant RestBinariesTest HTTP timeouts
1 parent e604435 commit 769d733

9 files changed

Lines changed: 112 additions & 7 deletions

File tree

exist-core/src/main/java/org/exist/jetty/WindowsPathResource.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
* when the URI path is {@code /D:/...}. Exploded test webapps on Windows CI hit this in
4242
* {@code WebAppContext.getWebInf()}. Remove when upstream Jetty restores safe Windows resolve.
4343
*/
44-
final class WindowsPathResource extends Resource {
44+
public final class WindowsPathResource extends Resource {
4545

4646
private final Resource delegate;
4747
private final ResourceFactory resourceFactory;
@@ -51,7 +51,7 @@ private WindowsPathResource(final Resource delegate, final ResourceFactory resou
5151
this.resourceFactory = Objects.requireNonNull(resourceFactory);
5252
}
5353

54-
static Resource wrapIfNeeded(final Resource resource, final ResourceFactory resourceFactory) {
54+
public static Resource wrapIfNeeded(final Resource resource, final ResourceFactory resourceFactory) {
5555
if (resource == null || File.separatorChar != '\\' || !(resource instanceof PathResource)) {
5656
return resource;
5757
}

exist-core/src/main/java/org/exist/test/ExistWebServer.java

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,32 @@
4242
import static org.exist.repo.AutoDeploymentTrigger.AUTODEPLOY_PROPERTY;
4343

4444
/**
45-
* Exist Jetty Web Server Rule for JUnit
45+
* JUnit {@link org.junit.rules.ExternalResource} that starts an embedded eXist Jetty server for tests.
46+
* <p>
47+
* Prefer {@link org.junit.ClassRule} over {@link org.junit.Rule} when every test method in the class
48+
* can share one server instance (see {@link org.exist.http.urlrewrite.URLRewritingTest}).
49+
* <p>
50+
* <strong>Jetty layout ({@code jettyStandaloneMode})</strong>
51+
* <ul>
52+
* <li>{@code true} (default): standalone deploy — single webapp at {@code /} via
53+
* {@code exist.jetty.standalone.webapp.dir}. The context must reach
54+
* {@link org.eclipse.jetty.server.handler.ContextHandler#isAvailable()} before HTTP clients
55+
* are used; {@link org.exist.jetty.JettyStart} blocks until it is ready.</li>
56+
* <li>{@code false}: distribution layout — {@code /exist} (main app) plus portal {@code /}.
57+
* {@code /exist} must be available; the portal may only need {@code isStarted()}.
58+
* Requires {@code exist.jetty.portal.dir} in Maven test configuration (see {@code exist-core/pom.xml}).</li>
59+
* </ul>
60+
* <p>
61+
* <strong>Common system properties</strong> (usually set in module {@code pom.xml} Surefire config):
62+
* <ul>
63+
* <li>{@code exist.jetty.standalone.webapp.dir} — exploded standalone test webapp root</li>
64+
* <li>{@code exist.jetty.portal.dir} — portal webapp for distribution-mode tests</li>
65+
* <li>{@code jetty.port}, {@code jetty.secure.port}, {@code jetty.ssl.port} — set automatically when
66+
* {@code useRandomPort} is {@code true}</li>
67+
* <li>{@code jetty.home} — Jetty configuration directory ({@code exist-jetty-config/target/classes/...})</li>
68+
* </ul>
69+
* Startup failures throw {@link IllegalStateException} with detail from {@link org.exist.jetty.JettyStart}
70+
* (also printed to {@code System.err} when test log4j root is OFF).
4671
*/
4772
public class ExistWebServer extends ExternalResource {
4873

exist-core/src/test/java/org/exist/http/urlrewrite/ControllerTest.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
import org.apache.http.entity.ContentType;
3131
import org.exist.http.AbstractHttpTest;
3232
import org.exist.test.ExistWebServer;
33-
import org.junit.Rule;
33+
import org.junit.ClassRule;
3434
import org.junit.Test;
3535

3636
import java.io.IOException;
@@ -50,8 +50,8 @@ public class ControllerTest extends AbstractHttpTest {
5050
private static final String LEGACY_CONTROLLER_XQUERY = "<controller>xql</controller>";
5151
private static final String TEST_DOCUMENT_NAME = "test.xml";
5252

53-
@Rule
54-
public final ExistWebServer existWebServer = new ExistWebServer(true, false, true, true, false);
53+
@ClassRule
54+
public static final ExistWebServer existWebServer = new ExistWebServer(true, false, true, true, false);
5555

5656
@Test
5757
public void findsLegacyController() throws IOException {

exist-core/src/test/resources/log4j2.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
</Console>
3030
</Appenders>
3131
<Loggers>
32+
<Logger name="org.exist.jetty" level="WARN"/>
3233
<Root level="OFF">
3334
<AppenderRef ref="Console"/>
3435
</Root>

extensions/exquery/restxq/src/test/resources/log4j2.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
</Console>
77
</Appenders>
88
<Loggers>
9+
<Logger name="org.exist.jetty" level="WARN"/>
910
<Root level="OFF">
1011
<AppenderRef ref="Console"/>
1112
</Root>

extensions/modules/file/src/test/java/org/exist/xquery/modules/file/RestBinariesTest.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,6 @@ private HttpResponse postXquery(final String xquery) throws JAXBException, IOExc
171171
try(final UnsynchronizedByteArrayOutputStream baos = UnsynchronizedByteArrayOutputStream.builder().get()) {
172172
marshaller.marshal(query, baos);
173173
response = executor.execute(Request.Post(getRestUrl() + "/db/")
174-
.connectTimeout(10000).socketTimeout(10000)
175174
.bodyByteArray(baos.toByteArray(), ContentType.APPLICATION_XML)
176175
).returnResponse();
177176
}

extensions/modules/file/src/test/resources/log4j2.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
</Console>
3030
</Appenders>
3131
<Loggers>
32+
<Logger name="org.exist.jetty" level="WARN"/>
3233
<Root level="OFF">
3334
<AppenderRef ref="Console"/>
3435
</Root>
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/*
2+
* eXist-db Open Source Native XML Database
3+
* Copyright (C) 2001 The eXist-db Authors
4+
*
5+
* info@exist-db.org
6+
* http://www.exist-db.org
7+
*
8+
* This library is free software; you can redistribute it and/or
9+
* modify it under the terms of the GNU Lesser General Public
10+
* License as published by the Free Software Foundation; either
11+
* version 2.1 of the License, or (at your option) any later version.
12+
*
13+
* This library is distributed in the hope that it will be useful,
14+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16+
* Lesser General Public License for more details.
17+
*
18+
* You should have received a copy of the GNU Lesser General Public
19+
* License along with this library; if not, write to the Free Software
20+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21+
*/
22+
package org.exist.jetty;
23+
24+
import org.eclipse.jetty.util.resource.PathResource;
25+
import org.eclipse.jetty.util.resource.Resource;
26+
import org.eclipse.jetty.util.resource.ResourceFactory;
27+
import org.junit.Test;
28+
29+
import java.io.File;
30+
import java.nio.file.Files;
31+
import java.nio.file.InvalidPathException;
32+
import java.nio.file.Path;
33+
34+
import static org.junit.Assert.assertNotSame;
35+
import static org.junit.Assert.assertTrue;
36+
import static org.junit.Assume.assumeTrue;
37+
38+
/**
39+
* Windows integration regression test for Jetty 12.1 {@link PathResource#resolve(String)} on
40+
* drive URIs ({@code /D:/...}). Lives in {@code exist-webdav} so it runs on Windows CI
41+
* ({@code verify -DskipUnitTests=true}).
42+
*/
43+
public class WindowsPathResourceIT {
44+
45+
@Test
46+
public void resolveWebInfOnWindowsDriveUri() throws Exception {
47+
assumeTrue("Windows-only PathResource URI regression", File.separatorChar == '\\');
48+
49+
final ResourceFactory resourceFactory = ResourceFactory.root();
50+
final Path webapp = Files.createTempDirectory("webapp");
51+
Files.createDirectory(webapp.resolve("WEB-INF"));
52+
try {
53+
final Resource resource = resourceFactory.newResource(webapp);
54+
assumeTrue("Expected PathResource for local webapp directory", resource instanceof PathResource);
55+
final String uriPath = resource.getURI().getPath();
56+
assumeTrue("Expected absolute Windows drive URI path, got: " + uriPath,
57+
uriPath != null && uriPath.matches("/[A-Za-z]:/.*"));
58+
59+
final PathResource pathResource = (PathResource) resource;
60+
try {
61+
pathResource.resolve("WEB-INF/");
62+
// Jetty version may already fix resolve; wrapped path must still work.
63+
} catch (final InvalidPathException e) {
64+
// Expected on Jetty 12.1.x with /X:/... URI paths.
65+
}
66+
67+
final Resource wrapped = WindowsPathResource.wrapIfNeeded(pathResource, resourceFactory);
68+
assertNotSame(pathResource, wrapped);
69+
70+
final Resource webInf = wrapped.resolve("WEB-INF/");
71+
assertTrue("WEB-INF should resolve to a directory", webInf.isDirectory());
72+
} finally {
73+
Files.deleteIfExists(webapp.resolve("WEB-INF"));
74+
Files.deleteIfExists(webapp);
75+
}
76+
}
77+
}

extensions/webdav/src/test/resources/log4j2.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
</Console>
3030
</Appenders>
3131
<Loggers>
32+
<Logger name="org.exist.jetty" level="WARN"/>
3233
<Root level="OFF">
3334
<AppenderRef ref="Console"/>
3435
</Root>

0 commit comments

Comments
 (0)