Skip to content

Commit 1ace1ef

Browse files
authored
fix(aws-cdk-lib): temporary Cloud Assemblies are not cleaned up (#36043)
The CDK framework creates a temporary directory in `/tmp` for every unit test, and never cleans those up. In this PR, register all temporary assembly directories created by doing `new Stack()` or `new App()` without an `outdir`, and delete them when the Node process exits. This will only affect unit tests: if the `outdir` property is set explicitly, or the CDK App is being synthesized by the CLI (and `$CDK_OUTDIR` is set), the assembly directory will not be cleaned. For users: if you set `outdir` you are reponsible for cleaning up the directory. If you don't set `outdir`, it will be automatically removed at some point. This will benefit both `aws-cdk` development itself, as well as users writing unit tests against CDK. Relates to #802. Also in this PR: cleanup of other temporary directories we create during tests. These will only benefit development on `aws-cdk` itself. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
1 parent 978382a commit 1ace1ef

File tree

14 files changed

+76
-14
lines changed

14 files changed

+76
-14
lines changed

packages/@aws-cdk-testing/framework-integ/test/aws-s3-deployment/test/integ.bucket-deployment-big-response.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ class TestBucketDeployment extends cdk.Stack {
3131
const sources = [];
3232
for (let i = 0; i < numFiles; i++) {
3333
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'tmpcdk'));
34+
process.on('exit', () => {
35+
fs.rmSync(tempDir, { force: true, recursive: true });
36+
});
37+
3438
fs.mkdirSync(tempDir, { recursive: true });
3539
const fileName = `${i+1}.txt`;
3640
const filePath = path.join(tempDir, fileName);

packages/@aws-cdk-testing/framework-integ/test/aws-s3-deployment/test/integ.bucket-deployment-large-file.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ const bucket = new Bucket(stack, 'Bucket', {
3030

3131
// Create a temporary directory for our large files
3232
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'cdk-large-files-'));
33+
process.on('exit', () => {
34+
fs.rmSync(tempDir, { force: true, recursive: true });
35+
});
3336

3437
// Generate a large JSON file (10MB) programmatically
3538
const largeJsonFilePath = path.join(tempDir, 'large-file.json');

packages/@aws-cdk/custom-resource-handlers/test/core/nodejs-entrypoint-handler.test.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,9 @@ async function invokeHandler(req: AWSLambda.CloudFormationCustomResourceEvent, u
179179

180180
// stage entry point and user handler.
181181
const workdir = fs.mkdtempSync(path.join(os.tmpdir(), 'cdk-custom-resource-provider-handler-test-'));
182+
process.on('exit', () => {
183+
fs.rmSync(workdir, { recursive: true, force: true });
184+
});
182185
entrypoint.external.userHandlerIndex = path.join(workdir, 'index.js');
183186
fs.writeFileSync(entrypoint.external.userHandlerIndex, `exports.handler = ${userHandler.toString()};`);
184187

packages/@aws-cdk/custom-resource-handlers/test/custom-resources-framework/callable-expr.test.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ describe('callable expression', () => {
1414
tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'cdk-test'));
1515
});
1616

17+
afterEach(() => {
18+
fs.removeSync(tmpDir);
19+
});
20+
1721
test('callable expression toString return expression name', () => {
1822
// GIVEN
1923
const expressionName = 'determineRuntime';

packages/@aws-cdk/custom-resource-handlers/test/custom-resources-framework/framework.test.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ describe('framework', () => {
1414
tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'cdk-test'));
1515
});
1616

17+
afterEach(() => {
18+
fs.removeSync(tmpDir);
19+
});
20+
1721
test('can codegen cdk function', () => {
1822
// GIVEN
1923
const module = new HandlerFrameworkModule('cdk-testing/test-provider');

packages/@aws-cdk/custom-resource-handlers/test/custom-resources-framework/module-importer.test.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ describe('module importer', () => {
1212
tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'cdk-test'));
1313
});
1414

15+
afterEach(() => {
16+
fs.removeSync(tmpDir);
17+
});
18+
1519
test('aliased import', () => {
1620
// GIVEN
1721
const module = new HandlerFrameworkModule('cdk-testing');

packages/@aws-cdk/custom-resource-handlers/test/nodejs-entrypoint.test.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,9 @@ async function invokeHandler(req: AWSLambda.CloudFormationCustomResourceEvent, u
179179

180180
// stage entry point and user handler.
181181
const workdir = fs.mkdtempSync(path.join(os.tmpdir(), 'cdk-custom-resource-provider-handler-test-'));
182+
process.on('exit', () => {
183+
fs.rmSync(workdir, { recursive: true, force: true });
184+
});
182185
entrypoint.external.userHandlerIndex = path.join(workdir, 'index.js');
183186
fs.writeFileSync(entrypoint.external.userHandlerIndex, `exports.handler = ${userHandler.toString()};`);
184187

packages/@aws-cdk/integ-tests-alpha/test/manifest-synthesizer.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ beforeEach(() => {
1818
});
1919

2020
afterEach(() => {
21+
fs.rmSync(tmpDir, { force: true, recursive: true });
2122
jest.restoreAllMocks();
2223
});
2324

packages/aws-cdk-lib/aws-s3-deployment/lib/source.ts

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -193,17 +193,22 @@ export class Source {
193193
return {
194194
bind: (scope: Construct, context?: DeploymentSourceContext) => {
195195
const workdir = FileSystem.mkdtemp('s3-deployment');
196-
const outputPath = join(workdir, objectKey);
197-
const rendered = renderData(data);
198-
fs.mkdirSync(dirname(outputPath), { recursive: true });
199-
fs.writeFileSync(outputPath, rendered.text);
200-
const asset = this.asset(workdir).bind(scope, context);
201-
return {
202-
bucket: asset.bucket,
203-
zipObjectKey: asset.zipObjectKey,
204-
markers: rendered.markers,
205-
markersConfig: markersConfig,
206-
};
196+
try {
197+
const outputPath = join(workdir, objectKey);
198+
const rendered = renderData(data);
199+
fs.mkdirSync(dirname(outputPath), { recursive: true });
200+
fs.writeFileSync(outputPath, rendered.text);
201+
const asset = this.asset(workdir).bind(scope, context);
202+
return {
203+
bucket: asset.bucket,
204+
zipObjectKey: asset.zipObjectKey,
205+
markers: rendered.markers,
206+
markersConfig: markersConfig,
207+
};
208+
} finally {
209+
// Calling `this.asset()` has copied files to the assembly, so we can delete the temporary directory.
210+
FileSystem.rmrf(workdir);
211+
}
207212
},
208213
};
209214
}

packages/aws-cdk-lib/core/lib/fs/index.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,5 +69,12 @@ export class FileSystem {
6969
return fs.mkdtempSync(path.join(FileSystem.tmpdir, prefix));
7070
}
7171

72+
/**
73+
* Deletes a directory
74+
*/
75+
public static rmrf(dirname: string) {
76+
fs.rmSync(dirname, { force: true, recursive: true });
77+
}
78+
7279
private static _tmpdir?: string;
7380
}

0 commit comments

Comments
 (0)