Skip to content

Commit 41f37a6

Browse files
test(mcp): add response-size unit tests
1 parent cd1ba74 commit 41f37a6

2 files changed

Lines changed: 76 additions & 2 deletions

File tree

openmetadata-mcp/src/main/java/org/openmetadata/mcp/tools/SearchMetadataTool.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,7 @@ static Map<String, Object> buildEnhancedSearchResponse(
334334
"message",
335335
String.format(
336336
"Found %d total results, showing first %d. "
337-
+ "There are many matching assets. Are you looking for something specific?"
337+
+ "There are many matching assets. Are you looking for something specific? "
338338
+ "Try narrowing with a service name, schema name, or more specific search term.",
339339
totalResults, cleanedResults.size()));
340340
result.put("hasMore", true);
@@ -367,7 +367,7 @@ static Map<String, Object> buildEnhancedSearchResponse(
367367
"message",
368368
String.format(
369369
"Response exceeded %d characters and was trimmed to %d of %d results. "
370-
+ "There are many matching assets. Are you looking for something specific?"
370+
+ "There are many matching assets. Are you looking for something specific? "
371371
+ "Try narrowing with a service name, schema, or specific name.",
372372
MAX_RESPONSE_CHARS, trimmed.size(), totalResults));
373373
}

openmetadata-mcp/src/test/java/org/openmetadata/mcp/tools/SearchMetadataAggregationTest.java

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,4 +242,78 @@ private Map<String, Object> createEmptyHits() {
242242
hits.put("total", total);
243243
return hits;
244244
}
245+
246+
@Test
247+
void testResponseTrimmedWhenExceedingCharLimit() {
248+
// 50 results each with 200 columns (~50 chars each) => ~500k chars, well over the 100k cap
249+
Map<String, Object> searchResponse = createSearchResponseWithLargeResults(50, 200);
250+
251+
Map<String, Object> result =
252+
SearchMetadataTool.buildEnhancedSearchResponse(
253+
searchResponse, "*", 50, Collections.emptyList(), false, 10);
254+
255+
@SuppressWarnings("unchecked")
256+
List<Map<String, Object>> results = (List<Map<String, Object>>) result.get("results");
257+
assertTrue(results.size() < 50, "Results should be trimmed below requested 50");
258+
assertEquals(true, result.get("hasMore"), "hasMore must be true when trimmed by size cap");
259+
assertEquals(results.size(), result.get("returnedCount"));
260+
String message = (String) result.get("message");
261+
assertTrue(message.contains("trimmed"), "Message should mention trimming");
262+
}
263+
264+
@Test
265+
void testResponseNotTrimmedWhenUnderCharLimit() {
266+
// 5 results with 2 columns each — well under 100k
267+
Map<String, Object> searchResponse = createSearchResponseWithLargeResults(5, 2);
268+
269+
Map<String, Object> result =
270+
SearchMetadataTool.buildEnhancedSearchResponse(
271+
searchResponse, "*", 50, Collections.emptyList(), false, 10);
272+
273+
@SuppressWarnings("unchecked")
274+
List<Map<String, Object>> results = (List<Map<String, Object>>) result.get("results");
275+
assertEquals(5, results.size(), "Results should not be trimmed when under char limit");
276+
}
277+
278+
@Test
279+
void testResponseTrimmedToAtLeastOneResult() {
280+
// Single result with enough columns to exceed 100k on its own
281+
Map<String, Object> searchResponse = createSearchResponseWithLargeResults(1, 3000);
282+
283+
Map<String, Object> result =
284+
SearchMetadataTool.buildEnhancedSearchResponse(
285+
searchResponse, "*", 50, Collections.emptyList(), false, 10);
286+
287+
@SuppressWarnings("unchecked")
288+
List<Map<String, Object>> results = (List<Map<String, Object>>) result.get("results");
289+
assertEquals(1, results.size(), "At least one result must always be returned");
290+
}
291+
292+
private Map<String, Object> createSearchResponseWithLargeResults(int count, int columnCount) {
293+
Map<String, Object> response = new HashMap<>();
294+
295+
List<Map<String, Object>> hits = new ArrayList<>();
296+
for (int i = 0; i < count; i++) {
297+
Map<String, Object> source = new HashMap<>();
298+
source.put("name", "table_" + i);
299+
source.put("fullyQualifiedName", "service.db.schema.table_" + i);
300+
source.put("entityType", "table");
301+
List<String> columnNames = new ArrayList<>();
302+
for (int c = 0; c < columnCount; c++) {
303+
columnNames.add("column_with_long_name_to_increase_payload_size_" + c);
304+
}
305+
source.put("columnNames", columnNames);
306+
Map<String, Object> hit = new HashMap<>();
307+
hit.put("_source", source);
308+
hits.add(hit);
309+
}
310+
311+
Map<String, Object> total = new HashMap<>();
312+
total.put("value", count);
313+
Map<String, Object> hitsObj = new HashMap<>();
314+
hitsObj.put("hits", hits);
315+
hitsObj.put("total", total);
316+
response.put("hits", hitsObj);
317+
return response;
318+
}
245319
}

0 commit comments

Comments
 (0)