From 94e810201e317dca44e271c2729b0fd68cd6dcdd Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Mon, 30 Oct 2023 14:11:56 +0000 Subject: [PATCH] Fix test for incremental build of renamed properties class Previously, the .class file for the renamed properties class was on the class path of the compilation in two places: 1. The output directory of the test's previous compilation 2. The output directory of the compilation of src/test/java of spring-boot-configuration-processor The first of these locations is addressed by updating TestProject. The .class file is now deleted from the project's output location at the same time as the .java file is deleted from its source location. The second of these locations is addressed by configuring the class path of the compiler to include a copy of the result of compiling src/test/java of spring-boot-configuration-processor. From this copy entries can then be deleted as needed without destabilizing other tests. Closes gh-26271 --- ...crementalBuildMetadataGenerationTests.java | 2 - .../configurationprocessor/TestProject.java | 39 ++++++++++++++++--- .../testsupport/compiler/TestCompiler.java | 6 +++ 3 files changed, 39 insertions(+), 8 deletions(-) diff --git a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/IncrementalBuildMetadataGenerationTests.java b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/IncrementalBuildMetadataGenerationTests.java index f5e80e4eae6..35b7e94245d 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/IncrementalBuildMetadataGenerationTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/IncrementalBuildMetadataGenerationTests.java @@ -16,7 +16,6 @@ package org.springframework.boot.configurationprocessor; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.springframework.boot.configurationprocessor.metadata.ConfigurationMetadata; @@ -74,7 +73,6 @@ class IncrementalBuildMetadataGenerationTests extends AbstractMetadataGeneration } @Test - @Disabled("gh-26271") void incrementalBuildTypeRenamed() throws Exception { TestProject project = new TestProject(this.tempDir, FooProperties.class, BarProperties.class); ConfigurationMetadata metadata = project.fullBuild(); diff --git a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/TestProject.java b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/TestProject.java index c8442e974ce..1a7d90277d3 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/TestProject.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/TestProject.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,15 +23,18 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.StringReader; +import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.LinkedHashSet; +import java.util.List; import java.util.Set; import org.springframework.boot.configurationprocessor.metadata.ConfigurationMetadata; import org.springframework.boot.configurationprocessor.test.TestConfigurationMetadataAnnotationProcessor; import org.springframework.boot.configurationsample.ConfigurationProperties; import org.springframework.boot.configurationsample.NestedConfigurationProperty; +import org.springframework.boot.testsupport.BuildOutput; import org.springframework.boot.testsupport.compiler.TestCompiler; import org.springframework.boot.testsupport.compiler.TestCompiler.TestCompilationTask; import org.springframework.util.Assert; @@ -56,21 +59,41 @@ public class TestProject { * Contains copies of the original source so we can modify it safely to test * incremental builds. */ - private File sourceDirectory; + private final File sourceDirectory; - private TestCompiler compiler; + private final TestCompiler compiler; - private Set sourceFiles = new LinkedHashSet<>(); + private final Set sourceFiles = new LinkedHashSet<>(); + + private final File classPathDirectory; public TestProject(File tempDirectory, Class... classes) throws IOException { this.sourceDirectory = new File(tempDirectory, "src"); - this.compiler = new TestCompiler(new File(tempDirectory, "build")) { + File outputDirectory = new File(tempDirectory, "build"); + File testClasses = new BuildOutput(TestProject.class).getTestClassesLocation(); + this.classPathDirectory = new File(tempDirectory, "classPath"); + FileSystemUtils.copyRecursively(testClasses, this.classPathDirectory); + this.compiler = new TestCompiler(outputDirectory) { @Override protected File getSourceDirectory() { return TestProject.this.sourceDirectory; } + @Override + protected Iterable prepareClassPath(Iterable classPath) { + List updatedClassPath = new ArrayList<>(); + for (File entry : classPath) { + if (!entry.equals(testClasses)) { + updatedClassPath.add(entry); + } + else { + updatedClassPath.add(TestProject.this.classPathDirectory); + } + } + return updatedClassPath; + } + }; Set> contents = new HashSet<>(Arrays.asList(classes)); contents.addAll(Arrays.asList(ALWAYS_INCLUDE)); @@ -143,13 +166,17 @@ public class TestProject { } /** - * Delete source file for given class from project. + * Delete from the project the source {@code .java} file and any compiled + * {@code .class} file for the given class. * @param type the class to delete */ public void delete(Class type) { File target = getSourceFile(type); target.delete(); this.sourceFiles.remove(target); + String fileName = type.getName().replace(".", "/") + ".class"; + new File(this.compiler.getOutputLocation(), fileName).delete(); + new File(this.classPathDirectory, fileName).delete(); } /** diff --git a/spring-boot-project/spring-boot-tools/spring-boot-test-support/src/main/java/org/springframework/boot/testsupport/compiler/TestCompiler.java b/spring-boot-project/spring-boot-tools/spring-boot-test-support/src/main/java/org/springframework/boot/testsupport/compiler/TestCompiler.java index 8eb8511a98e..ed90f6e292a 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-test-support/src/main/java/org/springframework/boot/testsupport/compiler/TestCompiler.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-test-support/src/main/java/org/springframework/boot/testsupport/compiler/TestCompiler.java @@ -62,6 +62,8 @@ public class TestCompiler { Iterable temp = Collections.singletonList(this.outputLocation); this.fileManager.setLocation(StandardLocation.CLASS_OUTPUT, temp); this.fileManager.setLocation(StandardLocation.SOURCE_OUTPUT, temp); + Iterable classPath = this.fileManager.getLocation(StandardLocation.CLASS_PATH); + this.fileManager.setLocation(StandardLocation.CLASS_PATH, prepareClassPath(classPath)); } public TestCompilationTask getTask(Collection sourceFiles) { @@ -103,6 +105,10 @@ public class TestCompiler { return SOURCE_DIRECTORY; } + protected Iterable prepareClassPath(Iterable classPath) { + return classPath; + } + /** * A compilation task. */