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

fix(integ-runner): Fix call to spawnSync for hooks commands #22429

Merged
merged 22 commits into from
Oct 19, 2022
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 17 additions & 9 deletions packages/@aws-cdk/integ-runner/lib/runner/integ-test-runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { RequireApproval } from '@aws-cdk/cloud-assembly-schema';
import { DeployOptions, DestroyOptions } from 'cdk-cli-wrapper';
import * as fs from 'fs-extra';
import * as logger from '../logger';
import { chain, exec } from '../utils';
import { exec, prepareForExec } from '../utils';
import { DestructiveChange, AssertionResults, AssertionResult } from '../workers/common';
import { IntegRunnerOptions, IntegRunner, DEFAULT_SYNTH_OPTIONS } from './runner-base';

Expand Down Expand Up @@ -222,17 +222,21 @@ export class IntegTestRunner extends IntegRunner {
const actualTestCase = this.actualTestSuite.testSuite[testCaseName];
try {
if (actualTestCase.hooks?.preDestroy) {
exec([chain(actualTestCase.hooks.preDestroy)], {
cwd: path.dirname(this.snapshotDir),
actualTestCase.hooks.preDestroy.forEach(cmd => {
exec(prepareForExec(cmd), {
cwd: path.dirname(this.snapshotDir),
});
});
}
this.cdk.destroy({
...destroyArgs,
});

if (actualTestCase.hooks?.postDestroy) {
exec([chain(actualTestCase.hooks.postDestroy)], {
cwd: path.dirname(this.snapshotDir),
actualTestCase.hooks.postDestroy.forEach(cmd => {
exec(prepareForExec(cmd), {
cwd: path.dirname(this.snapshotDir),
});
});
}
} catch (e) {
Expand All @@ -255,8 +259,10 @@ export class IntegTestRunner extends IntegRunner {
const actualTestCase = this.actualTestSuite.testSuite[testCaseName];
try {
if (actualTestCase.hooks?.preDeploy) {
exec([chain(actualTestCase.hooks?.preDeploy)], {
cwd: path.dirname(this.snapshotDir),
actualTestCase.hooks.preDeploy.forEach(cmd => {
exec(prepareForExec(cmd), {
cwd: path.dirname(this.snapshotDir),
});
});
}
// if the update workflow is not disabled, first
Expand Down Expand Up @@ -297,8 +303,10 @@ export class IntegTestRunner extends IntegRunner {
});

if (actualTestCase.hooks?.postDeploy) {
exec([chain(actualTestCase.hooks?.postDeploy)], {
cwd: path.dirname(this.snapshotDir),
actualTestCase.hooks.postDeploy.forEach(cmd => {
exec(prepareForExec(cmd), {
cwd: path.dirname(this.snapshotDir),
});
});
}

Expand Down
12 changes: 12 additions & 0 deletions packages/@aws-cdk/integ-runner/lib/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,18 @@ export function chain(commands: string[]): string {
return commands.filter(c => !!c).join(' && ');
}

/**
* Prepare command for execution by exec
*/
export function prepareForExec(command: string): string[] {
let chunks = command.split(/\s+/);
const cmd = chunks.shift();
if (cmd !== undefined) {
return [cmd, chunks.join(' ')];
Copy link
Contributor

Choose a reason for hiding this comment

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

Should this be return chunks instead?

For example if I had

hooks: {
  preDeploy: ['npx cdk deploy'],
}

I would want it to return ['npx', 'cdk', 'deploy'] right?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@corymhall, thank you for the comment, for the command you mentioned it could be like that. But for example for the command echo "preDeploy hook" if we just split it by space it will result in ['echo', '"preDeploy', 'hook"'] which seems to be not the correct input for exec.

Copy link
Contributor

Choose a reason for hiding this comment

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

You could do something like this instead in order to keep quoted sections together.

let chunks = command.match(/(?:[^\s"]+|"[^"]*")+/g)
// ['echo', '"preDeploy hook"']

I think if you use arguments with spawnSync each argument to the command needs to be its own element in the list.

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, make sense, I updated the solution. Thank you again for the review.

}
return [];
}


/**
* A class holding a set of items which are being crossed off in time
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -347,16 +347,22 @@ describe('IntegTest runIntegTests', () => {
// THEN
expect(spawnSyncMock.mock.calls).toEqual(expect.arrayContaining([
expect.arrayContaining([
'echo "preDeploy"',
'echo', ['"preDeploy hook"'],
]),
expect.arrayContaining([
'echo "postDeploy"',
'echo', ['"postDeploy hook"'],
]),
expect.arrayContaining([
'echo "preDestroy"',
'echo', ['"preDestroy hook"'],
]),
expect.arrayContaining([
'echo "postDestroy"',
'echo', ['"postDestroy hook"'],
]),
expect.arrayContaining([
'ls', [''],
]),
expect.arrayContaining([
'echo', ['-n "No new line"'],
]),
]));
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@
"stackUpdateWorkflow": false,
"diffAssets": false,
"hooks": {
"preDeploy": ["echo \"preDeploy\""],
"postDeploy": ["echo \"postDeploy\""],
"preDestroy": ["echo \"preDestroy\""],
"postDestroy": ["echo \"postDestroy\""]
"preDeploy": ["echo \"preDeploy hook\"", "ls", "echo -n \"No new line\""],
"postDeploy": ["echo \"postDeploy hook\""],
"preDestroy": ["echo \"preDestroy hook\""],
"postDestroy": ["echo \"postDestroy hook\""]
},
"allowDestroy": [
"AWS::IAM::Role"
Expand Down
4 changes: 3 additions & 1 deletion packages/@aws-cdk/integ-tests/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@
"compat": "cdk-compat",
"rosetta:extract": "yarn --silent jsii-rosetta extract",
"build+extract": "yarn build && yarn rosetta:extract",
"build+test+extract": "yarn build+test && yarn rosetta:extract"
"build+test+extract": "yarn build+test && yarn rosetta:extract",
"integ": "integ-runner"
Copy link
Contributor

Choose a reason for hiding this comment

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

This isn't needed in this package.

},
"author": {
"name": "Amazon Web Services",
Expand All @@ -65,6 +66,7 @@
"@aws-cdk/cdk-build-tools": "0.0.0",
"@aws-cdk/cx-api": "0.0.0",
"@aws-cdk/pkglint": "0.0.0",
"@aws-cdk/integ-runner": "0.0.0",
Copy link
Contributor

Choose a reason for hiding this comment

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

Nor this.

"@types/fs-extra": "^8.1.2",
"@types/jest": "^27.5.2",
"@types/node": "^14.18.32",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"version": "21.0.0",
"files": {
"21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": {
"source": {
"path": "IntegDefaultTestDeployAssert4E6713E1.template.json",
"packaging": "file"
},
"destinations": {
"current_account-current_region": {
"bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
"objectKey": "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json",
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
}
}
}
},
"dockerImages": {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"Parameters": {
"BootstrapVersion": {
"Type": "AWS::SSM::Parameter::Value<String>",
"Default": "/cdk-bootstrap/hnb659fds/version",
"Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]"
}
},
"Rules": {
"CheckBootstrapVersion": {
"Assertions": [
{
"Assert": {
"Fn::Not": [
{
"Fn::Contains": [
[
"1",
"2",
"3",
"4",
"5"
],
{
"Ref": "BootstrapVersion"
}
]
}
]
},
"AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI."
}
]
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"version":"21.0.0"}
18 changes: 18 additions & 0 deletions packages/@aws-cdk/integ-tests/test/app.integ.snapshot/integ.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"version": "21.0.0",
"testCases": {
"Integ/DefaultTest": {
"stacks": [
"Default"
],
"assertionStack": "Integ/DefaultTest/DeployAssert",
"assertionStackName": "IntegDefaultTestDeployAssert4E6713E1",
"hooks": {
"preDeploy": ["echo \"preDeploy\""],
"postDeploy": ["echo \"postDeploy\""],
"preDestroy": ["echo \"preDestroy\""],
"postDestroy": ["echo \"postDestroy\""]
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
{
"version": "21.0.0",
"artifacts": {
"Tree": {
"type": "cdk:tree",
"properties": {
"file": "tree.json"
}
},
"IntegDefaultTestDeployAssert4E6713E1.assets": {
"type": "cdk:asset-manifest",
"properties": {
"file": "IntegDefaultTestDeployAssert4E6713E1.assets.json",
"requiresBootstrapStackVersion": 6,
"bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version"
}
},
"IntegDefaultTestDeployAssert4E6713E1": {
"type": "aws:cloudformation:stack",
"environment": "aws://unknown-account/unknown-region",
"properties": {
"templateFile": "IntegDefaultTestDeployAssert4E6713E1.template.json",
"validateOnSynth": false,
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}",
"cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}",
"stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json",
"requiresBootstrapStackVersion": 6,
"bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version",
"additionalDependencies": [
"IntegDefaultTestDeployAssert4E6713E1.assets"
],
"lookupRole": {
"arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}",
"requiresBootstrapStackVersion": 8,
"bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version"
}
},
"dependencies": [
"IntegDefaultTestDeployAssert4E6713E1.assets"
],
"metadata": {
"/Integ/DefaultTest/DeployAssert/BootstrapVersion": [
{
"type": "aws:cdk:logicalId",
"data": "BootstrapVersion"
}
],
"/Integ/DefaultTest/DeployAssert/CheckBootstrapVersion": [
{
"type": "aws:cdk:logicalId",
"data": "CheckBootstrapVersion"
}
]
},
"displayName": "Integ/DefaultTest/DeployAssert"
}
}
}
57 changes: 57 additions & 0 deletions packages/@aws-cdk/integ-tests/test/app.integ.snapshot/tree.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
{
"version": "tree-0.1",
"tree": {
"id": "App",
"path": "",
"children": {
"Tree": {
"id": "Tree",
"path": "Tree",
"constructInfo": {
"fqn": "constructs.Construct",
"version": "10.1.102"
}
},
"Integ": {
"id": "Integ",
"path": "Integ",
"children": {
"DefaultTest": {
"id": "DefaultTest",
"path": "Integ/DefaultTest",
"children": {
"Default": {
"id": "Default",
"path": "Integ/DefaultTest/Default",
"constructInfo": {
"fqn": "constructs.Construct",
"version": "10.1.102"
}
},
"DeployAssert": {
"id": "DeployAssert",
"path": "Integ/DefaultTest/DeployAssert",
"constructInfo": {
"fqn": "@aws-cdk/core.Stack",
"version": "0.0.0"
}
}
},
"constructInfo": {
"fqn": "@aws-cdk/integ-tests.IntegTestCase",
"version": "0.0.0"
}
}
},
"constructInfo": {
"fqn": "@aws-cdk/integ-tests.IntegTest",
"version": "0.0.0"
}
}
},
"constructInfo": {
"fqn": "@aws-cdk/core.App",
"version": "0.0.0"
}
}
}
7 changes: 7 additions & 0 deletions packages/@aws-cdk/integ-tests/test/integ.app.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { App, Stack } from '@aws-cdk/core';
Copy link
Contributor

Choose a reason for hiding this comment

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

This isn't testing anything. Why is this here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@TheRealAmazonKendra, I can actually remove this I added it to avoid the linter issue saying PR must have at least one integration test update. But integ-runner doesn't have its own integration tests that's why I added this small test. And with this test integ-tests/package.json will also be reverted.

import { IntegTest } from '../lib';

const app = new App();
const stack = new Stack();

new IntegTest(app, 'Integ', { testCases: [stack] });