-
Notifications
You must be signed in to change notification settings - Fork 154
Add Stdio coverage for integration tests #276
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR adds integration test coverage for the Stdio transport mechanism to complement the existing SSE transport tests. The tests have been refactored to eliminate duplication by extracting abstract base classes and organizing tests by transport type.
Key Changes
- Added support for Stdio transport alongside existing SSE transport tests
- Refactored test structure using abstract base classes to reduce code duplication
- Reorganized test files into transport-specific packages (stdio and sse)
Reviewed Changes
Copilot reviewed 30 out of 32 changed files in this pull request and generated 9 comments.
Show a summary per file
File | Description |
---|---|
kotlin-sdk-test/src/jvmTest/kotlin/io/modelcontextprotocol/kotlin/sdk/integration/typescript/stdio/*.ts | TypeScript server and client implementations for Stdio transport testing |
kotlin-sdk-test/src/jvmTest/kotlin/io/modelcontextprotocol/kotlin/sdk/integration/typescript/stdio/*.kt | Kotlin test classes for Stdio transport scenarios |
kotlin-sdk-test/src/jvmTest/kotlin/io/modelcontextprotocol/kotlin/sdk/integration/typescript/TsTestBase.kt | New consolidated base class supporting both SSE and Stdio transports |
kotlin-sdk-test/src/jvmTest/kotlin/io/modelcontextprotocol/kotlin/sdk/integration/typescript/Abstract*.kt | Abstract base classes to eliminate test duplication |
kotlin-sdk-test/src/jvmTest/kotlin/io/modelcontextprotocol/kotlin/sdk/integration/kotlin/Test.kt | Refactored Kotlin integration tests using abstract base classes |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
...vmTest/kotlin/io/modelcontextprotocol/kotlin/sdk/integration/typescript/stdio/simpleStdio.ts
Show resolved
Hide resolved
...vmTest/kotlin/io/modelcontextprotocol/kotlin/sdk/integration/typescript/stdio/simpleStdio.ts
Show resolved
Hide resolved
...vmTest/kotlin/io/modelcontextprotocol/kotlin/sdk/integration/typescript/stdio/simpleStdio.ts
Show resolved
Hide resolved
...tlin/io/modelcontextprotocol/kotlin/sdk/integration/kotlin/stdio/ToolIntegrationTestStdio.kt
Show resolved
Hide resolved
.../io/modelcontextprotocol/kotlin/sdk/integration/kotlin/stdio/ResourceIntegrationTestStdio.kt
Show resolved
Hide resolved
...in/io/modelcontextprotocol/kotlin/sdk/integration/kotlin/stdio/PromptIntegrationTestStdio.kt
Show resolved
Hide resolved
...t/kotlin/io/modelcontextprotocol/kotlin/sdk/integration/kotlin/sse/ToolIntegrationTestSse.kt
Show resolved
Hide resolved
...tlin/io/modelcontextprotocol/kotlin/sdk/integration/kotlin/sse/ResourceIntegrationTestSse.kt
Show resolved
Hide resolved
...kotlin/io/modelcontextprotocol/kotlin/sdk/integration/kotlin/sse/PromptIntegrationTestSse.kt
Show resolved
Hide resolved
…ontextprotocol#267) Ignore flaky `testMultipleClientParallel`
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you @skarpovdev for adding tests! ❤️ LGTM
The follow-ups:
- Avoid cloning the MCP TypeScript SDK on every run. Prefer creating and reusing a Docker image with a fixed package version/hash.
- Check for duplications
- Consider switching to JUnit Pioneer for retryable tests and to Kotest assertions and for better readability. Especially, try avoiding asserting JSONs as a string.
@JvmStatic | ||
@BeforeAll | ||
fun setupTypeScriptSdk() { | ||
println("Cloning TypeScript SDK repository") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Wow! Would it be possible to use some Docker image with the TS SDK? There might be an official one. Not a blocker tho
return outputReader | ||
} | ||
|
||
private fun createProcessErrorReader(process: Process, prefix: String = "TS-SERVER"): Thread { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
duplicate of createProcessOutputReader
?
protected suspend fun <T> withClient(serverUrl: String, block: suspend (Client) -> T): T { | ||
val client = newClient(serverUrl) | ||
return try { | ||
withTimeout(20.seconds) { block(client) } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Normally, tests should finish much faster than 20 seconds
serverThread.start() | ||
|
||
// Read ONLY stderr from client for human-readable output | ||
val output = StringBuilder() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It' more safe to use StringBuffer if writing will happen in a different thread
val process = ProcessBuilder( | ||
"git", | ||
"clone", | ||
"--depth", | ||
"1", | ||
"https://github.com/modelcontextprotocol/typescript-sdk.git", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can be done before tests and reused, instead of cloning the repo on every test. Also, the TS SDK commit should be pinned to avoid introducing flakiness.
Instead of cloning the repo, it makes sense to create a Docker image with the MCP TypeScript SDK preinstalled, and reuse this image in tests.
@kpavlov Thank you for the review! I agree with all your points and will address them in a separet PR. |
| Package | Type | Package file | Manager | Update | Change | |---|---|---|---|---|---| | [org.mockito:mockito-core](https://github.com/mockito/mockito) | dependencies | misk/gradle/libs.versions.toml | gradle | minor | `5.19.0` -> `5.20.0` | | [io.modelcontextprotocol:kotlin-sdk-server](https://github.com/modelcontextprotocol/kotlin-sdk) | dependencies | misk/gradle/libs.versions.toml | gradle | patch | `0.7.1` -> `0.7.2` | | [io.modelcontextprotocol:kotlin-sdk-core](https://github.com/modelcontextprotocol/kotlin-sdk) | dependencies | misk/gradle/libs.versions.toml | gradle | patch | `0.7.1` -> `0.7.2` | | [io.modelcontextprotocol:kotlin-sdk-client](https://github.com/modelcontextprotocol/kotlin-sdk) | dependencies | misk/gradle/libs.versions.toml | gradle | patch | `0.7.0` -> `0.7.2` | | [com.google.errorprone:error_prone_annotations](https://errorprone.info) ([source](https://github.com/google/error-prone)) | dependencies | misk/gradle/libs.versions.toml | gradle | minor | `2.41.0` -> `2.42.0` | | [software.amazon.awssdk:sdk-core](https://aws.amazon.com/sdkforjava) | dependencies | misk/gradle/libs.versions.toml | gradle | minor | `2.33.13` -> `2.34.0` | | [software.amazon.awssdk:sqs](https://aws.amazon.com/sdkforjava) | dependencies | misk/gradle/libs.versions.toml | gradle | minor | `2.33.13` -> `2.34.0` | | [software.amazon.awssdk:s3](https://aws.amazon.com/sdkforjava) | dependencies | misk/gradle/libs.versions.toml | gradle | minor | `2.33.13` -> `2.34.0` | | [software.amazon.awssdk:regions](https://aws.amazon.com/sdkforjava) | dependencies | misk/gradle/libs.versions.toml | gradle | minor | `2.33.13` -> `2.34.0` | | [software.amazon.awssdk:dynamodb-enhanced](https://aws.amazon.com/sdkforjava) | dependencies | misk/gradle/libs.versions.toml | gradle | minor | `2.33.13` -> `2.34.0` | | [software.amazon.awssdk:dynamodb](https://aws.amazon.com/sdkforjava) | dependencies | misk/gradle/libs.versions.toml | gradle | minor | `2.33.13` -> `2.34.0` | | [software.amazon.awssdk:aws-core](https://aws.amazon.com/sdkforjava) | dependencies | misk/gradle/libs.versions.toml | gradle | minor | `2.33.13` -> `2.34.0` | | [software.amazon.awssdk:bom](https://aws.amazon.com/sdkforjava) | dependencies | misk/gradle/libs.versions.toml | gradle | minor | `2.33.13` -> `2.34.0` | | [software.amazon.awssdk:auth](https://aws.amazon.com/sdkforjava) | dependencies | misk/gradle/libs.versions.toml | gradle | minor | `2.33.13` -> `2.34.0` | --- ### Release Notes <details> <summary>mockito/mockito (org.mockito:mockito-core)</summary> ### [`v5.20.0`](https://github.com/mockito/mockito/releases/tag/v5.20.0) <sup><sup>*Changelog generated by [Shipkit Changelog Gradle Plugin](https://github.com/shipkit/shipkit-changelog)*</sup></sup> ##### 5.20.0 - 2025-09-20 - [11 commit(s)](mockito/mockito@v5.19.0...v5.20.0) by Adrian-Kim, Giulio Longfils, Rafael Winterhalter, dependabot\[bot] - Bump org.assertj:assertj-core from 3.27.4 to 3.27.5 [(#​3730)](mockito/mockito#3730) - Introducing the Ability to Mock Construction of Generic Types ([#​2401](mockito/mockito#2401)) [(#​3729)](mockito/mockito#3729) - Bump com.gradle.develocity from 4.1.1 to 4.2 [(#​3726)](mockito/mockito#3726) - Bump graalvm/setup-graalvm from 1.3.6 to 1.3.7 [(#​3725)](mockito/mockito#3725) - Bump org.eclipse.platform:org.eclipse.osgi from 3.23.100 to 3.23.200 [(#​3720)](mockito/mockito#3720) - Bump graalvm/setup-graalvm from 1.3.5 to 1.3.6 [(#​3719)](mockito/mockito#3719) - Bump actions/setup-java from 4 to 5 [(#​3715)](mockito/mockito#3715) - Bump com.gradle.develocity from 4.1 to 4.1.1 [(#​3713)](mockito/mockito#3713) - Bump bytebuddy from 1.17.6 to 1.17.7 [(#​3712)](mockito/mockito#3712) - test: Use Assume.assumeThat for SequencedCollection tests [(#​3711)](mockito/mockito#3711) - Fix [#​3709](mockito/mockito#3709) [(#​3710)](mockito/mockito#3710) - feat: Add support for JDK21 Sequenced Collections. [(#​3708)](mockito/mockito#3708) - Introducing the Ability to Mock Construction of Generic Types [(#​2401)](mockito/mockito#2401) </details> <details> <summary>modelcontextprotocol/kotlin-sdk (io.modelcontextprotocol:kotlin-sdk-server)</summary> ### [`v0.7.2`](https://github.com/modelcontextprotocol/kotlin-sdk/releases/tag/0.7.2) [Compare Source](modelcontextprotocol/kotlin-sdk@0.7.1...0.7.2) ##### What's Changed - migration from `jreleaser` to `mavenPublish` plugin by [@​devcrocod](https://github.com/devcrocod) in [#​277](modelcontextprotocol/kotlin-sdk#277) - Generate test report by [@​kpavlov](https://github.com/kpavlov) in [#​271](modelcontextprotocol/kotlin-sdk#271) - Move `generateLibVersion` task to `kotlin-sdk-core` by [@​devcrocod](https://github.com/devcrocod) in [#​274](modelcontextprotocol/kotlin-sdk#274) - [#​196](modelcontextprotocol/kotlin-sdk#196) Update build configuration and workflows for enhanced local publ… by [@​kpavlov](https://github.com/kpavlov) in [#​275](modelcontextprotocol/kotlin-sdk#275) - Add Stdio coverage for integration tests by [@​skarpovdev](https://github.com/skarpovdev) in [#​276](modelcontextprotocol/kotlin-sdk#276) - Bump io.kotest:kotest-assertions-json from 5.9.1 to 6.0.3 by [@​dependabot](https://github.com/dependabot)\[bot] in [#​247](modelcontextprotocol/kotlin-sdk#247) - migration from `jreleaser` to `mavenPublish` plugin by [@​devcrocod](https://github.com/devcrocod) in [#​277](modelcontextprotocol/kotlin-sdk#277) **Full Changelog**: <modelcontextprotocol/kotlin-sdk@0.7.1...0.7.2> </details> <details> <summary>google/error-prone (com.google.errorprone:error_prone_annotations)</summary> ### [`v2.42.0`](https://github.com/google/error-prone/releases/tag/v2.42.0): Error Prone 2.42.0 New checks: - [`ExplicitArrayForVarargs`](https://errorprone.info/bugpattern/ExplicitArrayForVarargs): discourage unnecessary explicit construction of an array to provide varargs. - [`FloggerPerWithoutRateLimit`](https://errorprone.info/bugpattern/FloggerPerWithoutRateLimit): discourage Flogger's `perUnique` without rate limiting - [`StringJoin`](https://errorprone.info/bugpattern/StringJoin): Ban `String.join(CharSequence)` and `String.join(CharSequence, CharSequence)` - [`ThreadBuilderNameWithPlaceholder`](https://errorprone.info/bugpattern/ThreadBuilderNameWithPlaceholder): Do not allow placeholders in `Thread.Builder.name(String)` or `name(String, int)`. Changes: - The return type of `ASTHelpers.asFlagSet` has changed. The previous type was `EnumSet<Flags.Flag>`, where `Flags.Flag` is an enum in the javac class `Flags`. A recent JDK change has replaced that enum with a new top-level enum called `FlagsEnum`. It is not possible to change `ASTHelpers.asFlagSet` in a way that would be type-safe and compatible with the enums from JDKs both before and after the change. Instead, the method now returns `ImmutableSet<String>`, where the strings come from the `toString()` of the enum constants. That means they are `"native"`, `"abstract"`, etc. - Flag `IO.print[ln]()` in [`SystemOut`](https://errorprone.info/bugpattern/SystemOut). Full changelog: <google/error-prone@v2.41.0...v2.42.0> </details> --- ### Configuration 📅 **Schedule**: Branch creation - "after 6pm every weekday,before 2am every weekday" in timezone Australia/Melbourne, Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Never, or you tick the rebase/retry checkbox. 👻 **Immortal**: This PR will be recreated if closed unmerged. Get [config help](https://github.com/renovatebot/renovate/discussions) if that's undesired. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). GitOrigin-RevId: 8ecb809cff408a555b4ee0773a9fb8cdca50b95c
This PR adds integration test coverage by covering the Stdio transport. The tests were refactored to accommodate Stdio without adding duplication.
Types of changes
Checklist
Additional context