diff --git a/settings.gradle.kts b/settings.gradle.kts index dc2418bfe1d..6dc165db0f0 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -57,7 +57,6 @@ 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") include(":tests:codegen:checksums") // generated services @@ -73,13 +72,6 @@ file("services").listFiles().forEach { } } -// generated services by smoke tests test suite -file("tests/codegen/smoke-tests/services").listFiles().forEach { - if (it.isServiceDir) { - include(":tests:codegen:smoke-tests:services:${it.name}") - } -} - if ("dynamodb".isBootstrappedService) { include(":hll:dynamodb-mapper") include(":hll:dynamodb-mapper:dynamodb-mapper") diff --git a/tests/codegen/build.gradle.kts b/tests/codegen/build.gradle.kts index 1b6c585df92..ce3df2cdb9b 100644 --- a/tests/codegen/build.gradle.kts +++ b/tests/codegen/build.gradle.kts @@ -19,12 +19,6 @@ subprojects { } } - /* - Don't apply the rest of the configuration to the code generated smoke test services! - Those use the KMP plugin not JVM. - */ - if (project.path.startsWith(":tests:codegen:smoke-tests:services")) return@subprojects - apply(plugin = libraries.plugins.aws.kotlin.repo.tools.smithybuild.get().pluginId) apply(plugin = libraries.plugins.kotlin.jvm.get().pluginId) diff --git a/tests/codegen/smoke-tests/build.gradle.kts b/tests/codegen/smoke-tests/build.gradle.kts index e6298681c91..0cb583f8e7e 100644 --- a/tests/codegen/smoke-tests/build.gradle.kts +++ b/tests/codegen/smoke-tests/build.gradle.kts @@ -3,43 +3,40 @@ * 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.smithyKotlinProjectionPath +import aws.sdk.kotlin.gradle.codegen.smithyKotlinProjectionSrcDir import aws.sdk.kotlin.tests.codegen.CodegenTest import aws.sdk.kotlin.tests.codegen.Model description = "AWS SDK for Kotlin's smoke test codegen test suite" -dependencies { - testImplementation(gradleTestKit()) -} - val tests = listOf( CodegenTest("successService", Model("smoke-tests-success.smithy"), "smithy.kotlin.traits#SuccessService"), CodegenTest("failureService", Model("smoke-tests-failure.smithy"), "smithy.kotlin.traits#FailureService"), CodegenTest("exceptionService", Model("smoke-tests-exception.smithy"), "smithy.kotlin.traits#ExceptionService"), ) -configureProjections() -configureTasks() +smithyBuild { + val basePackage = "aws.sdk.kotlin.test.codegen.smoketest" + + projections { + tests.forEach { test -> + create(test.name) { + val modelPath = layout.projectDirectory.file(test.model.path + test.model.fileName).asFile.absolutePath + imports = listOf(modelPath) -fun configureProjections() { - smithyBuild { - this@Build_gradle.tests.forEach { test -> - projections.register(test.name) { - imports = listOf(layout.projectDirectory.file(test.model.path + test.model.fileName).asFile.absolutePath) smithyKotlinPlugin { serviceShapeId = test.serviceShapeId - packageName = "aws.sdk.kotlin.test.${test.name.lowercase()}" - packageVersion = "1.0" + packageName = "$basePackage.${test.name}" + packageVersion = project.version.toString() + sdkId = test.name.replaceFirstChar { it.uppercaseChar() } buildSettings { - generateFullProject = false generateDefaultBuildFiles = false - optInAnnotations = listOf( - "aws.smithy.kotlin.runtime.InternalApi", - "aws.sdk.kotlin.runtime.InternalSdkApi", - ) + generateFullProject = false + } + apiSettings { + visibility = "internal" } } } @@ -47,40 +44,12 @@ fun configureProjections() { } } -fun configureTasks() { - tasks.register("stageServices") { - dependsOn(tasks.generateSmithyProjections) - doLast { - this@Build_gradle.tests.forEach { test -> - val projectionPath = smithyBuild.smithyKotlinProjectionPath(test.name).get() - val destinationPath = layout.projectDirectory.asFile.absolutePath + "/services/${test.name}" - - copy { - from("$projectionPath/src") - into("$destinationPath/generated-src") - } - - copy { - from("$projectionPath/build.gradle.kts") - into(destinationPath) - } - } - } - } +kotlin.sourceSets.getByName("test") { + smithyBuild.projections.forEach { projection -> + // Add generated model to source set + kotlin.srcDir(smithyBuild.smithyKotlinProjectionSrcDir(projection.name)) - tasks.withType { - dependsOn(tasks.getByName("stageServices")) - mustRunAfter(tasks.getByName("stageServices")) - } - - tasks.build { - dependsOn(tasks.getByName("stageServices")) - mustRunAfter(tasks.getByName("stageServices")) - } - - tasks.clean { - this@Build_gradle.tests.forEach { test -> - delete("services/${test.name}") - } + // Add generated smoke tests to source set + kotlin.srcDir(smithyBuild.smithyKotlinProjectionPath(projection.name).map { it.resolve("src/test/kotlin") }) } } diff --git a/tests/codegen/smoke-tests/services/build.gradle.kts b/tests/codegen/smoke-tests/services/build.gradle.kts deleted file mode 100644 index a7a52c11934..00000000000 --- a/tests/codegen/smoke-tests/services/build.gradle.kts +++ /dev/null @@ -1,32 +0,0 @@ -plugins { - alias(libs.plugins.kotlin.multiplatform) -} - -val libraries = libs -subprojects { - apply(plugin = libraries.plugins.kotlin.multiplatform.get().pluginId) - - val optinAnnotations = listOf( - "aws.smithy.kotlin.runtime.InternalApi", - "aws.sdk.kotlin.runtime.InternalSdkApi", - "kotlin.RequiresOptIn", - ) - kotlin.sourceSets.all { - optinAnnotations.forEach { languageSettings.optIn(it) } - } - - kotlin { - sourceSets { - commonMain { - kotlin.srcDir("generated-src/main/kotlin") - - dependencies { - implementation(libraries.kotlin.test) - } - } - commonTest { - kotlin.srcDir("generated-src/test/kotlin") - } - } - } -} diff --git a/tests/codegen/smoke-tests/src/test/kotlin/aws/sdk/kotlin/test/codegen/smoketest/SmokeTestE2ETest.kt b/tests/codegen/smoke-tests/src/test/kotlin/aws/sdk/kotlin/test/codegen/smoketest/SmokeTestE2ETest.kt index f3e4d17bbc6..1992e486d3e 100644 --- a/tests/codegen/smoke-tests/src/test/kotlin/aws/sdk/kotlin/test/codegen/smoketest/SmokeTestE2ETest.kt +++ b/tests/codegen/smoke-tests/src/test/kotlin/aws/sdk/kotlin/test/codegen/smoketest/SmokeTestE2ETest.kt @@ -7,93 +7,87 @@ package aws.sdk.kotlin.test.codegen.smoketest import aws.sdk.kotlin.codegen.smoketests.AWS_SERVICE_FILTER import aws.sdk.kotlin.codegen.smoketests.AWS_SKIP_TAGS -import aws.smithy.kotlin.runtime.util.OsFamily -import aws.smithy.kotlin.runtime.util.PlatformProvider -import java.io.File +import aws.smithy.kotlin.runtime.util.TestPlatformProvider +import kotlinx.coroutines.test.runTest import kotlin.test.Test import kotlin.test.assertContains +import kotlin.test.assertFalse import kotlin.test.assertTrue class SmokeTestE2ETest { @Test - fun successService() { - val smokeTestRunnerOutput = runSmokeTests("successService") + fun successService() = runTest { + val output = StringBuilder() + val runner = aws.sdk.kotlin.test.codegen.smoketest.successService.smoketests.SmokeTestRunner( + TestPlatformProvider(), + output, + ) + val success = runner.runAllTests() + assertTrue(success, "Unexpected failures running successService E2E smoke test. Full output: $output") - assertContains(smokeTestRunnerOutput, "ok SuccessService SuccessTest - no error expected from service") - assertContains(smokeTestRunnerOutput, "ok SuccessService SuccessTestWithTags - no error expected from service") + assertContains(output, "ok SuccessService SuccessTest - no error expected from service") + assertContains(output, "ok SuccessService SuccessTestWithTags - no error expected from service") } @Test - fun failureService() { - val smokeTestRunnerOutput = runSmokeTests("failureService") + fun failureService() = runTest { + val output = StringBuilder() + val runner = aws.sdk.kotlin.test.codegen.smoketest.failureService.smoketests.SmokeTestRunner( + TestPlatformProvider(), + output, + ) + val success = runner.runAllTests() + assertTrue(success, "Unexpected failures running failureService E2E smoke test. Full output: $output") - assertContains(smokeTestRunnerOutput, "ok FailureService FailuresTest - error expected from service") + assertContains(output, "ok FailureService FailuresTest - error expected from service") } @Test - fun exceptionService() { - val smokeTestRunnerOutput = runSmokeTests("exceptionService", expectingFailure = true) + fun exceptionService() = runTest { + val output = StringBuilder() + val runner = aws.sdk.kotlin.test.codegen.smoketest.exceptionService.smoketests.SmokeTestRunner( + TestPlatformProvider(), + output, + ) + val success = runner.runAllTests() + assertFalse(success, "Unexpected success running exceptionService E2E smoke test. Full output: $output") - assertContains(smokeTestRunnerOutput, "not ok ExceptionService ExceptionTest - no error expected from service") - assertContains(smokeTestRunnerOutput, "#aws.smithy.kotlin.runtime.http.interceptors.SmokeTestsFailureException: Smoke test failed with HTTP status code: 400") + assertContains(output, "not ok ExceptionService ExceptionTest - no error expected from service") + assertContains( + output, + "# aws.smithy.kotlin.runtime.http.interceptors.SmokeTestsFailureException: Smoke test failed with HTTP status code: 400", + ) } @Test - fun successServiceSkipTags() { - val envVars = mapOf(AWS_SKIP_TAGS to "success") - val smokeTestRunnerOutput = runSmokeTests("successService", envVars) + fun successServiceSkipTags() = runTest { + val output = StringBuilder() + val runner = aws.sdk.kotlin.test.codegen.smoketest.successService.smoketests.SmokeTestRunner( + TestPlatformProvider( + env = mapOf(AWS_SKIP_TAGS to "success"), + ), + output, + ) + val success = runner.runAllTests() + assertTrue(success, "Unexpected failures running successService E2E smoke test. Full output: $output") - assertContains(smokeTestRunnerOutput, "ok SuccessService SuccessTest - no error expected from service") - assertContains(smokeTestRunnerOutput, "ok SuccessService SuccessTestWithTags - no error expected from service # skip") + assertContains(output, "ok SuccessService SuccessTest - no error expected from service") + assertContains(output, "ok SuccessService SuccessTestWithTags - no error expected from service # skip") } @Test - fun successServiceServiceFilter() { - val envVars = mapOf(AWS_SERVICE_FILTER to "Failure") // Only run tests for services with this SDK ID - val smokeTestRunnerOutput = runSmokeTests("successService", envVars) - - assertContains(smokeTestRunnerOutput, "ok SuccessService SuccessTest - no error expected from service # skip") - assertContains(smokeTestRunnerOutput, "ok SuccessService SuccessTestWithTags - no error expected from service # skip") - } -} - -private fun runSmokeTests( - service: String, - envVars: Map = emptyMap(), - expectingFailure: Boolean = false, -): String { - val sdkRootDir = System.getProperty("user.dir") + "/../../../" - val processBuilder = - ProcessBuilder( - *gradleWrapperCommand(), - ":tests:codegen:smoke-tests:services:$service:smokeTest", - // Make sure unexpected errors are debuggable - "--stacktrace", - // FIXME: Remove `-Paws.kotlin.native=false` when Kotlin Native is ready - "-Paws.kotlin.native=false", + fun successServiceServiceFilter() = runTest { + val output = StringBuilder() + val runner = aws.sdk.kotlin.test.codegen.smoketest.successService.smoketests.SmokeTestRunner( + TestPlatformProvider( + env = mapOf(AWS_SERVICE_FILTER to "Failure"), // Only run tests for services with this SDK ID + ), + output, ) - .directory(File(sdkRootDir)) - .redirectErrorStream(true) - - processBuilder.environment().putAll(envVars) + val success = runner.runAllTests() + assertTrue(success, "Unexpected failures running successService E2E smoke test. Full output: $output") - val process = processBuilder.start() - val output = process.inputStream.bufferedReader().use { it.readText() } - val exitCode = process.waitFor() - - if (expectingFailure) { - assertTrue(exitCode != 0) + assertContains(output, "ok SuccessService SuccessTest - no error expected from service # skip") + assertContains(output, "ok SuccessService SuccessTestWithTags - no error expected from service # skip") } - - return output } - -/** - * Determines the appropriate Gradle wrapper command based on the operating system. - */ -private fun gradleWrapperCommand() = - if (PlatformProvider.System.osInfo().family == OsFamily.Windows) { - arrayOf("cmd.exe", "/c", "gradlew.bat") - } else { - arrayOf("./gradlew") - }