Skip to content

Commit bc1d7f3

Browse files
Add unit test for PathTestHelper and test which makes sure tests in jars can be executed
Co-authored-by: Alexey Loubyanksy <[email protected]>
1 parent 4ab38c0 commit bc1d7f3

File tree

10 files changed

+378
-7
lines changed

10 files changed

+378
-7
lines changed
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package io.quarkus.maven.it;
2+
3+
import static org.assertj.core.api.Assertions.assertThat;
4+
5+
import java.io.File;
6+
import java.util.List;
7+
import java.util.Map;
8+
9+
import org.junit.jupiter.api.Test;
10+
11+
import io.quarkus.maven.it.verifier.MavenProcessInvocationResult;
12+
import io.quarkus.maven.it.verifier.RunningInvoker;
13+
14+
/**
15+
* Tests to ensure Quarkus tests behave well with mvn verify
16+
*/
17+
@DisableForNative
18+
class VerifyIT extends MojoTestBase {
19+
20+
private RunningInvoker running;
21+
private File testDir;
22+
23+
@Test
24+
void testTestsInJar() throws Exception {
25+
{
26+
// Prepare the jar containing the tests
27+
File packagerDir = initProject("projects/tests-in-jar-packager", "projects/tests-in-jar-packager-processed");
28+
RunningInvoker packagerInvoker = new RunningInvoker(packagerDir, false);
29+
// We can't run the tests at this stage, since there's no application for them to run against
30+
MavenProcessInvocationResult result = packagerInvoker
31+
.execute(List.of("clean", "install", "-DskipTests"), Map.of());
32+
assertThat(result.getProcess()
33+
.waitFor()).isZero();
34+
}
35+
36+
testDir = initProject("projects/tests-in-jar", "projects/tests-in-jar-processed");
37+
running = new RunningInvoker(testDir, false);
38+
39+
MavenProcessInvocationResult result = running
40+
.execute(List.of("clean", "verify"), Map.of());
41+
assertThat(result.getProcess().waitFor()).isZero();
42+
// Hardcode a check to make sure some tests ran
43+
String log = running.log();
44+
assertThat(log).contains("[INFO] Running org.acme.HelloResourceFromJarTest");
45+
assertThat(log).contains("[INFO] Running org.acme.ThirdpartyResourceFromJarTest");
46+
assertThat(log).contains("Tests run: 2, Failures: 0, Errors: 0, Skipped: 0");
47+
}
48+
49+
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
<?xml version="1.0"?>
2+
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
4+
<modelVersion>4.0.0</modelVersion>
5+
<groupId>org.acme</groupId>
6+
<artifactId>independent-tests</artifactId>
7+
<version>1.0-SNAPSHOT</version>
8+
<properties>
9+
<quarkus.platform.group-id>io.quarkus</quarkus.platform.group-id>
10+
<quarkus.platform.artifact-id>quarkus-bom</quarkus.platform.artifact-id>
11+
<quarkus.platform.version>@project.version@</quarkus.platform.version>
12+
<compiler-plugin.version>${compiler-plugin.version}</compiler-plugin.version>
13+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
14+
<maven.compiler.source>${maven.compiler.source}</maven.compiler.source>
15+
<maven.compiler.target>${maven.compiler.target}</maven.compiler.target>
16+
<version.surefire.plugin>${version.surefire.plugin}</version.surefire.plugin>
17+
</properties>
18+
19+
<dependencyManagement>
20+
<dependencies>
21+
<!-- insert managed dependencies here -->
22+
<dependency>
23+
<groupId>\${quarkus.platform.group-id}</groupId>
24+
<artifactId>\${quarkus.platform.artifact-id}</artifactId>
25+
<version>\${quarkus.platform.version}</version>
26+
<type>pom</type>
27+
<scope>import</scope>
28+
</dependency>
29+
</dependencies>
30+
</dependencyManagement>
31+
<dependencies>
32+
<!-- this is to compile the ThirdpartyResource -->
33+
<dependency>
34+
<groupId>io.quarkus</groupId>
35+
<artifactId>quarkus-rest</artifactId>
36+
</dependency>
37+
<!-- insert test dependencies here -->
38+
<dependency>
39+
<groupId>io.quarkus</groupId>
40+
<artifactId>quarkus-junit5</artifactId>
41+
<scope>test</scope>
42+
</dependency>
43+
<dependency>
44+
<groupId>io.rest-assured</groupId>
45+
<artifactId>rest-assured</artifactId>
46+
<scope>test</scope>
47+
</dependency>
48+
</dependencies>
49+
<build>
50+
<plugins>
51+
<plugin>
52+
<artifactId>maven-compiler-plugin</artifactId>
53+
<version>\${compiler-plugin.version}</version>
54+
</plugin>
55+
<plugin>
56+
<artifactId>maven-jar-plugin</artifactId>
57+
<version>${version.jar.plugin}</version>
58+
<executions>
59+
<execution>
60+
<goals>
61+
<goal>test-jar</goal>
62+
</goals>
63+
</execution>
64+
</executions>
65+
</plugin>
66+
</plugins>
67+
</build>
68+
69+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package org.acme;
2+
3+
import jakarta.ws.rs.GET;
4+
import jakarta.ws.rs.Path;
5+
import jakarta.ws.rs.Produces;
6+
import jakarta.ws.rs.core.MediaType;
7+
8+
@Path("/thirdparty")
9+
public class ThirdpartyResource {
10+
11+
@GET
12+
@Produces(MediaType.TEXT_PLAIN)
13+
public String hello() {
14+
return "Hello from thirdparty";
15+
}
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package org.acme;
2+
3+
import static io.restassured.RestAssured.given;
4+
import static org.hamcrest.CoreMatchers.is;
5+
6+
import org.junit.jupiter.api.Test;
7+
8+
import io.quarkus.test.junit.QuarkusTest;
9+
10+
@QuarkusTest
11+
public class HelloResourceFromJarTest {
12+
13+
@Test
14+
public void testHelloEndpoint() {
15+
given()
16+
.when().get("/hello")
17+
.then()
18+
.statusCode(200)
19+
.body(is("hello jar friends"));
20+
}
21+
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package org.acme;
2+
3+
import static io.restassured.RestAssured.given;
4+
import static org.hamcrest.CoreMatchers.is;
5+
6+
import org.junit.jupiter.api.Test;
7+
8+
import io.quarkus.test.junit.QuarkusTest;
9+
10+
@QuarkusTest
11+
public class ThirdpartyResourceFromJarTest {
12+
13+
@Test
14+
public void testHelloEndpoint() {
15+
given()
16+
.when().get("/thirdparty")
17+
.then()
18+
.statusCode(200)
19+
.body(is("Hello from thirdparty"));
20+
}
21+
22+
}
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
<?xml version="1.0"?>
2+
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
4+
<modelVersion>4.0.0</modelVersion>
5+
<groupId>org.acme</groupId>
6+
<artifactId>acme-tests-in-jar</artifactId>
7+
<version>1.0-SNAPSHOT</version>
8+
<properties>
9+
<quarkus.platform.group-id>io.quarkus</quarkus.platform.group-id>
10+
<quarkus.platform.artifact-id>quarkus-bom</quarkus.platform.artifact-id>
11+
<quarkus.platform.version>@project.version@</quarkus.platform.version>
12+
<quarkus-plugin.version>@project.version@</quarkus-plugin.version>
13+
<compiler-plugin.version>${compiler-plugin.version}</compiler-plugin.version>
14+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
15+
<maven.compiler.source>${maven.compiler.source}</maven.compiler.source>
16+
<maven.compiler.target>${maven.compiler.target}</maven.compiler.target>
17+
<version.surefire.plugin>${version.surefire.plugin}</version.surefire.plugin>
18+
</properties>
19+
20+
<dependencyManagement>
21+
<dependencies>
22+
<!-- insert managed dependencies here -->
23+
<dependency>
24+
<groupId>\${quarkus.platform.group-id}</groupId>
25+
<artifactId>\${quarkus.platform.artifact-id}</artifactId>
26+
<version>\${quarkus.platform.version}</version>
27+
<type>pom</type>
28+
<scope>import</scope>
29+
</dependency>
30+
</dependencies>
31+
</dependencyManagement>
32+
<dependencies>
33+
<!-- insert test dependencies here -->
34+
<!-- This dependency hold the tests for this project -->
35+
<dependency>
36+
<groupId>org.acme</groupId>
37+
<artifactId>independent-tests</artifactId>
38+
<version>1.0-SNAPSHOT</version>
39+
<type>test-jar</type>
40+
<scope>test</scope>
41+
</dependency>
42+
<!-- This dependency includes the ThirdpartyResource tested by tests included in the above dependency.
43+
This is how the Quarkus platform testsuite is setup -->
44+
<dependency>
45+
<groupId>org.acme</groupId>
46+
<artifactId>independent-tests</artifactId>
47+
<version>1.0-SNAPSHOT</version>
48+
<scope>test</scope>
49+
</dependency>
50+
<dependency>
51+
<groupId>io.quarkus</groupId>
52+
<artifactId>quarkus-junit5</artifactId>
53+
<scope>test</scope>
54+
</dependency>
55+
<dependency>
56+
<groupId>io.rest-assured</groupId>
57+
<artifactId>rest-assured</artifactId>
58+
<scope>test</scope>
59+
</dependency>
60+
<dependency>
61+
<groupId>io.quarkus</groupId>
62+
<artifactId>quarkus-rest</artifactId>
63+
</dependency>
64+
</dependencies>
65+
<build>
66+
<plugins>
67+
<plugin>
68+
<artifactId>maven-compiler-plugin</artifactId>
69+
<version>\${compiler-plugin.version}</version>
70+
</plugin>
71+
<plugin>
72+
<groupId>io.quarkus</groupId>
73+
<artifactId>quarkus-maven-plugin</artifactId>
74+
<version>\${quarkus-plugin.version}</version>
75+
<executions>
76+
<execution>
77+
<goals>
78+
<goal>build</goal>
79+
</goals>
80+
</execution>
81+
</executions>
82+
</plugin>
83+
<!-- Tell maven to run the tests in the jar -->
84+
<plugin>
85+
<groupId>org.apache.maven.plugins</groupId>
86+
<artifactId>maven-surefire-plugin</artifactId>
87+
<version>\${version.surefire.plugin}</version>
88+
<configuration>
89+
<dependenciesToScan>
90+
<dependency>org.acme:independent-tests</dependency>
91+
</dependenciesToScan>
92+
<systemPropertyVariables>
93+
<java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
94+
<maven.home>\${maven.home}</maven.home>
95+
</systemPropertyVariables>
96+
</configuration>
97+
</plugin>
98+
</plugins>
99+
</build>
100+
<profiles>
101+
<profile>
102+
<id>native</id>
103+
<properties>
104+
<quarkus.native.enabled>true</quarkus.native.enabled>
105+
</properties>
106+
</profile>
107+
<profile>
108+
<id>customOutputDir</id>
109+
<build>
110+
<directory>target-other</directory>
111+
</build>
112+
</profile>
113+
</profiles>
114+
</project>
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package org.acme;
2+
3+
import jakarta.ws.rs.GET;
4+
import jakarta.ws.rs.Path;
5+
import jakarta.ws.rs.Produces;
6+
import jakarta.ws.rs.core.MediaType;
7+
8+
@Path("/hello")
9+
public class HelloResource {
10+
11+
@GET
12+
@Produces(MediaType.TEXT_PLAIN)
13+
public String greeting() {
14+
return "hello jar friends";
15+
}
16+
17+
}

test-framework/common/src/main/java/io/quarkus/test/common/PathTestHelper.java

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,15 @@
88
import java.net.URL;
99
import java.nio.file.Files;
1010
import java.nio.file.Path;
11-
import java.nio.file.Paths;
1211
import java.util.HashMap;
12+
import java.util.List;
1313
import java.util.Map;
1414
import java.util.Optional;
1515
import java.util.stream.Stream;
1616

1717
import io.quarkus.bootstrap.BootstrapConstants;
1818
import io.quarkus.bootstrap.app.CuratedApplication;
19+
import io.quarkus.bootstrap.classloading.ClassPathElement;
1920
import io.quarkus.bootstrap.classloading.QuarkusClassLoader;
2021
import io.quarkus.bootstrap.workspace.ArtifactSources;
2122
import io.quarkus.bootstrap.workspace.SourceDir;
@@ -247,7 +248,7 @@ public static Path getAppClassLocationForTestLocation(Path testClassLocationPath
247248

248249
if (testClassLocation.endsWith(".jar")) {
249250
if (testClassLocation.endsWith("-tests.jar")) {
250-
return Paths.get(new StringBuilder()
251+
return Path.of(new StringBuilder()
251252
.append(testClassLocation, 0, testClassLocation.length() - "-tests.jar".length())
252253
.append(".jar")
253254
.toString());
@@ -323,6 +324,25 @@ public static Path getResourcesForClassesDirOrNull(Path classesDir, String name)
323324
}
324325

325326
public static boolean isTestClass(String className, ClassLoader classLoader, Path testLocation) {
327+
if (classLoader instanceof QuarkusClassLoader qcl) {
328+
// this appears to be a more efficient and reliable way of performing this check
329+
// the code after this IF block has an issue on Windows
330+
final List<ClassPathElement> cpeList = qcl.getElementsWithResource(fromClassNameToResourceName(className),
331+
false);
332+
if (!cpeList.isEmpty()) {
333+
// if it's not empty, it's pretty much always a list with a single element
334+
if (cpeList.size() == 1) {
335+
final ClassPathElement cpe = cpeList.get(0);
336+
return cpe.isRuntime() && testLocation.equals(cpe.getRoot());
337+
}
338+
for (ClassPathElement cpe : cpeList) {
339+
if (cpe.isRuntime()) {
340+
return cpe.getRoot().equals(testLocation);
341+
}
342+
}
343+
}
344+
return false;
345+
}
326346
URL resource = classLoader.getResource(fromClassNameToResourceName(className));
327347
if (resource == null) {
328348
return false;

0 commit comments

Comments
 (0)