Skip to content

Commit

Permalink
start updating tests to run against exact simulated classpath
Browse files Browse the repository at this point in the history
  • Loading branch information
sigpwned committed Jan 7, 2025
1 parent 77e6ff7 commit a36dfa9
Show file tree
Hide file tree
Showing 5 changed files with 146 additions and 17 deletions.
49 changes: 42 additions & 7 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,13 @@
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<maven.compiler.release>11</maven.compiler.release>

<!-- These versions are injected into tests, so all attempts to -->
<!-- control versions of these dependencies must be done here. -->
<dagger.version>2.54</dagger.version>
<javax.inject.version>1</javax.inject.version>
<jakarta.inject-api.version>2.0.1</jakarta.inject-api.version>
<jsr305.version>3.0.2</jsr305.version>
</properties>

<build>
Expand All @@ -63,16 +69,29 @@
<artifactId>maven-surefire-plugin</artifactId>
<version>3.5.2</version>
<configuration>
<!-- The below is required for testing annotation processors -->
<!-- The below is required for testing annotation
processors -->
<!-- using com.google.testing.compile:compile-testing. -->
<argLine>
--add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED
--add-opens jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED
--add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED
--add-opens jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED
--add-exports jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED
--add-opens jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED
--add-exports
jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED
--add-opens
jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED
--add-exports
jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED
--add-opens
jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED
--add-exports
jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED
--add-opens
jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED
</argLine>
<systemPropertyVariables>
<dagger.version>${dagger.version}</dagger.version>
<javax.inject.version>${javax.inject.version}</javax.inject.version>
<jakarta.inject-api.version>${jakarta.inject-api.version}</jakarta.inject-api.version>
<jsr305.version>${jsr305.version}</jsr305.version>
</systemPropertyVariables>
</configuration>
</plugin>
<plugin>
Expand Down Expand Up @@ -205,6 +224,22 @@
<artifactId>dagger-compiler</artifactId>
<version>${dagger.version}</version>
</dependency>
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>${javax.inject.version}</version>
</dependency>
<dependency>
<groupId>jakarta.inject</groupId>
<artifactId>jakarta.inject-api</artifactId>
<version>${jakarta.inject-api.version}</version>
</dependency>
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
<version>${jsr305.version}</version>
</dependency>

<dependency>
<groupId>com.google.testing.compile</groupId>
<artifactId>compile-testing</artifactId>
Expand Down
6 changes: 4 additions & 2 deletions rapier-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,14 @@
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
<dependency>
<groupId>jakarta.inject</groupId>
<artifactId>jakarta.inject-api</artifactId>
<version>2.0.1</version>
</dependency>
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
</dependency>
<dependency>
<groupId>com.google.dagger</groupId>
Expand Down
66 changes: 60 additions & 6 deletions rapier-core/src/test/java/rapier/core/DaggerTestBase.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
*/
package rapier.core;

import static java.util.stream.Collectors.joining;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
Expand All @@ -34,6 +35,7 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
Expand All @@ -43,8 +45,7 @@
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;


import rapier.core.util.Maven;

public abstract class DaggerTestBase {
@SuppressWarnings("serial")
Expand Down Expand Up @@ -122,8 +123,12 @@ protected String compileAndRunSourceCode(List<String> compilationUnitSourceCodes

try {
// Dynamically load the compiled classes
try (URLClassLoader classLoader = new URLClassLoader(new URL[] {tempDir.toURI().toURL()},
Thread.currentThread().getContextClassLoader())) {
final List<URL> classpath = new ArrayList<>();
for (File simulationClasspathEntry : simulationClasspath())
classpath.add(simulationClasspathEntry.toURI().toURL());
classpath.add(tempDir.toURI().toURL());
try (URLClassLoader classLoader = new URLClassLoader(classpath.toArray(URL[]::new),
ClassLoader.getPlatformClassLoader())) {

final Class<?> mainClass = classLoader.loadClass(mainCompilationUnitName);

Expand Down Expand Up @@ -200,6 +205,7 @@ private String compileSourceCode(File tempDir, List<String> compilationUnitSourc
"JavaCompiler not available. Make sure JDK is used instead of JRE.");
}

// Write the source files to disk
final List<File> sourceFiles = new ArrayList<>();
for (final String compilationUnitSourceCode : compilationUnitSourceCodes) {
final Matcher classNameMatcher =
Expand All @@ -219,9 +225,13 @@ private String compileSourceCode(File tempDir, List<String> compilationUnitSourc
// Set up diagnostic collector to capture compilation errors
DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<>();

// Set up our classpath
final String classpath = simulationClasspath().stream().map(File::getAbsolutePath)
.collect(joining(File.pathSeparator));

// Configure annotation processors (include Dagger's processor)
List<String> options = List.of("-processor", String.join(",", annotationProcessors), "-s",
tempDir.getAbsolutePath());
List<String> options = List.of("-cp", classpath, "-processor",
String.join(",", annotationProcessors), "-s", tempDir.getAbsolutePath());

// Compile the source file
try (StandardJavaFileManager fileManager =
Expand All @@ -244,4 +254,48 @@ private String compileSourceCode(File tempDir, List<String> compilationUnitSourc
return errors;
}
}

/**
* The Dagger version to use for compiling test code. This should be passed by
* maven-surefire-plugin using the exact dagger version from the POM. See the root POM for the
* specific details of the setup.
*/
private static final String DAGGER_VERSION =
Optional.ofNullable(System.getProperty("dagger.version"))
.orElseThrow(() -> new IllegalStateException("dagger.version system property not set"));

/**
* The javax.inject version to use for compiling test code. This should be passed by
* maven-surefire-plugin using the exact javax.inject version from the POM. See the root POM for
* the specific details of the setup.
*/
private static final String JAVAX_INJECT_VERSION =
Optional.ofNullable(System.getProperty("javax.inject.version")).orElseThrow(
() -> new IllegalStateException("javax.inject.version system property not set"));

/**
* The Jakarta Inject API version to use for compiling test code. This should be passed by
* maven-surefire-plugin using the exact Jakarta Inject API version from the POM. See the root POM
* for the specific details
*/
private static final String JAKARTA_INJECT_API_VERSION =
Optional.ofNullable(System.getProperty("jakarta.inject-api.version")).orElseThrow(
() -> new IllegalStateException("jakarta.inject-api.version system property not set"));

private static final String JSR_305_VERSION =
Optional.ofNullable(System.getProperty("jsr305.version")).orElseThrow(
() -> new IllegalStateException("jsr305.version system property not set"));


private List<File> simulationClasspath() {
final File daggerJar =
Maven.findJarInLocalRepository("com.google.dagger", "dagger", DAGGER_VERSION);
final File javaxInjectJar =
Maven.findJarInLocalRepository("javax.inject", "javax.inject", JAVAX_INJECT_VERSION);
final File jakartaInjectApiJar = Maven.findJarInLocalRepository("jakarta.inject",
"jakarta.inject-api", JAKARTA_INJECT_API_VERSION);
final File jsr305Jar = Maven.findJarInLocalRepository("com.google.code.findbugs",
"jsr305", JSR_305_VERSION);
return List.of(daggerJar, javaxInjectJar, jakartaInjectApiJar, jsr305Jar);
}
}
37 changes: 37 additions & 0 deletions rapier-core/src/test/java/rapier/core/util/Maven.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package rapier.core.util;

import java.io.File;

public final class Maven {
private Maven() {}

private static final String LOCAL_REPO_PATH = System.getProperty("user.home") + "/.m2/repository";

/**
* Finds the JAR file for a given Maven artifact in the local repository. Makes no attempt to
* download the artifact if it does not exist in the local cache. For this reason, this method
* should generally only be used for artifacts that are present in the build, since the build will
* guarantee that the artifact is present in the local repository.
*
* @param groupId The group ID of the artifact
* @param artifactId The artifact ID of the artifact
* @param version The version of the artifact
* @return An Optional containing the JAR file if it exists, or an empty Optional otherwise
*/
public static File findJarInLocalRepository(String groupId, String artifactId, String version) {
// Convert groupId to directory path (e.g., org.apache.maven -> org/apache/maven)
final String groupPath = groupId.replace('.', '/');

// Construct the path to the JAR file
final String jarPath = String.format("%s/%s/%s/%s/%s-%s.jar", LOCAL_REPO_PATH, groupPath,
artifactId, version, artifactId, version);

// Return the JAR file as a File object
final File jarFile = new File(jarPath);

if (!jarFile.exists())
throw new IllegalArgumentException("JAR file does not exist: " + jarFile);

return jarFile;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
package rapier.processor.cli;

import static com.google.testing.compile.CompilationSubject.assertThat;
import static java.util.Collections.emptyList;
import javax.tools.JavaFileObject;
import org.junit.jupiter.api.Test;
import com.google.testing.compile.Compilation;
Expand Down Expand Up @@ -49,8 +50,8 @@ public interface ExampleComponent {
""");

// Run the annotation processor
final Compilation compilation =
Compiler.javac().withProcessors(new CliProcessor()).compile(source);
final Compilation compilation = Compiler.javac().withClasspath(emptyList())
.withProcessors(new CliProcessor()).compile(source);

// Assert the compilation succeeded
assertThat(compilation).succeeded();
Expand Down

0 comments on commit a36dfa9

Please sign in to comment.