Skip to content

Commit

Permalink
Gradle: Support for additional test-to-main directory mappings
Browse files Browse the repository at this point in the history
* Determine test output directory based on the task
* Raise an exception if the mapping data is invalid.
* Include a functional-test for verifying the plugin behavior
  • Loading branch information
roguexz committed Sep 28, 2020
1 parent 64d4587 commit 48fa25b
Show file tree
Hide file tree
Showing 11 changed files with 182 additions and 11 deletions.
6 changes: 3 additions & 3 deletions devtools/gradle/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,9 @@ javadoc {
}

pluginBundle {
website = 'https://quarkus.io/'
vcsUrl = 'https://github.com/quarkusio/quarkus'
tags = ['quarkus', 'quarkusio', 'graalvm']
website = 'https://quarkus.io/'
vcsUrl = 'https://github.com/quarkusio/quarkus'
tags = ['quarkus', 'quarkusio', 'graalvm']
}

gradlePlugin {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

import org.gradle.api.Project;
import org.gradle.api.file.FileCollection;
Expand All @@ -14,6 +16,7 @@
import org.gradle.api.plugins.JavaPluginConvention;
import org.gradle.api.provider.Provider;
import org.gradle.api.tasks.SourceSet;
import org.gradle.api.tasks.SourceSetContainer;
import org.gradle.api.tasks.testing.Test;
import org.gradle.jvm.tasks.Jar;

Expand Down Expand Up @@ -55,6 +58,20 @@ void beforeTest(Test task) {
final Path serializedModel = QuarkusGradleUtils.serializeAppModel(appModel, task);
props.put(BootstrapConstants.SERIALIZED_APP_MODEL, serializedModel.toString());

// Identify the folder containing the sources associated with this test task
String fileList = getSourceSets().stream()
.filter(sourceSet -> Objects.equals(
task.getTestClassesDirs().getAsPath(),
sourceSet.getOutput().getClassesDirs().getAsPath()))
.flatMap(sourceSet -> sourceSet.getOutput().getClassesDirs().getFiles().stream())
.filter(File::exists)
.distinct()
.map(testSrcDir -> String.format("%s:%s",
project.relativePath(testSrcDir),
project.relativePath(outputDirectory())))
.collect(Collectors.joining(","));
task.environment(BootstrapConstants.TEST_TO_MAIN_MAPPINGS, fileList);

final String nativeRunner = task.getProject().getBuildDir().toPath().resolve(finalName() + "-runner")
.toAbsolutePath()
.toString();
Expand Down Expand Up @@ -96,8 +113,8 @@ public Path appJarOrClasses() {

public File outputDirectory() {
if (outputDirectory == null) {
outputDirectory = getLastFile(project.getConvention().getPlugin(JavaPluginConvention.class)
.getSourceSets().getByName(SourceSet.MAIN_SOURCE_SET_NAME).getOutput().getClassesDirs());
outputDirectory = getLastFile(getSourceSets().getByName(SourceSet.MAIN_SOURCE_SET_NAME).getOutput()
.getClassesDirs());
}
return outputDirectory;
}
Expand All @@ -108,8 +125,8 @@ public void setOutputDirectory(String outputDirectory) {

public File outputConfigDirectory() {
if (outputConfigDirectory == null) {
outputConfigDirectory = project.getConvention().getPlugin(JavaPluginConvention.class)
.getSourceSets().getByName(SourceSet.MAIN_SOURCE_SET_NAME).getOutput().getResourcesDir();
outputConfigDirectory = getSourceSets().getByName(SourceSet.MAIN_SOURCE_SET_NAME).getOutput()
.getResourcesDir();
}
return outputConfigDirectory;
}
Expand All @@ -120,8 +137,8 @@ public void setOutputConfigDirectory(String outputConfigDirectory) {

public File sourceDir() {
if (sourceDir == null) {
sourceDir = getLastFile(project.getConvention().getPlugin(JavaPluginConvention.class)
.getSourceSets().getByName(SourceSet.MAIN_SOURCE_SET_NAME).getAllJava().getSourceDirectories());
sourceDir = getLastFile(getSourceSets().getByName(SourceSet.MAIN_SOURCE_SET_NAME).getAllJava()
.getSourceDirectories());
}
return sourceDir;
}
Expand Down Expand Up @@ -153,8 +170,7 @@ public void setFinalName(String finalName) {
}

public Set<File> resourcesDir() {
return project.getConvention().getPlugin(JavaPluginConvention.class)
.getSourceSets().getByName(SourceSet.MAIN_SOURCE_SET_NAME).getResources().getSrcDirs();
return getSourceSets().getByName(SourceSet.MAIN_SOURCE_SET_NAME).getResources().getSrcDirs();
}

public AppArtifact getAppArtifact() {
Expand Down Expand Up @@ -199,4 +215,13 @@ private File getLastFile(FileCollection fileCollection) {
return result;
}

/**
* Convenience method to get the source sets associated with the current project.
*
* @return the source sets associated with the current project.
*/
private SourceSetContainer getSourceSets() {
return project.getConvention().getPlugin(JavaPluginConvention.class).getSourceSets();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ public interface BootstrapConstants {
String SERIALIZED_APP_MODEL = "quarkus-internal.serialized-app-model.path";
String DESCRIPTOR_FILE_NAME = "quarkus-extension.properties";

/**
* Constant for sharing the additional mappings between test-sources and the corresponding application-sources.
* The Gradle plugin populates this data which is then read by the PathTestHelper when executing tests.
*/
String TEST_TO_MAIN_MAPPINGS = "TEST_TO_MAIN_MAPPINGS";

@Deprecated
String EXTENSION_PROPS_JSON_FILE_NAME = "quarkus-extension.json";

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package io.quarkus.gradle;

import static org.junit.jupiter.api.Assertions.assertEquals;

import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;

import org.junit.jupiter.api.Test;

/**
* Test for verifying that the plugin can work with test-sources which are included as part of a custom source set.
* E.g., functional-tests / integration-tests.
*/
public class AdditionalSourceSetsTest extends QuarkusGradleWrapperTestBase {

@Test
public void executeFunctionalTest() throws URISyntaxException, IOException, InterruptedException {
final File projectDir = getProjectDir("additional-source-sets");
BuildResult result = runGradleWrapper(projectDir, "functionalTest");
assertEquals(BuildResult.SUCCESS_OUTCOME, result.getTasks().get(":functionalTest"),
"Failed to run tests defined in an alternate test sources directory");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
plugins {
id 'java'
id 'io.quarkus'
}

repositories {
mavenLocal()
mavenCentral()
}

dependencies {
implementation enforcedPlatform("${quarkusPlatformGroupId}:${quarkusPlatformArtifactId}:${quarkusPlatformVersion}")
implementation "io.quarkus:quarkus-arc"
testImplementation "io.quarkus:quarkus-junit5"
}

sourceSets {
// Functional Tests
funcTest {
java.srcDir 'src/funcTest/java'
if (file('src/funcTest/resources').exists()) {
resources.srcDir 'src/funcTest/resources'
}

compileClasspath += sourceSets.main.output + configurations.testRuntimeClasspath + configurations.compileOnly
runtimeClasspath += output + compileClasspath
}
}

compileJava {
options.compilerArgs << '-parameters'
}

/*
* Functional tests for this module.
*/
task functionalTest(type: Test, description: 'Functional tests', dependsOn: [processResources, classes]) {
description = 'Run the functional tests.'
group = 'verification'

useJUnitPlatform()
testClassesDirs = sourceSets.funcTest.output.classesDirs
classpath = sourceSets.funcTest.runtimeClasspath

// Show standard streams on the console.
testLogging {
showStandardStreams = true
}
systemProperty 'quarkus.http.host', 'localhost'
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
quarkusPlatformArtifactId=quarkus-bom
quarkusPlatformGroupId=io.quarkus
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
pluginManagement {
repositories {
mavenLocal()
mavenCentral()
gradlePluginPortal()
}
plugins {
id 'io.quarkus' version "${quarkusPluginVersion}"
}
}

rootProject.name = 'additional-test-sources'
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package ft;

import javax.inject.Inject;
import org.junit.jupiter.api.Test;
import io.quarkus.test.junit.QuarkusTest;

import static org.junit.jupiter.api.Assertions.assertEquals;

@QuarkusTest
public class SimpleBeanTest {

@Inject
SimpleBean bean;

@Test
public void verify() {
assertEquals("hello", bean.hello(), "Did the implementation of the SimpleBean change?");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package ft;

import javax.enterprise.context.ApplicationScoped;

@ApplicationScoped
public class SimpleBean {

public String hello() {
return "hello";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_2_0.xsd"
bean-discovery-mode="all">
</beans>
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Stream;

import io.quarkus.bootstrap.BootstrapConstants;
import io.quarkus.runtime.util.ClassPathUtils;

/**
Expand Down Expand Up @@ -99,6 +101,20 @@ public final class PathTestHelper {
File.separator + "test-classes",
File.separator + "classes");
//endregion

String mappings = System.getenv(BootstrapConstants.TEST_TO_MAIN_MAPPINGS);
if (mappings != null) {
Stream.of(mappings.split(","))
.filter(s -> !s.isEmpty())
.forEach(s -> {
String[] entry = s.split(":");
if (entry.length == 2) {
TEST_TO_MAIN_DIR_FRAGMENTS.put(entry[0], entry[1]);
} else {
throw new IllegalStateException("Unable to parse additional test-to-main mapping: " + s);
}
});
}
}

private PathTestHelper() {
Expand Down

0 comments on commit 48fa25b

Please sign in to comment.