Skip to content

Commit 0ac540d

Browse files
alxkmsobychacko
authored andcommitted
test: Enhanced test coverage for AzureOpenAiRuntimeHintsTests
Signed-off-by: Alex Klimenko <[email protected]>
1 parent b45fd12 commit 0ac540d

File tree

1 file changed

+122
-3
lines changed

1 file changed

+122
-3
lines changed

models/spring-ai-azure-openai/src/test/java/org/springframework/ai/azure/openai/aot/AzureOpenAiRuntimeHintsTests.java

Lines changed: 122 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,28 +16,39 @@
1616

1717
package org.springframework.ai.azure.openai.aot;
1818

19+
import java.util.HashSet;
1920
import java.util.Set;
2021

2122
import com.azure.ai.openai.OpenAIAsyncClient;
2223
import com.azure.ai.openai.OpenAIClient;
2324
import com.azure.ai.openai.models.ChatChoice;
2425
import org.junit.jupiter.api.Test;
26+
import org.junit.jupiter.api.BeforeEach;
2527

2628
import org.springframework.ai.aot.AiRuntimeHints;
2729
import org.springframework.aot.hint.RuntimeHints;
2830
import org.springframework.aot.hint.TypeReference;
31+
import org.springframework.aot.hint.MemberCategory;
2932

3033
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
3134
import static org.springframework.aot.hint.predicate.RuntimeHintsPredicates.reflection;
3235
import static org.springframework.aot.hint.predicate.RuntimeHintsPredicates.resource;
3336

3437
class AzureOpenAiRuntimeHintsTests {
3538

39+
private RuntimeHints runtimeHints;
40+
41+
private AzureOpenAiRuntimeHints azureOpenAiRuntimeHints;
42+
43+
@BeforeEach
44+
void setUp() {
45+
runtimeHints = new RuntimeHints();
46+
azureOpenAiRuntimeHints = new AzureOpenAiRuntimeHints();
47+
}
48+
3649
@Test
3750
void registerHints() {
38-
RuntimeHints runtimeHints = new RuntimeHints();
39-
AzureOpenAiRuntimeHints openAiRuntimeHints = new AzureOpenAiRuntimeHints();
40-
openAiRuntimeHints.registerHints(runtimeHints, null);
51+
azureOpenAiRuntimeHints.registerHints(runtimeHints, null);
4152

4253
Set<TypeReference> azureModelTypes = AiRuntimeHints.findClassesInPackage(ChatChoice.class.getPackageName(),
4354
(metadataReader, metadataReaderFactory) -> true);
@@ -50,4 +61,112 @@ void registerHints() {
5061
assertThat(runtimeHints).matches(resource().forResource("/azure-ai-openai.properties"));
5162
}
5263

64+
@Test
65+
void registerHintsWithNullClassLoader() {
66+
// Test that registering hints with null ClassLoader works correctly
67+
azureOpenAiRuntimeHints.registerHints(runtimeHints, null);
68+
69+
assertThat(runtimeHints).matches(reflection().onType(OpenAIClient.class));
70+
assertThat(runtimeHints).matches(reflection().onType(OpenAIAsyncClient.class));
71+
assertThat(runtimeHints).matches(resource().forResource("/azure-ai-openai.properties"));
72+
}
73+
74+
@Test
75+
void registerHintsWithCustomClassLoader() {
76+
// Test that registering hints with a custom ClassLoader works correctly
77+
ClassLoader customClassLoader = Thread.currentThread().getContextClassLoader();
78+
azureOpenAiRuntimeHints.registerHints(runtimeHints, customClassLoader);
79+
80+
assertThat(runtimeHints).matches(reflection().onType(OpenAIClient.class));
81+
assertThat(runtimeHints).matches(reflection().onType(OpenAIAsyncClient.class));
82+
assertThat(runtimeHints).matches(resource().forResource("/azure-ai-openai.properties"));
83+
}
84+
85+
@Test
86+
void allMemberCategoriesAreRegisteredForAzureTypes() {
87+
azureOpenAiRuntimeHints.registerHints(runtimeHints, null);
88+
89+
Set<TypeReference> azureModelTypes = AiRuntimeHints.findClassesInPackage(ChatChoice.class.getPackageName(),
90+
(metadataReader, metadataReaderFactory) -> true);
91+
92+
// Verify that all MemberCategory values are registered for Azure model types
93+
runtimeHints.reflection().typeHints().forEach(typeHint -> {
94+
if (azureModelTypes.contains(typeHint.getType())) {
95+
Set<MemberCategory> expectedCategories = Set.of(MemberCategory.values());
96+
Set<MemberCategory> actualCategories = typeHint.getMemberCategories();
97+
assertThat(actualCategories.containsAll(expectedCategories)).isTrue();
98+
}
99+
});
100+
}
101+
102+
@Test
103+
void verifySpecificAzureOpenAiClasses() {
104+
azureOpenAiRuntimeHints.registerHints(runtimeHints, null);
105+
106+
// Verify specific Azure OpenAI classes are registered
107+
assertThat(runtimeHints).matches(reflection().onType(OpenAIClient.class));
108+
assertThat(runtimeHints).matches(reflection().onType(OpenAIAsyncClient.class));
109+
assertThat(runtimeHints).matches(reflection().onType(ChatChoice.class));
110+
}
111+
112+
@Test
113+
void emptyRuntimeHintsInitiallyContainsNoTypes() {
114+
// Verify that fresh RuntimeHints instance contains no reflection hints
115+
RuntimeHints emptyHints = new RuntimeHints();
116+
Set<TypeReference> emptyRegisteredTypes = new HashSet<>();
117+
emptyHints.reflection().typeHints().forEach(typeHint -> emptyRegisteredTypes.add(typeHint.getType()));
118+
119+
assertThat(emptyRegisteredTypes.size()).isEqualTo(0);
120+
}
121+
122+
@Test
123+
void multipleRegistrationCallsAreIdempotent() {
124+
// Register hints multiple times and verify no duplicates
125+
azureOpenAiRuntimeHints.registerHints(runtimeHints, null);
126+
int firstRegistrationCount = (int) runtimeHints.reflection().typeHints().count();
127+
128+
azureOpenAiRuntimeHints.registerHints(runtimeHints, null);
129+
int secondRegistrationCount = (int) runtimeHints.reflection().typeHints().count();
130+
131+
assertThat(firstRegistrationCount).isEqualTo(secondRegistrationCount);
132+
133+
// Verify resource hint registration is also idempotent
134+
assertThat(runtimeHints).matches(resource().forResource("/azure-ai-openai.properties"));
135+
}
136+
137+
@Test
138+
void verifyAzureModelTypesInPackageIsNotEmpty() {
139+
Set<TypeReference> azureModelTypes = AiRuntimeHints.findClassesInPackage(ChatChoice.class.getPackageName(),
140+
(metadataReader, metadataReaderFactory) -> true);
141+
assertThat(azureModelTypes.size()).isGreaterThan(0);
142+
}
143+
144+
@Test
145+
void verifyResourceHintIsRegistered() {
146+
azureOpenAiRuntimeHints.registerHints(runtimeHints, null);
147+
148+
// Verify the specific resource hint is registered
149+
assertThat(runtimeHints).matches(resource().forResource("/azure-ai-openai.properties"));
150+
}
151+
152+
@Test
153+
void verifyAllRegisteredTypesHaveReflectionHints() {
154+
azureOpenAiRuntimeHints.registerHints(runtimeHints, null);
155+
156+
// Ensure every registered type has proper reflection hints
157+
runtimeHints.reflection().typeHints().forEach(typeHint -> {
158+
assertThat(typeHint.getType()).isNotNull();
159+
assertThat(typeHint.getMemberCategories().size()).isGreaterThan(0);
160+
});
161+
}
162+
163+
@Test
164+
void verifyClientTypesAreRegistered() {
165+
azureOpenAiRuntimeHints.registerHints(runtimeHints, null);
166+
167+
// Verify both sync and async client types are properly registered
168+
assertThat(runtimeHints).matches(reflection().onType(OpenAIClient.class));
169+
assertThat(runtimeHints).matches(reflection().onType(OpenAIAsyncClient.class));
170+
}
171+
53172
}

0 commit comments

Comments
 (0)