-
Notifications
You must be signed in to change notification settings - Fork 252
Fix bugs with BDD codegen #4666
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
Merged
Merged
Changes from 8 commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
b9db402
Fix codegen bug with dynamodb BDD
landonxjames 8cc7498
Fix param name collision codegen bug in BDD
landonxjames 4011c4f
Update ddb model with BDD
landonxjames 9f4234d
Merge branch 'main' into landonxjames/bdd-fix
landonxjames 74826e0
Updates for failing EndpointResolverGeneratorTest
landonxjames 1b02e26
Merge branch 'main' into landonxjames/bdd-fix
landonxjames bf7b547
Proactively fix more potential BDD bugs
landonxjames d6d9fd6
Merge branch 'main' into landonxjames/bdd-fix
landonxjames 718865a
Cleaning up some doc references to spec files
landonxjames File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
271 changes: 224 additions & 47 deletions
271
...ware/amazon/smithy/rust/codegen/client/smithy/endpoint/generators/EndpointBddGenerator.kt
Large diffs are not rendered by default.
Oops, something went wrong.
250 changes: 207 additions & 43 deletions
250
...ware/amazon/smithy/rust/codegen/client/smithy/endpoint/rulesgen/BddExpressionGenerator.kt
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
110 changes: 110 additions & 0 deletions
110
.../test/kotlin/software/amazon/smithy/rust/codegen/client/smithy/endpoint/BddCodegenTest.kt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,110 @@ | ||
| /* | ||
| * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
| * SPDX-License-Identifier: Apache-2.0 | ||
| */ | ||
|
|
||
| package software.amazon.smithy.rust.codegen.client.smithy.endpoint | ||
|
|
||
| import org.junit.jupiter.api.Test | ||
| import software.amazon.smithy.rust.codegen.client.testutil.clientIntegrationTest | ||
| import software.amazon.smithy.rust.codegen.core.testutil.asSmithyModel | ||
|
|
||
| /** | ||
| * Regression tests for BDD codegen bugs identified in `.kiro/bdd-codegen-risk-analysis.md`. | ||
| * | ||
| * Bug #1 (`tryGenerateTrivialCondition.visitBoolEquals` does not gate on `ref.isOptional`) is | ||
| * unreachable through valid Smithy models — Smithy's own trait validator rejects | ||
| * `booleanEquals(OptionalBool, literal)` before codegen runs, so no test is included. | ||
| * | ||
| * Bug #3 (`isStringTypedRef` defaulting to `true` on typecheck failure) cannot be triggered | ||
| * through a normal Smithy model because the typechecker runs during model load. The fix makes | ||
| * the fallback conservative regardless; see the comment on `isStringTypedRef` in | ||
| * `BddExpressionGenerator.kt`. | ||
| */ | ||
| class BddCodegenTest { | ||
| /** | ||
| * Bug #2 regression: `BddExpressionGenerator.isOptionalArgument` previously text-matched a | ||
| * `StringLiteral`'s raw value against parameter names. When a static literal happened to | ||
| * have the same text as an optional parameter (e.g. literal `"Bucket"` while a parameter | ||
| * `Bucket` is also declared), `wrapDefaultArg` wrapped the literal's lowering — `&str` — | ||
| * in `if let Some(param) = ... { param } else { return false }`. That produces invalid | ||
| * Rust because `&str` does not pattern-match `Some(_)`. | ||
| * | ||
| * Fix: `isOptionalSingleDynamicReference` now inspects the [Template] structure via | ||
| * `TemplateVisitor.visitSingleDynamicTemplate` and only flags the argument as optional | ||
| * when it is genuinely a one-element `{Reference}` template wrapping an optional ref. | ||
| * | ||
| * The model below intentionally collides a literal with a parameter name and exercises a | ||
| * library function call (`substring("Bucket", 0, 4, false)`). After the fix, codegen | ||
| * compiles cleanly. Before the fix, it failed to compile with E0308 — see | ||
| * `.kiro/bdd-codegen-test-failures.md`. | ||
|
landonxjames marked this conversation as resolved.
Outdated
|
||
| */ | ||
| @Test | ||
| fun `string literal whose text matches an optional parameter name is not falsely treated as optional`() { | ||
| val nodes = | ||
| BddTestHelpers.encodeNodes( | ||
| listOf( | ||
| // condition 0: high → result[1] (the endpoint), low → NoMatch terminal | ||
| BddTestHelpers.Node(0, BddTestHelpers.resultRef(1), -1), | ||
| ), | ||
| ) | ||
|
|
||
| val model = | ||
| """ | ||
| namespace test | ||
|
|
||
| use aws.protocols#awsJson1_1 | ||
| use smithy.rules#endpointBdd | ||
| use smithy.rules#clientContextParams | ||
|
|
||
| @awsJson1_1 | ||
| @clientContextParams( | ||
| Bucket: { type: "string", documentation: "An optional bucket parameter" } | ||
| ) | ||
| @endpointBdd({ | ||
| version: "1.1", | ||
| "parameters": { | ||
| "Bucket": { | ||
| "type": "string", | ||
| "required": false, | ||
| "documentation": "An optional bucket parameter" | ||
| } | ||
| }, | ||
| "conditions": [ | ||
| { | ||
| "fn": "substring", | ||
| "argv": ["Bucket", 0, 4, false] | ||
| } | ||
| ], | ||
| "results": [ | ||
| { | ||
| "conditions": [], | ||
| "endpoint": { | ||
| "url": "https://parsed.example.com", | ||
| "properties": {}, | ||
| "headers": {} | ||
| }, | ||
| "type": "endpoint" | ||
| } | ||
| ], | ||
| "root": 2, | ||
| "nodeCount": 2, | ||
| "nodes": "$nodes" | ||
| }) | ||
| service TestService { | ||
| version: "1.0", | ||
| operations: [TestOp] | ||
| } | ||
|
|
||
| operation TestOp { | ||
| input: TestInput | ||
| } | ||
|
|
||
| structure TestInput {} | ||
| """.asSmithyModel() | ||
|
|
||
| // Should compile cleanly. Before the fix, this threw CommandError with | ||
| // `mismatched types: expected str, found Option<_>` from the wrap. | ||
| clientIntegrationTest(model) | ||
| } | ||
| } | ||
48 changes: 48 additions & 0 deletions
48
.../test/kotlin/software/amazon/smithy/rust/codegen/client/smithy/endpoint/BddTestHelpers.kt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| /* | ||
| * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
| * SPDX-License-Identifier: Apache-2.0 | ||
| */ | ||
|
|
||
| package software.amazon.smithy.rust.codegen.client.smithy.endpoint | ||
|
|
||
| import java.nio.ByteBuffer | ||
| import java.nio.ByteOrder | ||
| import java.util.Base64 | ||
|
|
||
| /** | ||
| * Helpers for assembling minimal `@endpointBdd` traits inline in codegen tests. | ||
| * | ||
| * The BDD trait's `nodes` field is a base64-encoded sequence of signed 32-bit | ||
| * **big-endian** integer triples: `[conditionIndex, highRef, lowRef]`. A reference | ||
| * of `1` or `-1` is the NoMatch terminal; `>=100_000_000` encodes a result at | ||
| * `results[ref - 100_000_000]`. The first node (index 0) **must** be the | ||
| * canonical terminal `[-1, 1, -1]`. | ||
| * | ||
| * See `.kiro/bdd-sep.md` for the full encoding spec. | ||
|
landonxjames marked this conversation as resolved.
Outdated
|
||
| */ | ||
| internal object BddTestHelpers { | ||
| /** Triple of (conditionIndex, highRef, lowRef) for one BDD node. */ | ||
| data class Node(val conditionIndex: Int, val high: Int, val low: Int) | ||
|
|
||
| /** The canonical terminal node that must occupy index 0 of every BDD. */ | ||
| val TERMINAL = Node(-1, 1, -1) | ||
|
|
||
| /** Result reference for `results[index]`. Index 0 is the implicit NoMatchRule. */ | ||
| fun resultRef(index: Int): Int = 100_000_000 + index | ||
|
|
||
| /** | ||
| * Encodes a list of nodes as the base64 string the BDD trait expects. | ||
| * The first node is automatically the terminal — callers pass only the | ||
| * non-terminal nodes. | ||
| */ | ||
| fun encodeNodes(nodesAfterTerminal: List<Node>): String { | ||
| val all = listOf(TERMINAL) + nodesAfterTerminal | ||
| val buf = ByteBuffer.allocate(all.size * 12).order(ByteOrder.BIG_ENDIAN) | ||
| all.forEach { n -> | ||
| buf.putInt(n.conditionIndex) | ||
| buf.putInt(n.high) | ||
| buf.putInt(n.low) | ||
| } | ||
| return Base64.getEncoder().encodeToString(buf.array()) | ||
| } | ||
| } | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.