Add type provider integration tests for CancellationToken-overloaded methods#338
Conversation
Co-authored-by: sergey-tihon <1197905+sergey-tihon@users.noreply.github.com> Agent-Logs-Url: https://github.com/fsprojects/SwaggerProvider/sessions/8363d577-d359-47b3-ae35-5f9003978db0
|
Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details. Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
|
@copilot ci still failing |
… invalid IL for structs Co-authored-by: sergey-tihon <1197905+sergey-tihon@users.noreply.github.com> Agent-Logs-Url: https://github.com/fsprojects/SwaggerProvider/sessions/cd02aac9-3f51-40c9-af2f-11d1eda31d77
Fixed in e74b3e2. Root cause: Fix: extract the CT argument by position (always the last parameter in the overload) and use Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
There was a problem hiding this comment.
Pull request overview
Adds end-to-end integration coverage for type-provider-generated CancellationToken overloads against the existing Swashbuckle test server, and updates the v3 operation invocation compiler to reliably extract the CT argument.
Changes:
- Add new v3 integration tests that call TP-generated methods with explicit
CancellationTokenarguments (including pre-cancelled token behavior). - Register the new test module in the provider test project with correct compile ordering.
- Adjust v3
OperationCompilerto extractCancellationTokenby argument position (last argument) instead of by name.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| tests/SwaggerProvider.ProviderTests/v3/Swashbuckle.CancellationToken.Tests.fs | New integration tests exercising CT overloads (GET/POST, active token, pre-cancelled token). |
| tests/SwaggerProvider.ProviderTests/SwaggerProvider.ProviderTests.fsproj | Includes the new test file after Swashbuckle.ReturnControllers.Tests.fs to reuse api. |
| src/SwaggerProvider.DesignTime/v3/OperationCompiler.fs | Changes CT extraction in provided method invoke code to be position-based and avoid prior name/cast issues. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // When the CancellationToken overload is generated, CancellationToken is always appended last. | ||
| // Extract it by position to avoid name-collision issues and invalid Expr.Coerce | ||
| // on a struct type (which generates an invalid castclass IL instruction). | ||
| let apiArgs, ct = | ||
| let allArgs = List.tail args // skip `this` | ||
|
|
||
| if includeCancellationToken then | ||
| match List.rev allArgs with | ||
| | ctArg :: revApiArgs -> List.rev revApiArgs, Expr.Cast<Threading.CancellationToken>(ctArg) | ||
| | [] -> failwith "Expected CancellationToken argument but argument list was empty" | ||
| else | ||
| allArgs, <@ Threading.CancellationToken.None @> |
There was a problem hiding this comment.
The PR title/description focuses on adding integration tests, but this hunk also changes type provider code generation behavior (CancellationToken argument extraction). Please update the PR description/title to reflect the compiler change (or split into a separate PR) so reviewers don’t miss the functional impact.
| if includeCancellationToken then | ||
| match List.rev allArgs with | ||
| | ctArg :: revApiArgs -> List.rev revApiArgs, Expr.Cast<Threading.CancellationToken>(ctArg) | ||
| | [] -> failwith "Expected CancellationToken argument but argument list was empty" |
There was a problem hiding this comment.
This failwith message is likely only hit when TP invocation arguments are unexpected, but it would be much easier to diagnose if it included the operation/method name (e.g., providedMethodName) and the received argument count. Consider switching to failwithf with that context.
| | [] -> failwith "Expected CancellationToken argument but argument list was empty" | |
| | [] -> | |
| failwithf | |
| "Method '%s' expected a CancellationToken argument as the last parameter but received %d argument(s)." | |
| providedMethodName | |
| allArgs.Length |
b2f0d80
into
repo-assist/feat-cancellationtoken-issue-212-2026-03-23-448c1cde90ec7d95
…vider generated methods (closes #212) (#336) * feat: add CancellationToken support to OpenApiClientProvider generated methods (closes #212) - Add CallAsync overload with CancellationToken to ProvidedApiClientBase - Thread CancellationToken from generated methods through to HttpClient.SendAsync - Each generated method gains an optional cancellationToken parameter (defaults to CancellationToken.None) - Backward-compatible: existing call sites without CT continue to work unchanged - Add unit tests: success with CancellationToken.None, cancellation propagation Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * ci: trigger checks * fix: replace optional struct CancellationToken parameter with method overloads (#337) * Initial plan * Fix: revert global.json and address CancellationToken build failures Co-authored-by: sergey-tihon <1197905+sergey-tihon@users.noreply.github.com> Agent-Logs-Url: https://github.com/fsprojects/SwaggerProvider/sessions/1861c3cb-6a0a-438a-aa31-f65b8c809f88 * fix: use method overloading for CancellationToken support instead of optional struct parameter Co-authored-by: sergey-tihon <1197905+sergey-tihon@users.noreply.github.com> Agent-Logs-Url: https://github.com/fsprojects/SwaggerProvider/sessions/1861c3cb-6a0a-438a-aa31-f65b8c809f88 --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: sergey-tihon <1197905+sergey-tihon@users.noreply.github.com> * Add type provider integration tests for CancellationToken-overloaded methods (#338) * Fix: CT parameter name uniqueness in CancellationToken overload generation (#339) * Initial plan * fix: generate unique CT parameter name to avoid collision with OpenAPI params named 'cancellationToken' Co-authored-by: sergey-tihon <1197905+sergey-tihon@users.noreply.github.com> Agent-Logs-Url: https://github.com/fsprojects/SwaggerProvider/sessions/7d588ec7-c4df-4a6c-89f8-9c13c2472d29 --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: sergey-tihon <1197905+sergey-tihon@users.noreply.github.com> * Fix CancellationToken parameter ordering and name collision in v3 OperationCompiler (#341) * Initial plan * fix: insert CT between required and optional params; generate unique CT name Co-authored-by: sergey-tihon <1197905+sergey-tihon@users.noreply.github.com> Agent-Logs-Url: https://github.com/fsprojects/SwaggerProvider/sessions/b0c519de-0186-40ca-8174-42ed67a5316a * fix: add explicit restore + --no-restore to BuildTests to fix NETSDK1005 Co-authored-by: sergey-tihon <1197905+sergey-tihon@users.noreply.github.com> Agent-Logs-Url: https://github.com/fsprojects/SwaggerProvider/sessions/565d6633-576d-4587-b924-a29b0ea53c2c --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: sergey-tihon <1197905+sergey-tihon@users.noreply.github.com> * refactor: use UniqueNameGenerator for CT param name uniqueness Replace hand-coded recursive findUniqueName function with the existing UniqueNameGenerator utility (already used in DefinitionCompiler and for method name deduplication in OperationCompiler). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * feat: add optional occupiedNames parameter to UniqueNameGenerator constructor Allows callers to pre-seed the generator with names that are already taken, so MakeUnique will never return any of those names without a numeric suffix. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * refactor: single CallAsync overload + single generated method with optional CancellationToken - Remove no-CT CallAsync overload from ProvidedApiClientBase; keep only the version with explicit CancellationToken (quotation code always supplies it) - Remove double-compilation in OperationCompiler: one method per operation with optional cancellationToken (null default = default(CancellationToken).None) - Update RuntimeHelpersTests to pass CancellationToken.None explicitly Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * cleanup: simplify OperationCompiler and add default/async CT tests - Use List.map instead of List.collect since compileOperation returns a single method - Clean up comments in OperationCompiler - Add test for calling generated method without CancellationToken (default token) - Add test for async (PreferAsync=true) generated method without CancellationToken * feat: propagate CancellationToken through ReadAsStringAsync/ReadAsStreamAsync via RuntimeHelpers Add readContentAsString and readContentAsStream wrappers to RuntimeHelpers with #if NET5_0_OR_GREATER guards, enabling CancellationToken propagation in generated quotation code that must compile against netstandard2.0. Also add explicit CancellationToken integration tests and conditional CT support in ProvidedApiClientBase error path. * test: add CT coverage for stream, text/plain, async cancellation, and async POST paths * fix: async tests --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com> Co-authored-by: sergey-tihon <1197905+sergey-tihon@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Sergey Tihon <sergey.tihon@gmail.com>
The CancellationToken PR lacked integration tests that exercise the TP-generated CT overloads end-to-end against a real HTTP server.
Changes
v3/Swashbuckle.CancellationToken.Tests.fs— new test module with 4[<Fact>]tests calling TP-generated methods with explicit CT arguments:CancellationToken.Noneon GET and POST operationsCancellationTokenSourcetoken (happy path)OperationCanceledExceptionSwaggerProvider.ProviderTests.fsproj— includes the new file, ordered afterSwashbuckle.ReturnControllers.Tests.fs(which defines theapiinstance these tests reuse)✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.