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

chore: parallelize integ tests across regions #10269

Merged
merged 13 commits into from
Sep 10, 2020

Conversation

rix0rrr
Copy link
Contributor

@rix0rrr rix0rrr commented Sep 9, 2020

When AWS_REGIONS=region1,region2,region3 is set, the CLI integration
tests are going to parallelize themselves across those regions.


By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license

When `AWS_REGIONS=region1,region2,region3` is set, the CLI integration
tests are going to parallelize themselves across those regions.
@rix0rrr rix0rrr requested review from iliapolo and nija-at September 9, 2020 13:42
@rix0rrr rix0rrr self-assigned this Sep 9, 2020
@mergify mergify bot added the contribution/core This is a PR that came from AWS. label Sep 9, 2020
@rix0rrr rix0rrr added the pr/do-not-merge This PR should not be merged at this time. label Sep 9, 2020
Copy link
Contributor

@nija-at nija-at left a comment

Choose a reason for hiding this comment

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

Not looked into the PR itself yet, but can we make it very clear in the logs which region the stack is going to (if not already). I'd rather not clickity-click across 10 different regions to find the stack.

@@ -42,6 +42,13 @@ To run regression tests in the source tree:
$ test/integ/test-cli-regression-against-current-code.sh [-t '...']
```

Integ tests can run in parallel across multiple regions. Set the `AWS_REGIONS`
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you add a bit more about what the striping strategy will be, or how tests get assigned to regions?

Copy link
Contributor

Choose a reason for hiding this comment

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

Also state which region will be picked by default.

Copy link
Contributor Author

@rix0rrr rix0rrr Sep 9, 2020

Choose a reason for hiding this comment

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

Also state which region will be picked by default.

All of them?

Why do you care? If you care, then you shouldn't be passing all of them.

Copy link
Contributor

Choose a reason for hiding this comment

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

Also state which region will be picked by default.

All of them?

Why do you care? If you care, then you shouldn't be passing all of them.

Not what I meant. Which region will be picked if AWS_REGIONS is not specified.

Copy link
Contributor

@iliapolo iliapolo Sep 10, 2020

Choose a reason for hiding this comment

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

In relation, It might be good for debugging if each test prints out the region its running in

nija-at
nija-at previously requested changes Sep 9, 2020
Comment on lines 151 to 153
} finally {
this.regionLease.dispose();
}
Copy link
Contributor

Choose a reason for hiding this comment

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

A bit hard to follow since the lease is taken in a different scope, (prepareAppFixture() I think).

Keep the take() and dispose() calls in the same block so it's easier to reason about.

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 fine, but I'm going to have to change everything to use higher-order functions. Not sure that's going to make things more readable, but it's definitely fun for me! :)

* forever before the user notices a simple misconfiguration.
*
* We can't check for the presence of environment variables since credentials could come from
* anywyere, so do simple account retrieval.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
* anywyere, so do simple account retrieval.
* anywhere, so do simple account retrieval.

* If there are multiple consumers waiting for a resource, consumers are serviced
* in FIFO order for most fairness.
*/
export class ResourcePool<A> {
Copy link
Contributor

Choose a reason for hiding this comment

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

Unit tests for the leasing logic. A regression here (now or in the future) would be hard to catch/debug, esp one that works partially causing the logic to skew but not fail.

@@ -42,6 +42,13 @@ To run regression tests in the source tree:
$ test/integ/test-cli-regression-against-current-code.sh [-t '...']
```

Integ tests can run in parallel across multiple regions. Set the `AWS_REGIONS`
Copy link
Contributor

Choose a reason for hiding this comment

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

Also state which region will be picked by default.

All of them?

Why do you care? If you care, then you shouldn't be passing all of them.

Not what I meant. Which region will be picked if AWS_REGIONS is not specified.

if (resources.length === 0) {
throw new Error('Must have at least one resource in the pool');
}
this.resources = [...resources];
Copy link
Contributor

Choose a reason for hiding this comment

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

Dedup maybe? To avoid any funky unexpected repititions

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not sure what you mean here. I'm making a copy so we don't have accidental sharing of arrays.

Copy link
Contributor

Choose a reason for hiding this comment

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

I mean that AWS_REGIONS might be configured as ['us-east-1', 'us-east-1', 'us-east-1'], effectively causing three tests to run in parallel on us-east-1.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hm. Seems that's the caller's responsibility. Maybe they want to weight certain regions differently? I could see that...

Copy link
Contributor

Choose a reason for hiding this comment

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

Agree as far as this generic pool is concerned.

But if we want to make sure tests don't run in parallel in the same region then I would add the deduplication on the caller side when you read the AWS_REGIONS env variable. Maybe even throw if len(array) != len(set).

I actually don't mind not deduping, just mentioning it because there is an edge case here that might break the intended functionality.

*/
async function ensureBootstrapped(fixture: TestFixture) {
// Old-style bootstrap stack with default name
if (await fixture.aws.stackStatus('CDKToolkit') === undefined) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Are you sure this is necessary? just running bootstrap will no-op if no changes are detected, and if there are changes, shouldn't we bootstrap them?

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 guess, just cutting down on the duration (since that's the whole goal of this). It's still pretty expensive to do a no-op bootstrap.

Copy link
Contributor

Choose a reason for hiding this comment

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

Ok, i'm still wondering about the need to re-bootstrap when changes are introduced. But thats for a later discussion.

Comment on lines 47 to 59
const regionLease = await REGION_POOL.take();

context.output.write(` Stack prefix: ${stackNamePrefix}\n`);
context.output.write(` Test directory: ${integTestDir}\n`);
context.output.write(` Region: ${regionLease.value}\n`);

await cloneDirectory(path.join(__dirname, 'app'), integTestDir, context.output);
const fixture = new TestFixture(
integTestDir,
stackNamePrefix,
context.output,
regionLease,
context.aws);
Copy link
Contributor

Choose a reason for hiding this comment

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

Why take the lease here if it's going to be released within the dispose() method? As mentioned previously, would be nice to see take() and dispose() in the same block/scope, making it easier to reason about.

Would it make more sense to take the least as part of the TextFixture constructor?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh wait. You are correct that i left a bug.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Would it make more sense to take the least as part of the TextFixture constructor?

Can't. It's async.

Comment on lines +34 to +42
/**
* Higher order function to execute a block with a CDK app fixture
*
* Requires an AWS client to be passed in.
*
* For backwards compatibility with existing tests (so we don't have to change
* too much) the inner block is expecte to take a `TestFixture` object.
*/
export function withCdkApp<A extends TestContext & AwsContext>(block: (context: TestFixture) => Promise<void>) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Very minor: Not just "with cdk app" but also "with region-based leases".
Could maybe split that into its own higher order function chain-link, or move that within withDefaultFixture().

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Well this wrapper doesn't ADD a region based lease, it adds a cdk fixture.

It does REQUIRE a region lease to do that, but that's not what the name means.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The idea being that these wrappers should be freely composeable to add more setup and teardown.

@rix0rrr rix0rrr removed the pr/do-not-merge This PR should not be merged at this time. label Sep 10, 2020
@mergify
Copy link
Contributor

mergify bot commented Sep 10, 2020

Thank you for contributing! Your pull request will be updated from master and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork).

@iliapolo iliapolo added the pr/do-not-merge This PR should not be merged at this time. label Sep 10, 2020
@iliapolo
Copy link
Contributor

@rix0rrr Added do-not-merge since it looks like the discussions are over yet?

@rix0rrr rix0rrr removed the pr/do-not-merge This PR should not be merged at this time. label Sep 10, 2020
@aws-cdk-automation
Copy link
Collaborator

AWS CodeBuild CI Report

  • CodeBuild project: AutoBuildProject6AEA49D1-qxepHUsryhcu
  • Commit ID: 9d70478
  • Result: SUCCEEDED
  • Build Logs (available for 30 days)

Powered by github-codebuild-logs, available on the AWS Serverless Application Repository

@mergify
Copy link
Contributor

mergify bot commented Sep 10, 2020

Thank you for contributing! Your pull request will be updated from master and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork).

@mergify mergify bot merged commit 238d963 into master Sep 10, 2020
@mergify mergify bot deleted the huijbers/parallel-integ-tests branch September 10, 2020 14:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
contribution/core This is a PR that came from AWS.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants