Skip to content

Commit a82f09a

Browse files
committed
wip
Signed-off-by: Attila Mészáros <a_meszaros@apple.com>
1 parent 461088d commit a82f09a

1 file changed

Lines changed: 60 additions & 0 deletions

File tree

operator-framework/src/test/java/io/javaoperatorsdk/operator/config/runtime/ControllerConfigurationAnnotationProcessorTest.java

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@
1515
*/
1616
package io.javaoperatorsdk.operator.config.runtime;
1717

18+
import java.io.IOException;
19+
import java.io.UncheckedIOException;
20+
1821
import javax.tools.StandardLocation;
1922

2023
import org.junit.jupiter.api.Test;
@@ -25,6 +28,7 @@
2528
import com.google.testing.compile.JavaFileObjects;
2629

2730
import static io.javaoperatorsdk.operator.config.runtime.RuntimeControllerMetadata.RECONCILERS_RESOURCE_PATH;
31+
import static org.assertj.core.api.Assertions.assertThat;
2832

2933
class ControllerConfigurationAnnotationProcessorTest {
3034

@@ -70,6 +74,26 @@ public void generateDoneableClassWithMultilevelHierarchy() {
7074
assertMapping(compilation, "io.MultilevelReconciler,io.MultilevelReconciler.MyCustomResource");
7175
}
7276

77+
/**
78+
* When the reconciled resource is itself generic, the resolved type is a parameterized {@code
79+
* DeclaredType}. Only its erasure may be written to the mapping resource: {@link
80+
* ClassMappingProvider} loads the recorded name with {@code ClassUtils.getClass(String)}, which
81+
* cannot parse type arguments.
82+
*/
83+
@Test
84+
public void writesErasureOfGenericResourceType() {
85+
Compilation compilation =
86+
Compiler.javac()
87+
.withProcessors(new ControllerConfigurationAnnotationProcessor())
88+
.compile(
89+
JavaFileObjects.forResource("compile-fixtures/GenericResourceReconciler.java"));
90+
CompilationSubject.assertThat(compilation).succeeded();
91+
assertMapping(
92+
compilation,
93+
"io.GenericResourceReconciler,io.GenericResourceReconciler.MyGenericCustomResource");
94+
assertLoadableMapping(compilation);
95+
}
96+
7397
/**
7498
* Checks that the generated mapping resource contains the expected {@code
7599
* reconciler,resource-class} line, using the same fully qualified, dot separated names that
@@ -81,4 +105,40 @@ private static void assertMapping(Compilation compilation, String expectedMappin
81105
.contentsAsUtf8String()
82106
.contains(expectedMapping);
83107
}
108+
109+
/**
110+
* Checks that every recorded name in the generated mapping resource is a plain binary-ish class
111+
* name, i.e. one that {@code ClassUtils.getClass(String)} can actually resolve, rather than a
112+
* generic type signature such as {@code io.Foo<java.lang.String>}.
113+
*/
114+
private static void assertLoadableMapping(Compilation compilation) {
115+
final var contents =
116+
compilation
117+
.generatedFile(StandardLocation.CLASS_OUTPUT, RECONCILERS_RESOURCE_PATH)
118+
.map(
119+
file -> {
120+
try {
121+
return file.getCharContent(true).toString();
122+
} catch (IOException e) {
123+
throw new UncheckedIOException(e);
124+
}
125+
})
126+
.orElseThrow(() -> new AssertionError("no mapping resource was generated"));
127+
contents
128+
.lines()
129+
.filter(line -> !line.isBlank())
130+
.forEach(
131+
line -> {
132+
final var names = line.split(",");
133+
assertThat(names).as("mapping line '%s'", line).hasSize(2);
134+
for (String name : names) {
135+
assertThat(name)
136+
.as("recorded class name '%s' must be loadable at runtime", name)
137+
.doesNotContain("<")
138+
.doesNotContain(">")
139+
.doesNotContain(" ")
140+
.matches("[\\p{L}_$][\\p{L}\\p{N}_$]*(\\.[\\p{L}_$][\\p{L}\\p{N}_$]*)*");
141+
}
142+
});
143+
}
84144
}

0 commit comments

Comments
 (0)