Skip to content
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

feat: add constraint checking for dotnet #336

Merged
merged 8 commits into from
Apr 12, 2024
Merged

Conversation

ajewellamz
Copy link
Contributor

Description of changes:

This ONLY addresses constraint checking for dotnet

pull/257 will address rejecting any types, traits or constraints that we do not or cannot handle properly.

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

@ajewellamz ajewellamz requested a review from a team as a code owner April 10, 2024 01:40
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this all just formatting?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, I completely re-did the helpers, into something that actually helped.

Comment on lines -93 to +101
@uniqueItems
list MyUniqueList {
member: String
}
// we don't do uniqueItems yet
// @uniqueItems
// list MyUniqueList {
// member: String
// }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't support them in .Net. We also don't have any code in Java?
Do we add an error if someone tries to do this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a different topic.
pull/257 is responsible for "we don't support that" errors.

Comment on lines +39 to +40
// This client is NOT wrapped
// Therefore, it does not do any constraint testing
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we want to add this above or something. The point here, is that by not wrapping these things we are relying on Dafny verification. And the fact that this succeeds may imply a soundness bug in the callers code. As opposed to just "well, we don't check it" :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Going further, given the extensive testing on the wrapped side, does this test serve any value? would it be better to do nothing here and explain that this is all verified by Dafny and so testing is not useful?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this test shows that the unwrapped client behaves as expected.
It's not especially interesting, I'll admit, but it seems a reasonable thing to test.

ensures client.ValidState()
{
var input := GetValidInput();
input := input.(StringLessThanOrEqualToTen := Some(ForceStringLessThanOrEqualToTen("this string is really way too long")));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given the conversations about how strings are complicated would it be better to not support this at all?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a different topic.
pull/257 is responsible for "we don't support that" errors.
This PR makes dotnet behave the same as Java.

@@ -251,6 +259,100 @@ public TypeConverter generateBooleanConverter(final BooleanShape booleanShape) {
return buildConverterFromMethodBodies(booleanShape, fromDafnyBody, toDafnyBody);
}

public String generateStringConstraints(final Shape shape, final String value) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again is it better to not support strings at all? Given dafny unicode false support?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, that's a different topic.
pull/257 is responsible for "we don't support that" errors.
This PR makes dotnet behave the same as Java.
I suppose that part pf pull/257 might be to rip these out, since the smithy file will have to remove any length constraints on strings.

var input := GetValidInput();
input := input.(OneToTen := Some(ForceOneToTen(1000)));
var ret := client.GetConstraints(input := input);
expect ret.Failure?;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit/Issue: I keep running into tests where we just expect ret.Failure? and do not validate what caused the failure or what the failure was.

These tests sometimes mask bugs.
As an example, there is a test that asserts that if no Branch Key ID exists,
the Keystore's Get* methods for that Branch Key ID will fail.

And the Keystore does fail!
But with a bizarre KMS Exception that no customer could use to realize they were asking for a non-existance Branch Key ID.

Is it possible to bulk replace ret.Failure? here with something like ret.Failure? AND ret.Failure == IllegalInputException?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree completely, but unfortunately, the error is an Opaque error that came from an exception, and there's no way (as far as I know) to get the actual exception type or the error text out of an Opaque error.
Further, things will likely be different between Java and Dotnet, even if we could get at that stuff; since the errors are generated from custom native code.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just logged in to write the same thing.
Which is a pretty severe limitation of this Test Model approach we have endorsed.

@seebees And @robin-aws for awareness.

Not that we are going to take any action to resolve this, but we should bear in mind that our limited error expressions mixed with our wrapping test strategy ensures we can never assert the exception type.


function method ForceLessThanTen(value : int) : LessThanTen
{
assume {:axiom} ValidInt32(value);
Copy link
Contributor

@lucasmcdonald3 lucasmcdonald3 Apr 10, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We might want to loop in @robin-aws.
He pushed back on testing failure cases for SimpleConstraints using assume statements.
(I am on board with what you've done)

final TokenTree fromDafnyBody = Token.of("return value;");
final TokenTree toDafnyBody = Token.of("return value;");
final TokenTree toDafnyBody = Token.of(constraints + "return value;");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Blocking: Are we not putting these into the validate method?
It appears we pushing these constraint checks into the Type Conversion Methods,
which definitely would solve the problem.

But I thought the plan was to put them in structure's validate method,
and then ensure validate is always called in the toDafnyBody methods.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ajewellamz and @texastony chatted on a call.
My dreams of a useful and complete Validate method are punted to another day.
But @ajewellamz in this PR or a very fast follow will ensure that Validate is called in the to Dafny methods for all structures.

I think I am going to leave this PR blocked until that is done,
but if @ajewellamz tells me that he really wants to do it another PR,
I will yield.

Copy link
Contributor

@texastony texastony left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most Groovy.
Thank you @ajewellamz

Comment on lines +561 to +564
String validate = "value.Validate();";
if (AwsSdkNameResolverHelpers.isInAwsSdkNamespace(structureShape.getId())) {
validate = "";
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Groovy.

@ajewellamz ajewellamz merged commit e631c8f into main-1.x Apr 12, 2024
125 checks passed
@ajewellamz ajewellamz deleted the ajewell/constraints branch April 12, 2024 11:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants