-
Notifications
You must be signed in to change notification settings - Fork 31
kn/misc: enable various ignored tests #1257
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
Conversation
…tlin as an includeBuild
This reverts commit 3580da4.
internal val AwsSigningConfig.credentialScope: String | ||
get() = run { | ||
val signingDate = signingDate.format(TimestampFormat.ISO_8601_CONDENSED_DATE) | ||
return when (algorithm) { | ||
AwsSigningAlgorithm.SIGV4 -> "$signingDate/$region/$service/aws4_request" | ||
AwsSigningAlgorithm.SIGV4_ASYMMETRIC -> "$signingDate/$service/aws4_request" | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: The run
function is good for assignments but just adds clutter to function definitions. Just use braces:
internal val AwsSigningConfig.credentialScope: String
get() {
val signingDate = signingDate.format(TimestampFormat.ISO_8601_CONDENSED_DATE)
return when (algorithm) {
AwsSigningAlgorithm.SIGV4 -> "$signingDate/$region/$service/aws4_request"
AwsSigningAlgorithm.SIGV4_ASYMMETRIC -> "$signingDate/$service/aws4_request"
}
}
/** Creates a customized instance of [AwsSigner] */ | ||
@Suppress("ktlint:standard:function-naming") | ||
public fun DefaultAwsSigner(block: DefaultAwsSignerBuilder.() -> Unit): AwsSigner = | ||
DefaultAwsSignerBuilder().apply(block).build() | ||
|
||
/** A builder class for creating instances of [AwsSigner] using the default implementation */ | ||
public class DefaultAwsSignerBuilder { | ||
public var telemetryProvider: TelemetryProvider? = null | ||
|
||
public fun build(): AwsSigner = DefaultAwsSignerImpl( | ||
telemetryProvider = telemetryProvider, | ||
) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Opinion: It now feels weird that this factory function and builder type exist only in JVM when the named value exists in all source sets.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Discussed separately and agreed that this API disparity is fine for now and can be reexamined if we ever see problems or get feedback.
/** The default implementation of [AwsSigner] */ | ||
public actual val DefaultAwsSigner: AwsSigner | ||
get() = DefaultAwsSignerImpl() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Question: Why is a new signer instantiated on every call? Before it was initialized only once and then reused everywhere.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will be refactored, same applies for CrtAwsSigner
/** The default implementation of [AwsSigner] */ | ||
public actual val DefaultAwsSigner: AwsSigner | ||
get() = CrtAwsSigner |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Question: Do we have to use a getter for this or can we just set the value one time?
public actual val DefaultAwsSigner: AwsSigner = CrtAwsSigner
internal actual fun transferRequestBody(outgoing: SdkBuffer, dest: MutableBuffer): Int = TODO("Not yet implemented") | ||
internal actual fun transferRequestBody(outgoing: SdkBuffer, dest: MutableBuffer): Int { | ||
val length = minOf(outgoing.size, dest.writeRemaining.toLong()) | ||
if (length <= 0) return 0 | ||
return dest.write(outgoing.readByteArray(length)) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Question: Why is this different than the JVM (formerly common) implementation? Why won't simply outgoing.read(dest.buffer)
work?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dest.buffer
exists only on JVM
@IgnoreNative // FIXME Re-enable after Kotlin/Native Implementation. | ||
@Test | ||
fun testStreamError() = runTest { | ||
CRT.initRuntime() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Question: This shouldn't properly be here, right? Does this need a FIXME
because some underlying component is not properly initializing the CRT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I could not decide which underlying component needs to initialize CRT in this test. This is testing the SdkStreamResponseHandler
which is a callback machine for reading a CRT HttpStream
. We're not creating a CRT engine or anything else which might initialize CRT here.
The only reason this initRuntime
is needed is for the final assertion:
ex.message.shouldContain("socket is closed.; crtErrorCode=$socketClosedEc")
CRT needs to be initialized to return human-readable error codes, otherwise it returns "unknown". This assertion is on an exception message which we typically avoid doing, so I could remove that assertion / remove CRT.init
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes removing the CRT.initRuntime()
is probably the simplest thing to do for this test. But I still worry we have our CRT initialization calls in so many disparate places and that we may still be missing the calls in other places.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll keep the CRT.initRuntime()
and the assertion in place. I'll add a comment* explaining why we need to initialize the CRT here.
val cause = assertNotNull(ex.cause) | ||
val cause = assertNotNull(ex.cause ?: ex) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Question: Why is there a fallback in this test? Why would the exception have a cause in one run/target but not another?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I spent a few hours on this one and could not figure out the root cause.
On JVM, the exception ex
is a copy of its cause (ex.cause
), but the cause is the one which has all of the suppressed exceptions. On all other platforms, there is just a single exception ex
which holds all of the suppressed exceptions.
This test is focused on suppressed exceptions, which do work consistently across platforms, so I think it's ok. I could leave a FIXME / open up a backlog task to investigate the ex.cause
if you'd like?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes it'd be good to understand what's duplicating it. A FIXME
seems correct.
public actual fun ecdsaSecp256r1(key: ByteArray, message: ByteArray): ByteArray = TODO("Not yet implemented") | ||
public actual fun ecdsaSecp256r1(key: ByteArray, message: ByteArray): ByteArray = error("This function should not be invoked on Native, which uses the CrtAwsSigner.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: It feels weird to have an actual
function that we'll never implement and should never call. That, to me, indicates that our expect
declaration is on the wrong component and should be higher up.
// FIXME Implement using aws-c-cal: https://github.com/awslabs/aws-c-cal/blob/main/include/aws/cal/ecc.h | ||
// Will need to be implemented and exposed in aws-crt-kotlin. Or maybe we can _only_ offer the CRT signer on Native? | ||
// Will require updating DefaultAwsSigner to be expect/actual and set to CrtSigner on Native. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Question: Did we go down the road of binding to CRT's crypto primitives and abandon it for some reason? Or did we just decide to use the whole CRT signer for a more important reason?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, I didn't even start binding to CRT for this. We previously discussed using CrtAwsSigner as the default on Native so that's where I went.
It sounds like you've changed your mind on this, we can talk about it and decide what to do
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We agreed to keep the CrtAwsSigner as default on Native and evaluate the decision if/when we get user feedback
Issue #
Description of changes
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.