-
Notifications
You must be signed in to change notification settings - Fork 4k
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
fix(rds): does not print all failed validations for DatabaseCluster props #32841
Conversation
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.
The pull request linter has failed. See the aws-cdk-automation comment below for failure reasons. If you believe this pull request should receive an exemption, please comment and provide a justification.
A comment requesting an exemption should contain the text Exemption Request
. Additionally, if clarification is needed add Clarification Request
to a comment.
@@ -2093,30 +2172,6 @@ describe('cluster', () => { | |||
}); | |||
}); | |||
|
|||
test('throws if performanceInsightRetention is set but performance insights is disabled', () => { |
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.
These two tests did the same thing (as implemented), removed them here and moved to line 567.
}).toThrow('Aurora Limitless Database requires I/O optimized storage type, got: aurora'); | ||
}); | ||
|
||
test.each([[], undefined])('throw error for invalid cloudwatch log exports', (cloudwatchLogsExports) => { |
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.
Tested at line 584.
✅ Updated pull request passes all PRLinter validations. Dismissing previous PRLinter review.
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #32841 +/- ##
==========================================
+ Coverage 81.52% 81.53% +0.01%
==========================================
Files 225 226 +1
Lines 13760 13769 +9
Branches 2413 2414 +1
==========================================
+ Hits 11218 11227 +9
Misses 2270 2270
Partials 272 272
Flags with carried forward coverage won't be shown. Click here to find out more.
|
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.
The pull request linter fails with the following errors:
❌ Features must contain a change to a README file.
❌ Features must contain a change to an integration test file and the resulting snapshot.
If you believe this pull request should receive an exemption, please comment and provide a justification. A comment requesting an exemption should contain the text Exemption Request
. Additionally, if clarification is needed, add Clarification Request
to a comment.
✅ A exemption request has been requested. Please wait for a maintainer's review.
Exemption Request: unit test changes provide coverage for single and multiple errors returned, no README changes are needed as the effects of this change will be intuitive to users. |
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.
Two pieces of feedback:
- Can you please change this to use
ValidationError
? We are currently starting a migration of all error types to the newValidationError
. You could not have known that. But would be good to get started on it. - This is great progress towards a more generic validation system. Good stuff! However I think we already should be aiming much higher and make this a generic (private) feature in core, so that all our constructs can you use this.
First one is an easy change and I will implement this. For your second point, are you suggesting to generalize But I worry this might be too abstracted. We have different rules for standard and limitless database initializations, and offering flexibility in an abstraction might make a generalized function more difficult to use. Happy to hear your thoughts on this. |
If I understand the PR correctly, you are introducing a feature that allows a construct to declare a number if rules that can be validated independently from each other. If any of the rules fails, the construct will throw a validation error with all failing rules. I think this a feature that would benefit other constructs as well and is worth generalizing.
That's a good concern, and we will have to make sure the API is easy enough to understand. I agree, this PR feels complex because you are starting from the list of all possible rules and then run some filters to only pick the applicable ones. That part I think can be kept local to the RDS DB Cluster. |
8aef9e4
to
16787f0
Compare
✅ Updated pull request passes all PRLinter validations. Dismissing previous PRLinter review.
import { ValidationError } from '../../lib/errors'; | ||
import { validateProps, ValidationRule } from '../../lib/helpers-internal/validate-props'; | ||
|
||
class MockConstruct extends Construct { |
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: In the context of jest tests "mock" means a very specific thing, I usually call this Fake
or Test
just to not confuse a future reader of the code.
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 rename to TestConstruct.
@@ -268,7 +268,7 @@ describe('cluster new api', () => { | |||
storageType: DBClusterStorageType.AURORA_IOPT1, | |||
cloudwatchLogsExports: ['postgresql'], | |||
}); | |||
}).toThrow('Performance Insights must be enabled for Aurora Limitless Database.'); | |||
}).toThrow('DatabaseCluster initialization failed due to the following validation error(s):\n- Performance Insights must be enabled for Aurora Limitless Database\n- Performance Insights retention period must be set to at least 31 days for Aurora Limitless Database'); |
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: Might be nicer to limit the test exception to what the test is trying to test. Like for this specific test, do we really care of the other error and the prelude is included?
We could keep the existing ones and then have a single test case that checks all possible parallel rules
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.
The way that the validations are implemented now, the prelude will always be included. Since we were only testing for Performance Insights must be enabled for Aurora Limitless Database
, I could change the test to include a valid retention period. However, this seems kind of contrived... since a user is unlikely to include a retention period if they did not enable performance insights.
* Validates props against a set of rules and throws an error if any validations fail. | ||
* | ||
* @template T The type of the props being validated. | ||
* @param {string} className - The name of the class being validated, used in the error message. |
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.
You should give the example how to use this normally. i.e. Queue.name
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 do, thanks.
* @param {ValidationRule<T>[]} rules - An array of validation rules to apply. | ||
* @throws {Error} If any validation rules fail, with a message detailing all failures. | ||
*/ | ||
export function validateProps<T>(scope: Construct, className: string, props: T, rules: ValidationRule<T>[]): void { |
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.
Can we find a name that indicates the exact behavior better? I mean "fail at first error" vs "process all".
@@ -829,36 +830,10 @@ abstract class DatabaseClusterNew extends DatabaseClusterBase { | |||
}); | |||
} | |||
|
|||
validateDatabaseClusterProps(scope, props); |
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.
validateDatabaseClusterProps(scope, props); | |
validateDatabaseClusterProps(this, props); |
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 make this change, thanks.
@@ -383,7 +383,7 @@ export class Queue extends QueueBase { | |||
physicalName: props.queueName, | |||
}); | |||
|
|||
validateProps(props); | |||
validateQueueProps(scope, props); |
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.
validateQueueProps(scope, props); | |
validateQueueProps(this, props); |
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 make this change, thanks.
? [...standardDatabaseRules, ...limitlessDatabaseRules] | ||
: standardDatabaseRules; | ||
|
||
validateProps(scope, DatabaseCluster.name, props, applicableRules); |
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.
Is using DatabaseCluster.name
always the correct choice?
If someone implements a subclass of DatabaseCluster
named FooBar
, the error will still say "DatabaseCluster". Is that what we want? Genuine question, cause I'm not sure about it.
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 did not consider that while implementing this, but I think that is the correct behavior. Ultimately we are validating the props of DatabaseCluster
, not FooBar
. If there are additional validations needed for FooBar
, they should be implemented separately.
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.
Looks great! Left some very minor comments. The other things is that we will need to have two separate PRs for this. One for e.g. RDS with the general implementation and then a follow-up for SQS. The reason being that we want two distinct entries in the changelog.
Side note: This feels more like a
|
fb36dec
to
bef0496
Compare
bef0496
to
9450eb8
Compare
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.
Thank you for contributing! Your pull request will be updated from main and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork). |
AWS CodeBuild CI Report
Powered by github-codebuild-logs, available on the AWS Serverless Application Repository |
Thank you for contributing! Your pull request will be updated from main and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork). |
Comments on closed issues and PRs are hard for our team to see. |
Issue #32840
Closes #32840
Reason for this change
When initializing a new RDS DB Cluster, the current implementation fails on the first validation error, making it possible for the user to encounter another failure after fixing known validation issues.
Description of changes
Implemented a validation function that collects all validation errors and presents them to the user. Used this function in RDS Database Cluster initialization. I will implement this separately for SQS Queue initialization as a POC for usability.
There are several other places that can make use of this shared code, to show users all validation errors at once. Here's a non-exhaustive list:
Describe any new or updated permissions being added
No permissions changes.
Description of how you validated changes
Added unit tests and modified existing unit tests.
Checklist
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license