Skip to content

Commit d98b8c9

Browse files
committed
WIP: Logging notifications tests on exchange adapted
Signed-off-by: Dariusz Jędrzejczyk <[email protected]>
1 parent a0ad5a5 commit d98b8c9

File tree

2 files changed

+37
-227
lines changed

2 files changed

+37
-227
lines changed

mcp/src/test/java/io/modelcontextprotocol/server/McpAsyncServerExchangeTests.java

Lines changed: 23 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import java.util.Map;
1111

1212
import com.fasterxml.jackson.core.type.TypeReference;
13+
import io.modelcontextprotocol.spec.DefaultMcpTransportContext;
1314
import io.modelcontextprotocol.spec.McpError;
1415
import io.modelcontextprotocol.spec.McpSchema;
1516
import io.modelcontextprotocol.spec.McpServerSession;
@@ -54,7 +55,8 @@ void setUp() {
5455

5556
clientInfo = new McpSchema.Implementation("test-client", "1.0.0");
5657

57-
exchange = new McpAsyncServerExchange(mockSession, clientCapabilities, clientInfo);
58+
exchange = new McpAsyncServerExchange("testSessionId", mockSession, clientCapabilities, clientInfo,
59+
new DefaultMcpTransportContext());
5860
}
5961

6062
@Test
@@ -219,132 +221,72 @@ void testLoggingNotificationWithNullMessage() {
219221
}
220222

221223
@Test
222-
void testLoggingNotificationWithAllowedLevel() {
224+
void testSetMinLoggingLevelWithNullValue() {
225+
assertThatThrownBy(() -> exchange.setMinLoggingLevel(null)).isInstanceOf(IllegalArgumentException.class)
226+
.hasMessage("minLoggingLevel must not be null");
227+
}
223228

229+
@Test
230+
void testLoggingNotificationWithAllowedLevel() {
224231
McpSchema.LoggingMessageNotification notification = McpSchema.LoggingMessageNotification.builder()
225232
.level(McpSchema.LoggingLevel.ERROR)
226233
.logger("test-logger")
227234
.data("Test error message")
228235
.build();
229236

237+
when(mockSession.isNotificationForLevelAllowed(any())).thenReturn(Boolean.TRUE);
230238
when(mockSession.sendNotification(eq(McpSchema.METHOD_NOTIFICATION_MESSAGE), eq(notification)))
231239
.thenReturn(Mono.empty());
232240

233241
StepVerifier.create(exchange.loggingNotification(notification)).verifyComplete();
234242

235-
// Verify that sendNotification was called exactly once
243+
verify(mockSession, times(1)).isNotificationForLevelAllowed(eq(McpSchema.LoggingLevel.ERROR));
236244
verify(mockSession, times(1)).sendNotification(eq(McpSchema.METHOD_NOTIFICATION_MESSAGE), eq(notification));
237245
}
238246

239247
@Test
240248
void testLoggingNotificationWithFilteredLevel() {
241-
// Given - Set minimum level to WARNING, send DEBUG message
242-
exchange.setMinLoggingLevel(McpSchema.LoggingLevel.WARNING);
249+
exchange.setMinLoggingLevel(McpSchema.LoggingLevel.DEBUG);
250+
verify(mockSession, times(1)).setMinLoggingLevel(eq(McpSchema.LoggingLevel.DEBUG));
243251

244252
McpSchema.LoggingMessageNotification debugNotification = McpSchema.LoggingMessageNotification.builder()
245253
.level(McpSchema.LoggingLevel.DEBUG)
246254
.logger("test-logger")
247255
.data("Debug message that should be filtered")
248256
.build();
249257

250-
// When & Then - Should complete without sending notification
251-
StepVerifier.create(exchange.loggingNotification(debugNotification)).verifyComplete();
252-
253-
// Verify that sendNotification was never called for filtered DEBUG level
254-
verify(mockSession, never()).sendNotification(eq(McpSchema.METHOD_NOTIFICATION_MESSAGE), eq(debugNotification));
255-
}
256-
257-
@Test
258-
void testLoggingNotificationLevelFiltering() {
259-
// Given - Set minimum level to WARNING
260-
exchange.setMinLoggingLevel(McpSchema.LoggingLevel.WARNING);
261-
262-
// Test DEBUG (should be filtered)
263-
McpSchema.LoggingMessageNotification debugNotification = McpSchema.LoggingMessageNotification.builder()
264-
.level(McpSchema.LoggingLevel.DEBUG)
265-
.logger("test-logger")
266-
.data("Debug message")
267-
.build();
258+
when(mockSession.isNotificationForLevelAllowed(eq(McpSchema.LoggingLevel.DEBUG))).thenReturn(Boolean.TRUE);
259+
when(mockSession.sendNotification(eq(McpSchema.METHOD_NOTIFICATION_MESSAGE), eq(debugNotification)))
260+
.thenReturn(Mono.empty());
268261

269262
StepVerifier.create(exchange.loggingNotification(debugNotification)).verifyComplete();
270263

271-
// Verify that sendNotification was never called for DEBUG level
272-
verify(mockSession, never()).sendNotification(eq(McpSchema.METHOD_NOTIFICATION_MESSAGE), eq(debugNotification));
273-
274-
// Test INFO (should be filtered)
275-
McpSchema.LoggingMessageNotification infoNotification = McpSchema.LoggingMessageNotification.builder()
276-
.level(McpSchema.LoggingLevel.INFO)
277-
.logger("test-logger")
278-
.data("Info message")
279-
.build();
280-
281-
StepVerifier.create(exchange.loggingNotification(infoNotification)).verifyComplete();
282-
283-
// Verify that sendNotification was never called for INFO level
284-
verify(mockSession, never()).sendNotification(eq(McpSchema.METHOD_NOTIFICATION_MESSAGE), eq(infoNotification));
285-
286-
reset(mockSession);
264+
verify(mockSession, times(1)).isNotificationForLevelAllowed(eq(McpSchema.LoggingLevel.DEBUG));
265+
verify(mockSession, times(1)).sendNotification(eq(McpSchema.METHOD_NOTIFICATION_MESSAGE),
266+
eq(debugNotification));
287267

288-
// Test WARNING (should be sent)
289268
McpSchema.LoggingMessageNotification warningNotification = McpSchema.LoggingMessageNotification.builder()
290269
.level(McpSchema.LoggingLevel.WARNING)
291270
.logger("test-logger")
292-
.data("Warning message")
271+
.data("Debug message that should be filtered")
293272
.build();
294273

295-
when(mockSession.sendNotification(eq(McpSchema.METHOD_NOTIFICATION_MESSAGE), eq(warningNotification)))
296-
.thenReturn(Mono.empty());
297-
298274
StepVerifier.create(exchange.loggingNotification(warningNotification)).verifyComplete();
299275

300-
// Verify that sendNotification was called exactly once for WARNING level
301-
verify(mockSession, times(1)).sendNotification(eq(McpSchema.METHOD_NOTIFICATION_MESSAGE),
276+
verify(mockSession, times(1)).isNotificationForLevelAllowed(eq(McpSchema.LoggingLevel.WARNING));
277+
verify(mockSession, never()).sendNotification(eq(McpSchema.METHOD_NOTIFICATION_MESSAGE),
302278
eq(warningNotification));
303-
304-
// Test ERROR (should be sent)
305-
McpSchema.LoggingMessageNotification errorNotification = McpSchema.LoggingMessageNotification.builder()
306-
.level(McpSchema.LoggingLevel.ERROR)
307-
.logger("test-logger")
308-
.data("Error message")
309-
.build();
310-
311-
when(mockSession.sendNotification(eq(McpSchema.METHOD_NOTIFICATION_MESSAGE), eq(errorNotification)))
312-
.thenReturn(Mono.empty());
313-
314-
StepVerifier.create(exchange.loggingNotification(errorNotification)).verifyComplete();
315-
316-
// Verify that sendNotification was called exactly once for ERROR level
317-
verify(mockSession, times(1)).sendNotification(eq(McpSchema.METHOD_NOTIFICATION_MESSAGE),
318-
eq(errorNotification));
319-
}
320-
321-
@Test
322-
void testLoggingNotificationWithDefaultLevel() {
323-
324-
McpSchema.LoggingMessageNotification infoNotification = McpSchema.LoggingMessageNotification.builder()
325-
.level(McpSchema.LoggingLevel.INFO)
326-
.logger("test-logger")
327-
.data("Info message")
328-
.build();
329-
330-
when(mockSession.sendNotification(eq(McpSchema.METHOD_NOTIFICATION_MESSAGE), eq(infoNotification)))
331-
.thenReturn(Mono.empty());
332-
333-
StepVerifier.create(exchange.loggingNotification(infoNotification)).verifyComplete();
334-
335-
// Verify that sendNotification was called exactly once for default level
336-
verify(mockSession, times(1)).sendNotification(eq(McpSchema.METHOD_NOTIFICATION_MESSAGE), eq(infoNotification));
337279
}
338280

339281
@Test
340282
void testLoggingNotificationWithSessionError() {
341-
342283
McpSchema.LoggingMessageNotification notification = McpSchema.LoggingMessageNotification.builder()
343284
.level(McpSchema.LoggingLevel.ERROR)
344285
.logger("test-logger")
345286
.data("Test error message")
346287
.build();
347288

289+
when(mockSession.isNotificationForLevelAllowed(any())).thenReturn(Boolean.TRUE);
348290
when(mockSession.sendNotification(eq(McpSchema.METHOD_NOTIFICATION_MESSAGE), eq(notification)))
349291
.thenReturn(Mono.error(new RuntimeException("Session error")));
350292

@@ -353,44 +295,6 @@ void testLoggingNotificationWithSessionError() {
353295
});
354296
}
355297

356-
@Test
357-
void testSetMinLoggingLevelWithNullValue() {
358-
// When & Then
359-
assertThatThrownBy(() -> exchange.setMinLoggingLevel(null)).isInstanceOf(IllegalArgumentException.class)
360-
.hasMessage("minLoggingLevel must not be null");
361-
}
362-
363-
@Test
364-
void testLoggingLevelHierarchy() {
365-
// Test all logging levels to ensure proper hierarchy
366-
McpSchema.LoggingLevel[] levels = { McpSchema.LoggingLevel.DEBUG, McpSchema.LoggingLevel.INFO,
367-
McpSchema.LoggingLevel.NOTICE, McpSchema.LoggingLevel.WARNING, McpSchema.LoggingLevel.ERROR,
368-
McpSchema.LoggingLevel.CRITICAL, McpSchema.LoggingLevel.ALERT, McpSchema.LoggingLevel.EMERGENCY };
369-
370-
// Set minimum level to WARNING
371-
exchange.setMinLoggingLevel(McpSchema.LoggingLevel.WARNING);
372-
373-
for (McpSchema.LoggingLevel level : levels) {
374-
McpSchema.LoggingMessageNotification notification = McpSchema.LoggingMessageNotification.builder()
375-
.level(level)
376-
.logger("test-logger")
377-
.data("Test message for " + level)
378-
.build();
379-
380-
if (level.level() >= McpSchema.LoggingLevel.WARNING.level()) {
381-
// Should be sent
382-
when(mockSession.sendNotification(eq(McpSchema.METHOD_NOTIFICATION_MESSAGE), eq(notification)))
383-
.thenReturn(Mono.empty());
384-
385-
StepVerifier.create(exchange.loggingNotification(notification)).verifyComplete();
386-
}
387-
else {
388-
// Should be filtered (completes without sending)
389-
StepVerifier.create(exchange.loggingNotification(notification)).verifyComplete();
390-
}
391-
}
392-
}
393-
394298
// ---------------------------------------
395299
// Create Elicitation Tests
396300
// ---------------------------------------

mcp/src/test/java/io/modelcontextprotocol/server/McpSyncServerExchangeTests.java

Lines changed: 14 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -226,113 +226,49 @@ void testLoggingNotificationWithAllowedLevel() {
226226
.data("Test error message")
227227
.build();
228228

229+
when(mockSession.isNotificationForLevelAllowed(any())).thenReturn(Boolean.TRUE);
229230
when(mockSession.sendNotification(eq(McpSchema.METHOD_NOTIFICATION_MESSAGE), eq(notification)))
230231
.thenReturn(Mono.empty());
231232

232233
exchange.loggingNotification(notification);
233234

234235
// Verify that sendNotification was called exactly once
236+
verify(mockSession, times(1)).isNotificationForLevelAllowed(eq(McpSchema.LoggingLevel.ERROR));
235237
verify(mockSession, times(1)).sendNotification(eq(McpSchema.METHOD_NOTIFICATION_MESSAGE), eq(notification));
236238
}
237239

238240
@Test
239241
void testLoggingNotificationWithFilteredLevel() {
240-
// Given - Set minimum level to WARNING, send DEBUG message
241-
asyncExchange.setMinLoggingLevel(McpSchema.LoggingLevel.WARNING);
242+
asyncExchange.setMinLoggingLevel(McpSchema.LoggingLevel.DEBUG);
243+
verify(mockSession, times(1)).setMinLoggingLevel(McpSchema.LoggingLevel.DEBUG);
242244

243245
McpSchema.LoggingMessageNotification debugNotification = McpSchema.LoggingMessageNotification.builder()
244246
.level(McpSchema.LoggingLevel.DEBUG)
245247
.logger("test-logger")
246248
.data("Debug message that should be filtered")
247249
.build();
248250

249-
// When & Then - Should complete without sending notification
250-
exchange.loggingNotification(debugNotification);
251-
252-
// Verify that sendNotification was never called for filtered DEBUG level
253-
verify(mockSession, never()).sendNotification(eq(McpSchema.METHOD_NOTIFICATION_MESSAGE), eq(debugNotification));
254-
}
255-
256-
@Test
257-
void testLoggingNotificationLevelFiltering() {
258-
// Given - Set minimum level to WARNING
259-
asyncExchange.setMinLoggingLevel(McpSchema.LoggingLevel.WARNING);
260-
261-
// Test DEBUG (should be filtered)
262-
McpSchema.LoggingMessageNotification debugNotification = McpSchema.LoggingMessageNotification.builder()
263-
.level(McpSchema.LoggingLevel.DEBUG)
264-
.logger("test-logger")
265-
.data("Debug message")
266-
.build();
251+
when(mockSession.isNotificationForLevelAllowed(eq(McpSchema.LoggingLevel.DEBUG))).thenReturn(Boolean.TRUE);
252+
when(mockSession.sendNotification(eq(McpSchema.METHOD_NOTIFICATION_MESSAGE), eq(debugNotification)))
253+
.thenReturn(Mono.empty());
267254

268255
exchange.loggingNotification(debugNotification);
269256

270-
// Verify that sendNotification was never called for DEBUG level
271-
verify(mockSession, never()).sendNotification(eq(McpSchema.METHOD_NOTIFICATION_MESSAGE), eq(debugNotification));
272-
273-
// Test INFO (should be filtered)
274-
McpSchema.LoggingMessageNotification infoNotification = McpSchema.LoggingMessageNotification.builder()
275-
.level(McpSchema.LoggingLevel.INFO)
276-
.logger("test-logger")
277-
.data("Info message")
278-
.build();
279-
280-
exchange.loggingNotification(infoNotification);
281-
282-
// Verify that sendNotification was never called for INFO level
283-
verify(mockSession, never()).sendNotification(eq(McpSchema.METHOD_NOTIFICATION_MESSAGE), eq(infoNotification));
284-
285-
reset(mockSession);
257+
verify(mockSession, times(1)).isNotificationForLevelAllowed(McpSchema.LoggingLevel.DEBUG);
258+
verify(mockSession, times(1)).sendNotification(eq(McpSchema.METHOD_NOTIFICATION_MESSAGE),
259+
eq(debugNotification));
286260

287-
// Test WARNING (should be sent)
288261
McpSchema.LoggingMessageNotification warningNotification = McpSchema.LoggingMessageNotification.builder()
289262
.level(McpSchema.LoggingLevel.WARNING)
290263
.logger("test-logger")
291-
.data("Warning message")
264+
.data("Debug message that should be filtered")
292265
.build();
293266

294-
when(mockSession.sendNotification(eq(McpSchema.METHOD_NOTIFICATION_MESSAGE), eq(warningNotification)))
295-
.thenReturn(Mono.empty());
296-
297267
exchange.loggingNotification(warningNotification);
298268

299-
// Verify that sendNotification was called exactly once for WARNING level
300-
verify(mockSession, times(1)).sendNotification(eq(McpSchema.METHOD_NOTIFICATION_MESSAGE),
269+
verify(mockSession, times(1)).isNotificationForLevelAllowed(McpSchema.LoggingLevel.WARNING);
270+
verify(mockSession, never()).sendNotification(eq(McpSchema.METHOD_NOTIFICATION_MESSAGE),
301271
eq(warningNotification));
302-
303-
// Test ERROR (should be sent)
304-
McpSchema.LoggingMessageNotification errorNotification = McpSchema.LoggingMessageNotification.builder()
305-
.level(McpSchema.LoggingLevel.ERROR)
306-
.logger("test-logger")
307-
.data("Error message")
308-
.build();
309-
310-
when(mockSession.sendNotification(eq(McpSchema.METHOD_NOTIFICATION_MESSAGE), eq(errorNotification)))
311-
.thenReturn(Mono.empty());
312-
313-
exchange.loggingNotification(errorNotification);
314-
315-
// Verify that sendNotification was called exactly once for ERROR level
316-
verify(mockSession, times(1)).sendNotification(eq(McpSchema.METHOD_NOTIFICATION_MESSAGE),
317-
eq(errorNotification));
318-
}
319-
320-
@Test
321-
void testLoggingNotificationWithDefaultLevel() {
322-
323-
McpSchema.LoggingMessageNotification infoNotification = McpSchema.LoggingMessageNotification.builder()
324-
.level(McpSchema.LoggingLevel.INFO)
325-
.logger("test-logger")
326-
.data("Info message")
327-
.build();
328-
329-
when(mockSession.sendNotification(eq(McpSchema.METHOD_NOTIFICATION_MESSAGE), eq(infoNotification)))
330-
.thenReturn(Mono.empty());
331-
332-
exchange.loggingNotification(infoNotification);
333-
334-
// Verify that sendNotification was called exactly once for default level
335-
verify(mockSession, times(1)).sendNotification(eq(McpSchema.METHOD_NOTIFICATION_MESSAGE), eq(infoNotification));
336272
}
337273

338274
@Test
@@ -344,44 +280,14 @@ void testLoggingNotificationWithSessionError() {
344280
.data("Test error message")
345281
.build();
346282

283+
when(mockSession.isNotificationForLevelAllowed(any())).thenReturn(Boolean.TRUE);
347284
when(mockSession.sendNotification(eq(McpSchema.METHOD_NOTIFICATION_MESSAGE), eq(notification)))
348285
.thenReturn(Mono.error(new RuntimeException("Session error")));
349286

350287
assertThatThrownBy(() -> exchange.loggingNotification(notification)).isInstanceOf(RuntimeException.class)
351288
.hasMessage("Session error");
352289
}
353290

354-
@Test
355-
void testLoggingLevelHierarchy() {
356-
// Test all logging levels to ensure proper hierarchy
357-
McpSchema.LoggingLevel[] levels = { McpSchema.LoggingLevel.DEBUG, McpSchema.LoggingLevel.INFO,
358-
McpSchema.LoggingLevel.NOTICE, McpSchema.LoggingLevel.WARNING, McpSchema.LoggingLevel.ERROR,
359-
McpSchema.LoggingLevel.CRITICAL, McpSchema.LoggingLevel.ALERT, McpSchema.LoggingLevel.EMERGENCY };
360-
361-
// Set minimum level to WARNING
362-
asyncExchange.setMinLoggingLevel(McpSchema.LoggingLevel.WARNING);
363-
364-
for (McpSchema.LoggingLevel level : levels) {
365-
McpSchema.LoggingMessageNotification notification = McpSchema.LoggingMessageNotification.builder()
366-
.level(level)
367-
.logger("test-logger")
368-
.data("Test message for " + level)
369-
.build();
370-
371-
if (level.level() >= McpSchema.LoggingLevel.WARNING.level()) {
372-
// Should be sent
373-
when(mockSession.sendNotification(eq(McpSchema.METHOD_NOTIFICATION_MESSAGE), eq(notification)))
374-
.thenReturn(Mono.empty());
375-
376-
exchange.loggingNotification(notification);
377-
}
378-
else {
379-
// Should be filtered (completes without sending)
380-
exchange.loggingNotification(notification);
381-
}
382-
}
383-
}
384-
385291
// ---------------------------------------
386292
// Create Elicitation Tests
387293
// ---------------------------------------

0 commit comments

Comments
 (0)