Skip to content

Commit

Permalink
misc: add rules engine codegen tests (#1459)
Browse files Browse the repository at this point in the history
  • Loading branch information
0marperez authored Dec 16, 2024
1 parent eb24838 commit ecab1a0
Show file tree
Hide file tree
Showing 4 changed files with 219 additions and 2 deletions.
4 changes: 2 additions & 2 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ coroutines-version = "1.9.0"
atomicfu-version = "0.25.0"

# smithy-kotlin codegen and runtime are versioned separately
smithy-kotlin-runtime-version = "1.3.29"
smithy-kotlin-codegen-version = "0.33.29"
smithy-kotlin-runtime-version = "1.3.30"
smithy-kotlin-codegen-version = "0.33.30"

# codegen
smithy-version = "1.51.0"
Expand Down
1 change: 1 addition & 0 deletions settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ include(":hll:hll-mapping-core")
include(":services")
include(":tests")
include(":tests:codegen:event-stream")
include(":tests:codegen:rules-engine")
include(":tests:e2e-test-util")
include(":tests:codegen:smoke-tests")
include(":tests:codegen:smoke-tests:services")
Expand Down
158 changes: 158 additions & 0 deletions tests/codegen/rules-engine/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/

import aws.sdk.kotlin.gradle.codegen.dsl.generateSmithyProjections
import aws.sdk.kotlin.gradle.codegen.dsl.smithyKotlinPlugin
import aws.sdk.kotlin.gradle.codegen.smithyKotlinProjectionSrcDir

plugins {
alias(libs.plugins.kotlin.jvm)
alias(libs.plugins.aws.kotlin.repo.tools.smithybuild)
}

description = "Smithy rules engine codegen integration test suite"

data class Test(
val projectionName: String,
val protocolName: String,
val modelTemplate: File,
) {
val model: File
get() = layout.buildDirectory.file("$projectionName/model.smithy").get().asFile
}

val tests = listOf(
Test("operationContextParams", "operationContextParams", file("operation-context-params.smithy")),
)

fun fillInModel(output: File, protocolName: String, template: File) {
val input = template.readText()
val opTraits = when (protocolName) {
"restJson1", "restXml" -> """@http(method: "POST", uri: "/test-eventstream", code: 200)"""
else -> ""
}
val replaced = input
.replace("{protocol-name}", protocolName)
.replace("{op-traits}", opTraits)

output.parentFile.mkdirs()
output.writeText(replaced)
}

val testServiceShapeId = "aws.sdk.kotlin.test#TestService"
smithyBuild {
tests.forEach { test ->

projections.register(test.projectionName) {
imports = listOf(test.model.absolutePath)
transforms = listOf(
"""
{
"name": "includeServices",
"args": {
"services": ["$testServiceShapeId"]
}
}
""",
)

smithyKotlinPlugin {
serviceShapeId = testServiceShapeId
packageName = "aws.sdk.kotlin.test.${test.projectionName.lowercase()}"
packageVersion = "1.0"
buildSettings {
generateFullProject = false
generateDefaultBuildFiles = false
optInAnnotations = listOf(
"aws.smithy.kotlin.runtime.InternalApi",
"aws.sdk.kotlin.runtime.InternalSdkApi",
)
}
}
}
}
}

val codegen by configurations.getting
dependencies {
codegen(project(":codegen:aws-sdk-codegen"))
codegen(libs.smithy.cli)
codegen(libs.smithy.model)
}

tasks.generateSmithyBuild {
doFirst {
tests.forEach { test -> fillInModel(test.model, test.protocolName, test.modelTemplate) }
}
}

tasks.generateSmithyProjections {
doFirst {
// ensure the generated tests use the same version of the runtime as the aws aws-runtime
val smithyKotlinRuntimeVersion = libs.versions.smithy.kotlin.runtime.version.get()
System.setProperty("smithy.kotlin.codegen.clientRuntimeVersion", smithyKotlinRuntimeVersion)
}
}

val optinAnnotations = listOf(
"kotlin.RequiresOptIn",
"aws.smithy.kotlin.runtime.InternalApi",
"aws.sdk.kotlin.runtime.InternalSdkApi",
)

kotlin.sourceSets.all {
optinAnnotations.forEach { languageSettings.optIn(it) }
}

kotlin.sourceSets.getByName("test") {
smithyBuild.projections.forEach {
kotlin.srcDir(smithyBuild.smithyKotlinProjectionSrcDir(it.name))
}
}

tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
dependsOn(tasks.generateSmithyProjections)
// generated clients have quite a few warnings
kotlinOptions.allWarningsAsErrors = false
}

tasks.test {
useJUnitPlatform()
testLogging {
events("passed", "skipped", "failed")
showStandardStreams = true
showStackTraces = true
showExceptions = true
exceptionFormat = org.gradle.api.tasks.testing.logging.TestExceptionFormat.FULL
}
}

dependencies {

implementation(libs.kotlinx.coroutines.core)

testImplementation(libs.kotlin.test)
testImplementation(libs.kotlin.test.junit5)
testImplementation(libs.kotlinx.coroutines.test)

testImplementation(libs.smithy.kotlin.smithy.test)
testImplementation(libs.smithy.kotlin.aws.signing.default)
testImplementation(libs.smithy.kotlin.telemetry.api)

// have to manually add all the dependencies of the generated client(s)
// doing it this way (as opposed to doing what we do for protocol-tests) allows
// the tests to work without a publish to maven-local step at the cost of maintaining
// this set of dependencies manually
// <-- BEGIN GENERATED DEPENDENCY LIST -->
implementation(libs.bundles.smithy.kotlin.service.client)
implementation(libs.smithy.kotlin.aws.event.stream)
implementation(project(":aws-runtime:aws-http"))
implementation(libs.smithy.kotlin.aws.json.protocols)
implementation(libs.smithy.kotlin.serde.json)
api(project(":aws-runtime:aws-config"))
api(project(":aws-runtime:aws-core"))
api(project(":aws-runtime:aws-endpoint"))
// <-- END GENERATED DEPENDENCY LIST -->
}
58 changes: 58 additions & 0 deletions tests/codegen/rules-engine/operation-context-params.smithy
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
$version: "2.0"
namespace aws.sdk.kotlin.test

use aws.protocols#awsJson1_0
use smithy.rules#operationContextParams
use smithy.rules#endpointRuleSet
use aws.api#service

@awsJson1_0
@service(sdkId: "OperationContextParamsTest")
@endpointRuleSet(
version: "1.0",
parameters: {
"ObjectKeys": {
"type": "stringArray",
"documentation": "A string array.",
"required": true
}
},
rules: [
{
"type": "endpoint",
"conditions": [],
"endpoint": {
"url": "https://static.endpoint"
}
}
]
)
service TestService {
operations: [DeleteObjects],
version: "1"
}

@operationContextParams(
ObjectKeys: {
path: "Delete.Objects[*].[Key][]"
}
)
operation DeleteObjects {
input: DeleteObjectsRequest
}

structure DeleteObjectsRequest {
Delete: Delete
}

structure Delete {
Objects: ObjectIdentifierList
}

list ObjectIdentifierList {
member: ObjectIdentifier
}

structure ObjectIdentifier {
Key: String
}

0 comments on commit ecab1a0

Please sign in to comment.