Skip to content

Commit 7d6f9be

Browse files
authored
test: Add comprehensive test coverage for SpringAI core runtime hints registration (#4024)
Signed-off-by: Alex Klimenko <[email protected]>
1 parent 5bc46dd commit 7d6f9be

File tree

1 file changed

+98
-0
lines changed

1 file changed

+98
-0
lines changed

spring-ai-model/src/test/java/org/springframework/ai/aot/SpringAiCoreRuntimeHintsTest.java

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,13 @@
2121
import org.springframework.ai.tool.ToolCallback;
2222
import org.springframework.ai.tool.definition.ToolDefinition;
2323
import org.springframework.aot.hint.RuntimeHints;
24+
import org.springframework.aot.hint.TypeReference;
25+
26+
import java.util.HashSet;
27+
import java.util.Set;
2428

2529
import static org.assertj.core.api.Assertions.assertThat;
30+
import static org.assertj.core.api.Assertions.assertThatCode;
2631
import static org.springframework.aot.hint.predicate.RuntimeHintsPredicates.reflection;
2732
import static org.springframework.aot.hint.predicate.RuntimeHintsPredicates.resource;
2833

@@ -42,4 +47,97 @@ void core() {
4247
assertThat(runtimeHints).matches(reflection().onType(ToolDefinition.class));
4348
}
4449

50+
@Test
51+
void registerHintsWithNullClassLoader() {
52+
var runtimeHints = new RuntimeHints();
53+
var springAiCore = new SpringAiCoreRuntimeHints();
54+
55+
// Should not throw exception with null ClassLoader
56+
assertThatCode(() -> springAiCore.registerHints(runtimeHints, null)).doesNotThrowAnyException();
57+
}
58+
59+
@Test
60+
void verifyEmbeddingResourceIsRegistered() {
61+
var runtimeHints = new RuntimeHints();
62+
var springAiCore = new SpringAiCoreRuntimeHints();
63+
springAiCore.registerHints(runtimeHints, null);
64+
65+
// Verify the specific embedding properties file is registered
66+
assertThat(runtimeHints).matches(resource().forResource("embedding/embedding-model-dimensions.properties"));
67+
}
68+
69+
@Test
70+
void verifyToolReflectionHintsAreRegistered() {
71+
var runtimeHints = new RuntimeHints();
72+
var springAiCore = new SpringAiCoreRuntimeHints();
73+
springAiCore.registerHints(runtimeHints, null);
74+
75+
Set<TypeReference> registeredTypes = new HashSet<>();
76+
runtimeHints.reflection().typeHints().forEach(typeHint -> registeredTypes.add(typeHint.getType()));
77+
78+
// Verify core tool classes are registered
79+
assertThat(registeredTypes.contains(TypeReference.of(ToolCallback.class))).isTrue();
80+
assertThat(registeredTypes.contains(TypeReference.of(ToolDefinition.class))).isTrue();
81+
}
82+
83+
@Test
84+
void verifyResourceAndReflectionHintsSeparately() {
85+
var runtimeHints = new RuntimeHints();
86+
var springAiCore = new SpringAiCoreRuntimeHints();
87+
springAiCore.registerHints(runtimeHints, null);
88+
89+
// Test resource hints
90+
assertThat(runtimeHints).matches(resource().forResource("embedding/embedding-model-dimensions.properties"));
91+
92+
// Test reflection hints
93+
assertThat(runtimeHints).matches(reflection().onType(ToolCallback.class));
94+
assertThat(runtimeHints).matches(reflection().onType(ToolDefinition.class));
95+
}
96+
97+
@Test
98+
void verifyMultipleRegistrationCallsAreIdempotent() {
99+
var runtimeHints1 = new RuntimeHints();
100+
var runtimeHints2 = new RuntimeHints();
101+
var springAiCore = new SpringAiCoreRuntimeHints();
102+
103+
// Register hints on two separate RuntimeHints instances
104+
springAiCore.registerHints(runtimeHints1, null);
105+
springAiCore.registerHints(runtimeHints2, null);
106+
107+
// Both should have the same hints registered
108+
assertThat(runtimeHints1).matches(resource().forResource("embedding/embedding-model-dimensions.properties"));
109+
assertThat(runtimeHints2).matches(resource().forResource("embedding/embedding-model-dimensions.properties"));
110+
111+
assertThat(runtimeHints1).matches(reflection().onType(ToolCallback.class));
112+
assertThat(runtimeHints2).matches(reflection().onType(ToolCallback.class));
113+
}
114+
115+
@Test
116+
void verifyResourceHintsForIncorrectPaths() {
117+
var runtimeHints = new RuntimeHints();
118+
var springAiCore = new SpringAiCoreRuntimeHints();
119+
springAiCore.registerHints(runtimeHints, null);
120+
121+
// Verify the exact resource path is registered
122+
assertThat(runtimeHints).matches(resource().forResource("embedding/embedding-model-dimensions.properties"));
123+
124+
// Verify that similar but incorrect paths are not matched
125+
assertThat(runtimeHints).doesNotMatch(resource().forResource("embedding-model-dimensions.properties"));
126+
assertThat(runtimeHints).doesNotMatch(resource().forResource("embedding/model-dimensions.properties"));
127+
}
128+
129+
@Test
130+
void ensureBothResourceAndReflectionHintsArePresent() {
131+
var runtimeHints = new RuntimeHints();
132+
var springAiCore = new SpringAiCoreRuntimeHints();
133+
springAiCore.registerHints(runtimeHints, null);
134+
135+
// Ensure both resource and reflection hints are registered
136+
boolean hasResourceHints = runtimeHints.resources() != null;
137+
boolean hasReflectionHints = runtimeHints.reflection().typeHints().spliterator().estimateSize() > 0;
138+
139+
assertThat(hasResourceHints).isTrue();
140+
assertThat(hasReflectionHints).isTrue();
141+
}
142+
45143
}

0 commit comments

Comments
 (0)