From 208e28c403ccfc77d17562db5b63d5b7d9353e04 Mon Sep 17 00:00:00 2001 From: Sai Ray Date: Tue, 16 Jun 2026 18:00:12 -0400 Subject: [PATCH 1/7] chore: mid work --- ...k-ls-json-no-synth-time-in-ci.integtest.ts | 21 +++++++++++++++++++ .../toolkit-lib/lib/toolkit/toolkit.ts | 4 +++- .../toolkit-lib/test/actions/list.test.ts | 16 ++++++++++++++ 3 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/list/cdk-ls-json-no-synth-time-in-ci.integtest.ts diff --git a/packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/list/cdk-ls-json-no-synth-time-in-ci.integtest.ts b/packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/list/cdk-ls-json-no-synth-time-in-ci.integtest.ts new file mode 100644 index 000000000..f230d7eea --- /dev/null +++ b/packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/list/cdk-ls-json-no-synth-time-in-ci.integtest.ts @@ -0,0 +1,21 @@ +import { integTest, withDefaultFixture } from '../../../lib'; + +integTest( + 'cdk ls --json does not pollute stdout with synthesis time in CI', + withDefaultFixture(async (fixture) => { + // In CI mode the CLI routes non-error output to stdout. `cdk list` is a + // read-only query whose stdout is commonly piped (e.g. to `jq`), so the + // synthesis-time message must not appear there. Regression test for the + // synth-time line leaking into `cdk ls --json` output. + const stdout = await fixture.cdk(['ls', '--json', '--no-notices'], { + captureStderr: false, // return stdout only + modEnv: { + CI: 'true', + }, + }); + + expect(stdout).not.toContain('Synthesis time'); + // stdout should still contain the actual listing + expect(stdout).toContain(fixture.fullStackName('test-1')); + }), +); diff --git a/packages/@aws-cdk/toolkit-lib/lib/toolkit/toolkit.ts b/packages/@aws-cdk/toolkit-lib/lib/toolkit/toolkit.ts index 41589dea2..e1c063928 100644 --- a/packages/@aws-cdk/toolkit-lib/lib/toolkit/toolkit.ts +++ b/packages/@aws-cdk/toolkit-lib/lib/toolkit/toolkit.ts @@ -596,7 +596,9 @@ export class Toolkit extends CloudAssemblySourceBuilder { public async list(cx: ICloudAssemblySource, options: ListOptions = {}): Promise { const ioHelper = asIoHelper(this.ioHost, 'list'); const selectStacks = stacksOpt(options); - await using assembly = await synthAndMeasure(ioHelper, cx, selectStacks); + // Not `synthAndMeasure`: `list` is a read-only query and its synth-time message + // would pollute stdout when the result is piped (e.g. `list --json | jq`). + await using assembly = await assemblyFromSource(ioHelper, cx); const stackCollection = await assembly.selectStacksV2(selectStacks); const stacks = stackCollection.withDependencies(); diff --git a/packages/@aws-cdk/toolkit-lib/test/actions/list.test.ts b/packages/@aws-cdk/toolkit-lib/test/actions/list.test.ts index 7e72c1977..258eab51b 100644 --- a/packages/@aws-cdk/toolkit-lib/test/actions/list.test.ts +++ b/packages/@aws-cdk/toolkit-lib/test/actions/list.test.ts @@ -488,6 +488,22 @@ describe('list', () => { expect(mockDispose).toHaveBeenCalled(); await realDispose(); }); + + test('does not emit a synthesis-time message', async () => { + // list is a read-only query; the synth-time message (CDK_TOOLKIT_I1000) must + // not be emitted, so that machine-readable output (e.g. `list --json`) stays clean. + const cx = new TestCloudAssemblySource({ + stacks: [MOCK_STACK_A, MOCK_STACK_B, MOCK_STACK_C], + }); + + // WHEN + await toolkit.list(cx); + + // THEN + expect(ioHost.notifySpy).not.toHaveBeenCalledWith(expect.objectContaining({ + code: 'CDK_TOOLKIT_I1000', + })); + }); }); const MOCK_STACK_A: TestStackArtifact = { From 09cf01e586f39969012c179111e96dd7fbaa8398 Mon Sep 17 00:00:00 2001 From: Sai Ray Date: Tue, 16 Jun 2026 19:18:55 -0400 Subject: [PATCH 2/7] chore: mid work --- ...ls-ci-no-synth-time-on-stdout.integtest.ts | 17 +++++++++++++++ ...k-ls-json-no-synth-time-in-ci.integtest.ts | 21 ------------------- 2 files changed, 17 insertions(+), 21 deletions(-) create mode 100644 packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/list/cdk-ls-ci-no-synth-time-on-stdout.integtest.ts delete mode 100644 packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/list/cdk-ls-json-no-synth-time-in-ci.integtest.ts diff --git a/packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/list/cdk-ls-ci-no-synth-time-on-stdout.integtest.ts b/packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/list/cdk-ls-ci-no-synth-time-on-stdout.integtest.ts new file mode 100644 index 000000000..ceb5699f6 --- /dev/null +++ b/packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/list/cdk-ls-ci-no-synth-time-on-stdout.integtest.ts @@ -0,0 +1,17 @@ +import { integTest, withDefaultFixture } from '../../../lib'; + +integTest( + 'cdk ls in CI does not print synthesis time to stdout', + withDefaultFixture(async (fixture) => { + // In CI mode the CLI routes non-error output to stdout. `cdk ls` stdout is + // commonly piped (e.g. to `jq`), so it must contain the stack listing and + // not the "Synthesis time" status line. + const listing = await fixture.cdk(['ls'], { + captureStderr: false, // stdout only + modEnv: { CI: 'true' }, + }); + + expect(listing).toContain(fixture.fullStackName('test-1')); + expect(listing).not.toContain('Synthesis time'); + }), +); diff --git a/packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/list/cdk-ls-json-no-synth-time-in-ci.integtest.ts b/packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/list/cdk-ls-json-no-synth-time-in-ci.integtest.ts deleted file mode 100644 index f230d7eea..000000000 --- a/packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/list/cdk-ls-json-no-synth-time-in-ci.integtest.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { integTest, withDefaultFixture } from '../../../lib'; - -integTest( - 'cdk ls --json does not pollute stdout with synthesis time in CI', - withDefaultFixture(async (fixture) => { - // In CI mode the CLI routes non-error output to stdout. `cdk list` is a - // read-only query whose stdout is commonly piped (e.g. to `jq`), so the - // synthesis-time message must not appear there. Regression test for the - // synth-time line leaking into `cdk ls --json` output. - const stdout = await fixture.cdk(['ls', '--json', '--no-notices'], { - captureStderr: false, // return stdout only - modEnv: { - CI: 'true', - }, - }); - - expect(stdout).not.toContain('Synthesis time'); - // stdout should still contain the actual listing - expect(stdout).toContain(fixture.fullStackName('test-1')); - }), -); From 38fee23eb758cef564f9ddd22581c6e082286d62 Mon Sep 17 00:00:00 2001 From: Sai Ray Date: Tue, 16 Jun 2026 19:51:28 -0400 Subject: [PATCH 3/7] chore: mid work --- ...-not-print-synthesis-time-to-stdout.integtest.ts} | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) rename packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/list/{cdk-ls-ci-no-synth-time-on-stdout.integtest.ts => cdk-ls-in-ci-does-not-print-synthesis-time-to-stdout.integtest.ts} (54%) diff --git a/packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/list/cdk-ls-ci-no-synth-time-on-stdout.integtest.ts b/packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/list/cdk-ls-in-ci-does-not-print-synthesis-time-to-stdout.integtest.ts similarity index 54% rename from packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/list/cdk-ls-ci-no-synth-time-on-stdout.integtest.ts rename to packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/list/cdk-ls-in-ci-does-not-print-synthesis-time-to-stdout.integtest.ts index ceb5699f6..2376a6e3b 100644 --- a/packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/list/cdk-ls-ci-no-synth-time-on-stdout.integtest.ts +++ b/packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/list/cdk-ls-in-ci-does-not-print-synthesis-time-to-stdout.integtest.ts @@ -11,7 +11,15 @@ integTest( modEnv: { CI: 'true' }, }); - expect(listing).toContain(fixture.fullStackName('test-1')); - expect(listing).not.toContain('Synthesis time'); + const lines = listing.trim().split('\n').filter(line => line.length > 0); + + // there is an actual listing (guards against an empty pass) + expect(lines.length).toBeGreaterThan(0); + + // every line is a stack entry; a status line like "✨ Synthesis time: ..." + // would not carry the stack prefix, so it fails this check + for (const line of lines) { + expect(line).toContain(fixture.stackNamePrefix); + } }), ); From 0a5495b8e85abe4e1501e63d8bf7458dfea3a6ce Mon Sep 17 00:00:00 2001 From: Sai Ray Date: Tue, 16 Jun 2026 20:37:18 -0400 Subject: [PATCH 4/7] chore: mid work --- ...es-not-print-synthesis-time-to-stdout.integtest.ts | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/list/cdk-ls-in-ci-does-not-print-synthesis-time-to-stdout.integtest.ts b/packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/list/cdk-ls-in-ci-does-not-print-synthesis-time-to-stdout.integtest.ts index 2376a6e3b..c8a36fe56 100644 --- a/packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/list/cdk-ls-in-ci-does-not-print-synthesis-time-to-stdout.integtest.ts +++ b/packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/list/cdk-ls-in-ci-does-not-print-synthesis-time-to-stdout.integtest.ts @@ -3,21 +3,18 @@ import { integTest, withDefaultFixture } from '../../../lib'; integTest( 'cdk ls in CI does not print synthesis time to stdout', withDefaultFixture(async (fixture) => { - // In CI mode the CLI routes non-error output to stdout. `cdk ls` stdout is - // commonly piped (e.g. to `jq`), so it must contain the stack listing and - // not the "Synthesis time" status line. + // In CI mode, `cdk ls` output goes to stdout and is often piped, so it must + // be only the stack listing, not status lines like "✨ Synthesis time: ...". const listing = await fixture.cdk(['ls'], { + verbose: false, // no -v, so stdout is just the listing captureStderr: false, // stdout only modEnv: { CI: 'true' }, }); const lines = listing.trim().split('\n').filter(line => line.length > 0); - // there is an actual listing (guards against an empty pass) + // every line should be a stack; a synth-time line would not carry the prefix expect(lines.length).toBeGreaterThan(0); - - // every line is a stack entry; a status line like "✨ Synthesis time: ..." - // would not carry the stack prefix, so it fails this check for (const line of lines) { expect(line).toContain(fixture.stackNamePrefix); } From d3cd4ee76fddf075f75867334fb0644b4d1fb870 Mon Sep 17 00:00:00 2001 From: Sai Ray Date: Wed, 17 Jun 2026 11:24:54 -0400 Subject: [PATCH 5/7] fix(toolkit-lib): suppress list synth-time line via host instead of bypassing synthAndMeasure --- .../@aws-cdk/toolkit-lib/lib/toolkit/toolkit.ts | 4 +--- .../toolkit-lib/test/actions/list.test.ts | 16 ---------------- packages/aws-cdk/lib/cli/cdk-toolkit.ts | 5 +++++ packages/aws-cdk/test/cli/cdk-toolkit.test.ts | 17 +++++++++++++++++ 4 files changed, 23 insertions(+), 19 deletions(-) diff --git a/packages/@aws-cdk/toolkit-lib/lib/toolkit/toolkit.ts b/packages/@aws-cdk/toolkit-lib/lib/toolkit/toolkit.ts index e1c063928..41589dea2 100644 --- a/packages/@aws-cdk/toolkit-lib/lib/toolkit/toolkit.ts +++ b/packages/@aws-cdk/toolkit-lib/lib/toolkit/toolkit.ts @@ -596,9 +596,7 @@ export class Toolkit extends CloudAssemblySourceBuilder { public async list(cx: ICloudAssemblySource, options: ListOptions = {}): Promise { const ioHelper = asIoHelper(this.ioHost, 'list'); const selectStacks = stacksOpt(options); - // Not `synthAndMeasure`: `list` is a read-only query and its synth-time message - // would pollute stdout when the result is piped (e.g. `list --json | jq`). - await using assembly = await assemblyFromSource(ioHelper, cx); + await using assembly = await synthAndMeasure(ioHelper, cx, selectStacks); const stackCollection = await assembly.selectStacksV2(selectStacks); const stacks = stackCollection.withDependencies(); diff --git a/packages/@aws-cdk/toolkit-lib/test/actions/list.test.ts b/packages/@aws-cdk/toolkit-lib/test/actions/list.test.ts index 258eab51b..7e72c1977 100644 --- a/packages/@aws-cdk/toolkit-lib/test/actions/list.test.ts +++ b/packages/@aws-cdk/toolkit-lib/test/actions/list.test.ts @@ -488,22 +488,6 @@ describe('list', () => { expect(mockDispose).toHaveBeenCalled(); await realDispose(); }); - - test('does not emit a synthesis-time message', async () => { - // list is a read-only query; the synth-time message (CDK_TOOLKIT_I1000) must - // not be emitted, so that machine-readable output (e.g. `list --json`) stays clean. - const cx = new TestCloudAssemblySource({ - stacks: [MOCK_STACK_A, MOCK_STACK_B, MOCK_STACK_C], - }); - - // WHEN - await toolkit.list(cx); - - // THEN - expect(ioHost.notifySpy).not.toHaveBeenCalledWith(expect.objectContaining({ - code: 'CDK_TOOLKIT_I1000', - })); - }); }); const MOCK_STACK_A: TestStackArtifact = { diff --git a/packages/aws-cdk/lib/cli/cdk-toolkit.ts b/packages/aws-cdk/lib/cli/cdk-toolkit.ts index 33209a5c9..94e6b4a8b 100644 --- a/packages/aws-cdk/lib/cli/cdk-toolkit.ts +++ b/packages/aws-cdk/lib/cli/cdk-toolkit.ts @@ -960,6 +960,11 @@ export class CdkToolkit { ): Promise { this.ioHost.rewriteOnce(IO.CDK_TOOLKIT_I2901, (msg) => formatStackList(msg.data.stacks, options)); + // `list` is a read-only query whose stdout is commonly piped (e.g. `list --json | jq`). + // Synthesis still runs and is measured, but the "Synthesis time" line (I1000) must not + // be printed, since in CI mode non-error output goes to stdout and would corrupt the listing. + this.ioHost.once(IO.CDK_TOOLKIT_I1000, () => ({ preventDefault: true })); + await this.toolkit.list(this.props.cloudExecutable, { stacks: selectors.length > 0 ? { patterns: selectors, strategy: StackSelectionStrategy.PATTERN_MATCH, expand: ExpandStackSelection.UPSTREAM } diff --git a/packages/aws-cdk/test/cli/cdk-toolkit.test.ts b/packages/aws-cdk/test/cli/cdk-toolkit.test.ts index ddd61b59d..bda86a722 100644 --- a/packages/aws-cdk/test/cli/cdk-toolkit.test.ts +++ b/packages/aws-cdk/test/cli/cdk-toolkit.test.ts @@ -207,6 +207,23 @@ describe('list', () => { 'Test-Stack-B', ]); }); + + test('registers an I1000 suppressor so the synthesis-time line is not written', async () => { + // `list` synthesizes (and is measured) like any other command, but the + // "Synthesis time" line (CDK_TOOLKIT_I1000) must not be written: in CI mode + // non-error output goes to stdout, and `cdk ls` stdout is commonly piped. + const toolkit = defaultToolkitSetup(); + const onceSpy = jest.spyOn(ioHost, 'once'); + + // WHEN + await toolkit.list([]); + + // THEN - a one-shot suppressor for I1000 was registered that prevents default handling. + const i1000Call = onceSpy.mock.calls.find(([code]) => (code as any)?.code === 'CDK_TOOLKIT_I1000'); + expect(i1000Call).toBeDefined(); + const listener = i1000Call![1] as (msg: any) => any; + expect(listener({ code: 'CDK_TOOLKIT_I1000' })).toEqual({ preventDefault: true }); + }); }); describe('deploy', () => { From 87387447d8e53df128499a6631db40292dbd87ff Mon Sep 17 00:00:00 2001 From: Sai Ray Date: Wed, 17 Jun 2026 12:35:48 -0400 Subject: [PATCH 6/7] test(cli-integ): rename list synth-time test to cdk-cdk-ls prefix --- ...test.ts => cdk-cdk-ls-ci-no-synth-time-on-stdout.integtest.ts} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/list/{cdk-ls-in-ci-does-not-print-synthesis-time-to-stdout.integtest.ts => cdk-cdk-ls-ci-no-synth-time-on-stdout.integtest.ts} (100%) diff --git a/packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/list/cdk-ls-in-ci-does-not-print-synthesis-time-to-stdout.integtest.ts b/packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/list/cdk-cdk-ls-ci-no-synth-time-on-stdout.integtest.ts similarity index 100% rename from packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/list/cdk-ls-in-ci-does-not-print-synthesis-time-to-stdout.integtest.ts rename to packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/list/cdk-cdk-ls-ci-no-synth-time-on-stdout.integtest.ts From 0e515e81a264c17843ec88875c9e7938aea2b81d Mon Sep 17 00:00:00 2001 From: Sai Ray Date: Wed, 17 Jun 2026 16:49:59 -0400 Subject: [PATCH 7/7] fix(cli): gate list synth-time suppression behind --json --- ...ls-ci-no-synth-time-on-stdout.integtest.ts | 14 ++++++------ packages/aws-cdk/lib/cli/cdk-toolkit.ts | 8 +++---- packages/aws-cdk/test/cli/cdk-toolkit.test.ts | 22 ++++++++++++++----- 3 files changed, 28 insertions(+), 16 deletions(-) diff --git a/packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/list/cdk-cdk-ls-ci-no-synth-time-on-stdout.integtest.ts b/packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/list/cdk-cdk-ls-ci-no-synth-time-on-stdout.integtest.ts index c8a36fe56..c346830e1 100644 --- a/packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/list/cdk-cdk-ls-ci-no-synth-time-on-stdout.integtest.ts +++ b/packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/list/cdk-cdk-ls-ci-no-synth-time-on-stdout.integtest.ts @@ -1,14 +1,14 @@ import { integTest, withDefaultFixture } from '../../../lib'; integTest( - 'cdk ls in CI does not print synthesis time to stdout', + 'cdk ls --json in CI does not print synthesis time to stdout', withDefaultFixture(async (fixture) => { - // In CI mode, `cdk ls` output goes to stdout and is often piped, so it must - // be only the stack listing, not status lines like "✨ Synthesis time: ...". - const listing = await fixture.cdk(['ls'], { - verbose: false, // no -v, so stdout is just the listing - captureStderr: false, // stdout only - modEnv: { CI: 'true' }, + // `cdk ls --json` stdout is a machine-readable contract and is often piped (e.g. to `jq`), + // so it must be only the stack listing, not status lines like "✨ Synthesis time: ...". + const listing = await fixture.cdk(['ls', '--json'], { + verbose: false, // fixture defaults verbose on; turn it off so stdout is just the listing + captureStderr: false, // capture stdout only; stderr is folded into the result by default + modEnv: { CI: 'true' }, // CI routes non-error output to stdout (default is stderr) }); const lines = listing.trim().split('\n').filter(line => line.length > 0); diff --git a/packages/aws-cdk/lib/cli/cdk-toolkit.ts b/packages/aws-cdk/lib/cli/cdk-toolkit.ts index 94e6b4a8b..e00ceb427 100644 --- a/packages/aws-cdk/lib/cli/cdk-toolkit.ts +++ b/packages/aws-cdk/lib/cli/cdk-toolkit.ts @@ -960,10 +960,10 @@ export class CdkToolkit { ): Promise { this.ioHost.rewriteOnce(IO.CDK_TOOLKIT_I2901, (msg) => formatStackList(msg.data.stacks, options)); - // `list` is a read-only query whose stdout is commonly piped (e.g. `list --json | jq`). - // Synthesis still runs and is measured, but the "Synthesis time" line (I1000) must not - // be printed, since in CI mode non-error output goes to stdout and would corrupt the listing. - this.ioHost.once(IO.CDK_TOOLKIT_I1000, () => ({ preventDefault: true })); + // With `--json`, stdout must stay machine-parsable, so suppress the synth-time line (I1000). + if (options.json) { + this.ioHost.once(IO.CDK_TOOLKIT_I1000, () => ({ preventDefault: true })); + } await this.toolkit.list(this.props.cloudExecutable, { stacks: selectors.length > 0 diff --git a/packages/aws-cdk/test/cli/cdk-toolkit.test.ts b/packages/aws-cdk/test/cli/cdk-toolkit.test.ts index bda86a722..8543ad486 100644 --- a/packages/aws-cdk/test/cli/cdk-toolkit.test.ts +++ b/packages/aws-cdk/test/cli/cdk-toolkit.test.ts @@ -208,15 +208,14 @@ describe('list', () => { ]); }); - test('registers an I1000 suppressor so the synthesis-time line is not written', async () => { - // `list` synthesizes (and is measured) like any other command, but the - // "Synthesis time" line (CDK_TOOLKIT_I1000) must not be written: in CI mode - // non-error output goes to stdout, and `cdk ls` stdout is commonly piped. + test('with --json, suppresses the synthesis-time line so stdout stays machine-parsable', async () => { + // `cdk ls --json` stdout is a machine-readable contract; the "Synthesis time" line + // (CDK_TOOLKIT_I1000) must not be written (in CI mode non-error output goes to stdout). const toolkit = defaultToolkitSetup(); const onceSpy = jest.spyOn(ioHost, 'once'); // WHEN - await toolkit.list([]); + await toolkit.list([], { json: true }); // THEN - a one-shot suppressor for I1000 was registered that prevents default handling. const i1000Call = onceSpy.mock.calls.find(([code]) => (code as any)?.code === 'CDK_TOOLKIT_I1000'); @@ -224,6 +223,19 @@ describe('list', () => { const listener = i1000Call![1] as (msg: any) => any; expect(listener({ code: 'CDK_TOOLKIT_I1000' })).toEqual({ preventDefault: true }); }); + + test('without --json, does not suppress the synthesis-time line', async () => { + // Plain `cdk ls` is not a machine-readable contract, so the line is left alone. + const toolkit = defaultToolkitSetup(); + const onceSpy = jest.spyOn(ioHost, 'once'); + + // WHEN + await toolkit.list([]); + + // THEN + const i1000Call = onceSpy.mock.calls.find(([code]) => (code as any)?.code === 'CDK_TOOLKIT_I1000'); + expect(i1000Call).toBeUndefined(); + }); }); describe('deploy', () => {