概要
apps/cdk/test/ の jest テスト(serverless-fullstack-webapp-starter-kit.test.ts と -without-domain.test.ts)は new cdk.App() を outdir 未指定 で生成している。CLI 経由ではないため CDK は os.tmpdir() に cdk.outXXXXXX を毎回新規作成し、プロセス終了時にも削除しない。加えて各 synth で Lambda@Edge / webapp Lambda / deploy-time-build のソースを asset.* としてローカルステージングするため、テストを繰り返すたびに ${TMPDIR} 配下の cdk.out* が単調増加する。
再現
origin/dev/v3 にて:
cd apps/cdk
BEFORE=$(ls -1d "${TMPDIR:-/tmp}"/cdk.out* 2>/dev/null | wc -l)
pnpm run test:unit
AFTER=$(ls -1d "${TMPDIR:-/tmp}"/cdk.out* 2>/dev/null | wc -l)
echo "delta: $((AFTER - BEFORE))"
du -sh "${TMPDIR:-/tmp}"/cdk.out* 2>/dev/null | tail
各テストファイルにつき最低 1 個の cdk.outXXXXXX が新規作成され、実行を繰り返してもクリーンアップされない。1 synth あたりのサイズは Lambda@Edge / webapp Lambda のバンドル・DSQL migrator の deploy-time-build コンテキスト等で数十 MB オーダーになる。
該当箇所:
apps/cdk/test/serverless-fullstack-webapp-starter-kit.test.ts:9 — const app = new cdk.App();
apps/cdk/test/serverless-fullstack-webapp-starter-kit-without-domain.test.ts:9 — const app = new cdk.App();
影響
- CI ジョブと開発マシンのローカルディスクを圧迫する。特にローカルで pre-commit フックや watch モードでテストが繰り返し実行されると顕在化しやすい
- macOS の
TMPDIR はユーザー単位(/var/folders/…)で、他ツールが同一ボリュームを使うため、No space left on device を他コマンドが踏むまで気付きにくい
- CI の一時ストレージが枯渇して以降のステップが失敗する可能性がある
提案する対応
apps/cdk/test/ 共通の App 生成ヘルパを用意し、以下 2 点を同時に適用する。
1. outdir をリポジトリ内固定 dir にする
毎回新規 TMPDIR を作らず、テストファイル単位のユニークな固定 dir に上書き出力させる。累積を止められる。
// apps/cdk/test/helpers/test-app.ts
import * as path from 'node:path';
import * as cdk from 'aws-cdk-lib';
export function createTestApp(outdirKey: string): cdk.App {
return new cdk.App({
outdir: path.join(__dirname, '..', '.cdk.out.test', outdirKey),
context: {
'aws:cdk:disable-asset-staging': true,
},
});
}
.gitignore に .cdk.out.test/ を追加する。jest 並列ワーカー衝突を避けるため outdirKey はテストファイル単位でユニークにする。
2. アセットステージングを無効化する(aws:cdk:disable-asset-staging)
Template.fromStack は CFN テンプレートのみ参照し、asset.* の物理コピーは不要。context フラグでステージングを止めれば 1 synth あたりの一時消費が大幅に減る(アセットハッシュは変わらず、CFN テンプレートの内容は不変なので既存の snapshot は影響を受けない)。
3. (任意)jest globalTeardown による defense-in-depth
1 と 2 が効いていれば TMPDIR には cdk.out* は作られない想定だが、万一の残存に備え jest 実行開始後に作られた cdk.out* のみを掃除する globalTeardown を用意しておくと安全網になる(開始時刻を globalSetup で env に記録し、それ以降の birthtime/mtime を持つものだけを削除。CDK CLI や他プロセスの pre-existing な outdir には触れない)。
完了条件
apps/cdk/test/*.ts の new cdk.App() が全てヘルパ経由になり outdir が固定される
aws:cdk:disable-asset-staging が全テスト App に適用される
- フル
pnpm run test:unit 実行後の ${TMPDIR} の cdk.out* 増加が 0(あるいはリポジトリ内固定 dir のみ)
- 既存の snapshot / テンプレートアサーションが不変であること
概要
apps/cdk/test/の jest テスト(serverless-fullstack-webapp-starter-kit.test.tsと-without-domain.test.ts)はnew cdk.App()をoutdir未指定 で生成している。CLI 経由ではないため CDK はos.tmpdir()にcdk.outXXXXXXを毎回新規作成し、プロセス終了時にも削除しない。加えて各 synth で Lambda@Edge / webapp Lambda / deploy-time-build のソースをasset.*としてローカルステージングするため、テストを繰り返すたびに${TMPDIR}配下のcdk.out*が単調増加する。再現
origin/dev/v3にて:各テストファイルにつき最低 1 個の
cdk.outXXXXXXが新規作成され、実行を繰り返してもクリーンアップされない。1 synth あたりのサイズは Lambda@Edge / webapp Lambda のバンドル・DSQL migrator の deploy-time-build コンテキスト等で数十 MB オーダーになる。該当箇所:
apps/cdk/test/serverless-fullstack-webapp-starter-kit.test.ts:9—const app = new cdk.App();apps/cdk/test/serverless-fullstack-webapp-starter-kit-without-domain.test.ts:9—const app = new cdk.App();影響
TMPDIRはユーザー単位(/var/folders/…)で、他ツールが同一ボリュームを使うため、No space left on deviceを他コマンドが踏むまで気付きにくい提案する対応
apps/cdk/test/共通の App 生成ヘルパを用意し、以下 2 点を同時に適用する。1.
outdirをリポジトリ内固定 dir にする毎回新規 TMPDIR を作らず、テストファイル単位のユニークな固定 dir に上書き出力させる。累積を止められる。
.gitignoreに.cdk.out.test/を追加する。jest 並列ワーカー衝突を避けるためoutdirKeyはテストファイル単位でユニークにする。2. アセットステージングを無効化する(
aws:cdk:disable-asset-staging)Template.fromStackは CFN テンプレートのみ参照し、asset.*の物理コピーは不要。context フラグでステージングを止めれば 1 synth あたりの一時消費が大幅に減る(アセットハッシュは変わらず、CFN テンプレートの内容は不変なので既存の snapshot は影響を受けない)。3. (任意)jest
globalTeardownによる defense-in-depth1 と 2 が効いていれば TMPDIR には
cdk.out*は作られない想定だが、万一の残存に備え jest 実行開始後に作られたcdk.out*のみを掃除するglobalTeardownを用意しておくと安全網になる(開始時刻をglobalSetupで env に記録し、それ以降のbirthtime/mtimeを持つものだけを削除。CDK CLI や他プロセスの pre-existing な outdir には触れない)。完了条件
apps/cdk/test/*.tsのnew cdk.App()が全てヘルパ経由になりoutdirが固定されるaws:cdk:disable-asset-stagingが全テスト App に適用されるpnpm run test:unit実行後の${TMPDIR}のcdk.out*増加が 0(あるいはリポジトリ内固定 dir のみ)