From 44720f4dc06c5a58b95ca25345b5be0f91ed5a6d Mon Sep 17 00:00:00 2001 From: Russell Cohen Date: Tue, 3 Nov 2020 18:44:38 -0500 Subject: [PATCH] Productionize Integration Test Machinery (#15) * Productionize Integration Test Machinery smithy-build.json is now dynamically generated along with a Cargo.toml to facilitate easy adding of new integration tests. * We don't need REPO_ROOT anymore --- .github/workflows/ci.yaml | 6 +- codegen-test/.gitignore | 1 + codegen-test/README.md | 9 +-- codegen-test/build.gradle.kts | 73 ++++++++++++++++++- codegen-test/smithy-build.json | 17 ----- .../rust/codegen/smithy/SymbolVisitor.kt | 3 +- test.sh | 4 - 7 files changed, 79 insertions(+), 34 deletions(-) create mode 100644 codegen-test/.gitignore delete mode 100644 codegen-test/smithy-build.json diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index f669da25e..243ac99fb 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -80,11 +80,8 @@ jobs: uses: actions/setup-java@v1 with: java-version: 8 - - name: set REPO_ROOT - run: echo "REPO_ROOT=$GITHUB_WORKSPACE" >> $GITHUB_ENV - name: integration-tests run: ./gradlew :codegen-test:test - # TODO: when the multi repo integration tests are merged, update this to glob all of them - uses: actions/upload-artifact@v2 name: Upload Codegen Output for inspection # Always upload the output even if the tests failed @@ -92,7 +89,8 @@ jobs: with: name: codegen-output path: | - codegen-test/build/smithyprojections/codegen-test/source/rust-codegen/ + codegen-test/build/smithyprojections/codegen-test/*/rust-codegen/ + codegen-test/build/smithyprojections/codegen-test/Cargo.toml !**/target runtime-tests: name: Rust runtime tests diff --git a/codegen-test/.gitignore b/codegen-test/.gitignore new file mode 100644 index 000000000..c063d7f5f --- /dev/null +++ b/codegen-test/.gitignore @@ -0,0 +1 @@ +smithy-build.json diff --git a/codegen-test/README.md b/codegen-test/README.md index 9e09e7b68..a91b9adeb 100644 --- a/codegen-test/README.md +++ b/codegen-test/README.md @@ -1,11 +1,8 @@ # Codegen Integration Test -This module defines an integration test of the code generation machinery. Models defined in `model` are built and generated into a Rust package. A `cargoCheck` Gradle task ensures that the generated Rust code compiles. This is added as a finalizer of the `test` task. +This module defines an integration test of the code generation machinery. `.build.gradle.kts` will generate a `smithy-build.json` file as part of the build. The Smithy build plugin then invokes our codegen machinery and generates Rust crates. +The `test` task will run `cargo check` and `cargo clippy` to validate that the generated Rust compiles and is idiomatic. ## Usage ``` -# Compile codegen, Regenerate Rust, compile: -# REPO_ROOT allows the runtime deps to be specified properly: -REPO_ROOT=../ ../gradlew test +../gradlew test ``` - -The `smithy-build.json` configures the runtime dependencies to point directly to `../rust-runtime/*` via relative paths. \ No newline at end of file diff --git a/codegen-test/build.gradle.kts b/codegen-test/build.gradle.kts index adcb07081..8e6a6a69e 100644 --- a/codegen-test/build.gradle.kts +++ b/codegen-test/build.gradle.kts @@ -16,12 +16,77 @@ val smithyVersion: String by project dependencies { implementation(project(":codegen")) + implementation("software.amazon.smithy:smithy-aws-protocol-tests:$smithyVersion") implementation("software.amazon.smithy:smithy-protocol-test-traits:$smithyVersion") implementation("software.amazon.smithy:smithy-aws-traits:$smithyVersion") } +data class CodegenTest(val service: String, val module: String) + +val CodgenTests = listOf( + CodegenTest("com.amazonaws.dynamodb#DynamoDB_20120810", "dynamo"), + CodegenTest("com.amazonaws.ebs#Ebs", "ebs"), + CodegenTest("aws.protocoltests.json10#JsonRpc10", "json_rpc10") +) + +fun generateSmithyBuild(tests: List): String { + val projections = tests.joinToString(",\n") { + """ + "${it.module}": { + "plugins": { + "rust-codegen": { + "runtimeConfig": { + "relativePath": "${rootProject.projectDir.absolutePath}/rust-runtime" + }, + "service": "${it.service}", + "module": "${it.module}", + "moduleVersion": "0.0.1", + "build": { + "rootProject": true + } + } + } + } + """.trimIndent() + } + return """ + { + "version": "1.0", + "projections": { $projections } + } + """ +} + + +task("generateSmithyBuild") { + description = "generate smithy-build.json" + doFirst { + projectDir.resolve("smithy-build.json").writeText(generateSmithyBuild(CodgenTests)) + } +} + + +fun generateCargoWorkspace(tests: List): String { + return """ + [workspace] + members = [ + ${tests.joinToString(",") { "\"${it.module}/rust-codegen\"" }} + ] + """.trimIndent() +} +task("generateCargoWorkspace") { + description = "generate Cargo.toml workspace file" + doFirst { + buildDir.resolve("smithyprojections/codegen-test/Cargo.toml").writeText(generateCargoWorkspace(CodgenTests)) + } +} + +tasks["smithyBuildJar"].dependsOn("generateSmithyBuild") +tasks["build"].finalizedBy("generateCargoWorkspace") + + tasks.register("cargoCheck") { - workingDir("build/smithyprojections/codegen-test/source/rust-codegen/") + workingDir("build/smithyprojections/codegen-test/") // disallow warnings environment("RUSTFLAGS", "-D warnings") commandLine("cargo", "check") @@ -29,7 +94,7 @@ tasks.register("cargoCheck") { } tasks.register("cargoClippy") { - workingDir("build/smithyprojections/codegen-test/source/rust-codegen/") + workingDir("build/smithyprojections/codegen-test/") // disallow warnings environment("RUSTFLAGS", "-D warnings") commandLine("cargo", "clippy") @@ -37,3 +102,7 @@ tasks.register("cargoClippy") { } tasks["test"].finalizedBy("cargoCheck", "cargoClippy") + +tasks["clean"].doFirst { + delete("smithy-build.json") +} diff --git a/codegen-test/smithy-build.json b/codegen-test/smithy-build.json deleted file mode 100644 index d8f11ec32..000000000 --- a/codegen-test/smithy-build.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "version": "1.0", - "outputDirectory": "target", - "plugins": { - "rust-codegen": { - "runtimeConfig": { - "relativePath": "${REPO_ROOT}/rust-runtime" - }, - "service": "com.amazonaws.ebs#Ebs", - "module": "weather", - "moduleVersion": "0.0.1", - "build": { - "rootProject": true - } - } - } -} diff --git a/codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/SymbolVisitor.kt b/codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/SymbolVisitor.kt index 26b2792b4..ac993f025 100644 --- a/codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/SymbolVisitor.kt +++ b/codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/SymbolVisitor.kt @@ -178,7 +178,8 @@ class SymbolVisitor( } override fun mapShape(shape: MapShape): Symbol { - require(shape.key.isStringShape) + val target = model.expectShape(shape.key.target) + require(target.isStringShape) { "unexpected key shape: ${shape.key}: $target [keys must be strings]" } val key = this.toSymbol(shape.key) val value = this.toSymbol(shape.value) return symbolBuilder(shape, RustType.HashMap(key.rustType(), value.rustType())).namespace( diff --git a/test.sh b/test.sh index 838965a68..3935e22d9 100755 --- a/test.sh +++ b/test.sh @@ -5,10 +5,6 @@ # set -e -# Used by codegen-test/smithy-build.json -declare REPO_ROOT -REPO_ROOT="$(git rev-parse --show-toplevel)" -export REPO_ROOT ./gradlew test ./gradlew ktlintFormat ./gradlew ktlint \ No newline at end of file -- GitLab