Unverified Commit 17545f6f authored by ysaito1001's avatar ysaito1001 Committed by GitHub
Browse files

Upgrade Smithy to 1.50.0 (#3728)

## Motivation and Context
This PR upgrades Smithy to 1.50.0. The majority of the changes follow
`TODO` added in https://github.com/smithy-lang/smithy-rs/pull/3690.
Other than that, a few adjustments needed to be made:
- for the client
- added two failing tests `RestJsonClientPopulatesDefaultValuesInInput`
and `RestJsonClientUsesExplicitlyProvidedMemberValuesOverDefaults` to
known failing tests for the same reason
[here](https://github.com/smithy-lang/smithy-rs/blob/main/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/generators/protocol/ClientProtocolTestGenerator.kt#L72)
- added one broken test (i.e. the upstream test definition is incorrect
but our implementation is correct) to known broken tests per
([smithy#2341](https://github.com/smithy-lang/smithy/pull/2341),
[smithy-rs#3726](https://github.com/smithy-lang/smithy-rs/pull/3726#issuecomment-2199833659)

)
- for the server
- removed `rest-xml-extras.smithy` since
`RestXmlMustSupportParametersInContentType` is now available upstream
Smithy 1.50.0
- added the following to known failing tests (since the `awsJson1_0`
counterparts are already in the list, but we need the server team to
verify this assumption & provide additional `TODO` comments if
necessary)
    - `RestJsonServerPopulatesDefaultsWhenMissingInRequestBody`
    - `RestJsonServerPopulatesDefaultsInResponseWhenMissingInParams`,
-
`RestJsonServerPopulatesNestedDefaultValuesWhenMissingInInResponseParams`

## Testing
Existing tests in CI

----

_By submitting this pull request, I confirm that you can use, modify,
copy, and redistribute this contribution, under the terms of your
choice._

---------

Co-authored-by: default avatarZelda Hessler <zhessler@amazon.com>
parent 2bf03857
Loading
Loading
Loading
Loading
+1 −10
Original line number Diff line number Diff line
@@ -66,16 +66,7 @@ val allCodegenTests = listOf(
    ClientTest(
        "aws.protocoltests.restjson#RestJsonExtras",
        "rest_json_extras",
        dependsOn = listOf(
            "rest-json-extras.smithy",
            // TODO(https://github.com/smithy-lang/smithy/pull/2310): Can be deleted when consumed in next Smithy version.
            "rest-json-extras-2310.smithy",
            // TODO(https://github.com/smithy-lang/smithy/pull/2314): Can be deleted when consumed in next Smithy version.
            "rest-json-extras-2314.smithy",
            // TODO(https://github.com/smithy-lang/smithy/pull/2315): Can be deleted when consumed in next Smithy version.
            // TODO(https://github.com/smithy-lang/smithy/pull/2331): Can be deleted when consumed in next Smithy version.
            "rest-json-extras-2315.smithy",
        ),
        dependsOn = listOf("rest-json-extras.smithy"),
    ),
    ClientTest("aws.protocoltests.misc#MiscService", "misc", dependsOn = listOf("misc.smithy")),
    ClientTest("aws.protocoltests.restxml#RestXml", "rest_xml", addMessageToErrors = false),
+35 −1
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@

package software.amazon.smithy.rust.codegen.client.smithy.generators.protocol

import software.amazon.smithy.model.node.NumberNode
import software.amazon.smithy.model.shapes.DoubleShape
import software.amazon.smithy.model.shapes.FloatShape
import software.amazon.smithy.model.shapes.OperationShape
@@ -27,7 +28,9 @@ import software.amazon.smithy.rust.codegen.core.smithy.generators.protocol.Broke
import software.amazon.smithy.rust.codegen.core.smithy.generators.protocol.FailingTest
import software.amazon.smithy.rust.codegen.core.smithy.generators.protocol.ProtocolSupport
import software.amazon.smithy.rust.codegen.core.smithy.generators.protocol.ProtocolTestGenerator
import software.amazon.smithy.rust.codegen.core.smithy.generators.protocol.ServiceShapeId
import software.amazon.smithy.rust.codegen.core.smithy.generators.protocol.ServiceShapeId.AWS_JSON_10
import software.amazon.smithy.rust.codegen.core.smithy.generators.protocol.ServiceShapeId.REST_JSON
import software.amazon.smithy.rust.codegen.core.smithy.generators.protocol.TestCase
import software.amazon.smithy.rust.codegen.core.util.PANIC
import software.amazon.smithy.rust.codegen.core.util.dq
@@ -73,7 +76,38 @@ class ClientProtocolTestGenerator(
                FailingTest.RequestTest(AWS_JSON_10, "AwsJson10ClientPopulatesDefaultsValuesWhenMissingInResponse"),
                FailingTest.RequestTest(AWS_JSON_10, "AwsJson10ClientUsesExplicitlyProvidedMemberValuesOverDefaults"),
                FailingTest.RequestTest(AWS_JSON_10, "AwsJson10ClientPopulatesDefaultValuesInInput"),
                FailingTest.RequestTest(REST_JSON, "RestJsonClientPopulatesDefaultValuesInInput"),
                FailingTest.RequestTest(REST_JSON, "RestJsonClientUsesExplicitlyProvidedMemberValuesOverDefaults"),
            )

        private val BrokenTests:
            Set<BrokenTest> =
            setOf(
                BrokenTest.ResponseTest(
                    ServiceShapeId.REST_JSON,
                    "RestJsonClientIgnoresDefaultValuesIfMemberValuesArePresentInResponse",
                    howToFixItFn = ::fixRestJsonClientIgnoresDefaultValuesIfMemberValuesArePresentInResponse,
                    inAtLeast = setOf("1.50.0"),
                    trackedIn =
                        setOf(
                            // TODO(https://github.com/smithy-lang/smithy/pull/2341)
                            "https://github.com/smithy-lang/smithy/pull/2341",
                        ),
                ),
            )

        private fun fixRestJsonClientIgnoresDefaultValuesIfMemberValuesArePresentInResponse(
            testCase: TestCase.ResponseTest,
        ): TestCase.ResponseTest {
            val fixedParams =
                testCase.testCase.params.toBuilder().withMember("defaultTimestamp", NumberNode.from(2)).build()
            return TestCase.ResponseTest(
                testCase.testCase.toBuilder()
                    .params(fixedParams)
                    .build(),
                testCase.targetShape,
            )
        }
    }

    override val appliesTo: AppliesTo
@@ -85,7 +119,7 @@ class ClientProtocolTestGenerator(
    override val disabledTests: Set<String>
        get() = emptySet()
    override val brokenTests: Set<BrokenTest>
        get() = emptySet()
        get() = BrokenTests

    override val logger: Logger = Logger.getLogger(javaClass.name)

+0 −35
Original line number Diff line number Diff line
$version: "1.0"

namespace aws.protocoltests.restjson

use aws.protocols#restJson1
use smithy.test#httpMalformedRequestTests

@http(method: "POST", uri: "/MalformedContentTypeWithBody")
operation MalformedContentTypeWithBody2 {
    input: GreetingStruct
}

structure GreetingStruct {
    salutation: String,
}

apply MalformedContentTypeWithBody2 @httpMalformedRequestTests([
    {
        id: "RestJsonWithBodyExpectsApplicationJsonContentTypeNoHeaders",
        documentation: "When there is modeled input, the content type must be application/json",
        protocol: restJson1,
        request: {
            method: "POST",
            uri: "/MalformedContentTypeWithBody",
            body: "{}",
        },
        response: {
            code: 415,
            headers: {
                "x-amzn-errortype": "UnsupportedMediaTypeException"
            }
        },
        tags: [ "content-type" ]
    }
])
+0 −39
Original line number Diff line number Diff line
$version: "1.0"

namespace aws.protocoltests.restjson

use aws.protocols#restJson1
use smithy.test#httpRequestTests

/// This example serializes a blob shape in the payload.
///
/// In this example, no JSON document is synthesized because the payload is
/// not a structure or a union type.
@http(uri: "/HttpPayloadTraits", method: "POST")
operation HttpPayloadTraits2 {
    input: HttpPayloadTraitsInputOutput,
    output: HttpPayloadTraitsInputOutput
}

apply HttpPayloadTraits2 @httpRequestTests([
    {
        id: "RestJsonHttpPayloadTraitsWithBlobAcceptsNoContentType",
        documentation: """
            Servers must accept no content type for blob inputs
            without the media type trait.""",
        protocol: restJson1,
        method: "POST",
        uri: "/HttpPayloadTraits",
        body: "This is definitely a jpeg",
        bodyMediaType: "application/octet-stream",
        headers: {
            "X-Foo": "Foo",
        },
        params: {
            foo: "Foo",
            blob: "This is definitely a jpeg"
        },
        appliesTo: "server",
        tags: [ "content-type" ]
    }
])
+0 −133
Original line number Diff line number Diff line
$version: "2.0"

namespace aws.protocoltests.restjson

use smithy.test#httpRequestTests
use smithy.test#httpResponseTests
use smithy.test#httpMalformedRequestTests
use smithy.framework#ValidationException

@http(uri: "/EnumPayload2", method: "POST")
@httpRequestTests([
    {
        id: "RestJsonEnumPayloadRequest2",
        uri: "/EnumPayload2",
        headers: { "Content-Type": "text/plain" },
        body: "enumvalue",
        params: { payload: "enumvalue" },
        method: "POST",
        protocol: "aws.protocols#restJson1"
    }
])
@httpResponseTests([
    {
        id: "RestJsonEnumPayloadResponse2",
        headers: { "Content-Type": "text/plain" },
        body: "enumvalue",
        params: { payload: "enumvalue" },
        protocol: "aws.protocols#restJson1",
        code: 200
    }
])
operation HttpEnumPayload2 {
    input: EnumPayloadInput,
    output: EnumPayloadInput
    errors: [ValidationException]
}

@http(uri: "/StringPayload2", method: "POST")
@httpRequestTests([
    {
        id: "RestJsonStringPayloadRequest2",
        uri: "/StringPayload2",
        body: "rawstring",
        bodyMediaType: "text/plain",
        headers: {
            "Content-Type": "text/plain",
        },
        requireHeaders: [
            "Content-Length"
        ],
        params: { payload: "rawstring" },
        method: "POST",
        protocol: "aws.protocols#restJson1"
    }
])
@httpResponseTests([
    {
        id: "RestJsonStringPayloadResponse2",
        headers: { "Content-Type": "text/plain" },
        body: "rawstring",
        bodyMediaType: "text/plain",
        params: { payload: "rawstring" },
        protocol: "aws.protocols#restJson1",
        code: 200
    }
])
@httpMalformedRequestTests([
    {
        id: "RestJsonStringPayloadNoContentType2",
        documentation: "Serializes a string in the HTTP payload without a content-type header",
        protocol: "aws.protocols#restJson1",
        request: {
            method: "POST",
            uri: "/StringPayload2",
            body: "rawstring",
            // We expect a `Content-Type` header but none was provided.
        },
        response: {
            code: 415,
            headers: {
                "x-amzn-errortype": "UnsupportedMediaTypeException"
            }
        },
        tags: [ "content-type" ]
    },
    {
        id: "RestJsonStringPayloadWrongContentType2",
        documentation: "Serializes a string in the HTTP payload without the expected content-type header",
        protocol: "aws.protocols#restJson1",
        request: {
            method: "POST",
            uri: "/StringPayload2",
            body: "rawstring",
            headers: {
                // We expect `text/plain`.
                "Content-Type": "application/json",
            },
        },
        response: {
            code: 415,
            headers: {
                "x-amzn-errortype": "UnsupportedMediaTypeException"
            }
        },
        tags: [ "content-type" ]
    },
    {
        id: "RestJsonStringPayloadUnsatisfiableAccept2",
        documentation: "Serializes a string in the HTTP payload with an unstatisfiable accept header",
        protocol: "aws.protocols#restJson1",
        request: {
            method: "POST",
            uri: "/StringPayload2",
            body: "rawstring",
            headers: {
                "Content-Type": "text/plain",
                // We can't satisfy this requirement; the server will return `text/plain`.
                "Accept": "application/json",
            },
        },
        response: {
            code: 406,
            headers: {
                "x-amzn-errortype": "NotAcceptableException"
            }
        },
        tags: [ "accept" ]
    },
])
operation HttpStringPayload2 {
    input: StringPayloadInput,
    output: StringPayloadInput
}
Loading