Skip to content

Commit 4bc3fde

Browse files
committed
fix: restore preview-specific harness functionality
Addresses review feedback — restores preview's versions of files that have harness-specific code paths which were accidentally dropped: - deploy flow: harness post-CDK deploy + teardown in TUI - remove flow: full harness removal states/handlers - create command: CLI harness creation path with --model-id etc. - status: harness tracking and display - integration/unit tests: use preview's test fixtures
1 parent 4952ea0 commit 4bc3fde

9 files changed

Lines changed: 659 additions & 286 deletions

File tree

integ-tests/add-remove-ab-test.test.ts

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,8 @@ import {
55
readProjectConfig,
66
runCLI,
77
} from '../src/test-utils/index.js';
8-
import { createTelemetryHelper } from '../src/test-utils/telemetry-helper.js';
98
import { afterAll, beforeAll, describe, expect, it } from 'vitest';
109

11-
const telemetry = createTelemetryHelper();
12-
1310
async function runSuccess(args: string[], cwd: string) {
1411
const result = await runCLI(args, cwd);
1512
expect(result.exitCode, `stdout: ${result.stdout}, stderr: ${result.stderr}`).toBe(0);
@@ -41,7 +38,6 @@ describe('integration: add and remove ab-test', () => {
4138

4239
afterAll(async () => {
4340
await project.cleanup();
44-
telemetry.destroy();
4541
});
4642

4743
it('requires --name for JSON mode', async () => {
@@ -158,26 +154,17 @@ describe('integration: add and remove ab-test', () => {
158154
});
159155

160156
it('removes ab-test', async () => {
161-
const result = await runCLI(['remove', 'ab-test', '--name', 'MyIntegTest', '--json'], project.projectPath, {
162-
env: telemetry.env,
163-
});
164-
expect(result.exitCode).toBe(0);
165-
const json = JSON.parse(result.stdout);
157+
const json = await runSuccess(['remove', 'ab-test', '--name', 'MyIntegTest', '--json'], project.projectPath);
166158
expect(json.success).toBe(true);
167159

160+
// Verify removal from agentcore.json
168161
const spec = await readProjectConfig(project.projectPath);
169162
const abTest = spec.abTests?.find((t: { name: string }) => t.name === 'MyIntegTest');
170163
expect(abTest).toBeUndefined();
171-
telemetry.assertMetricEmitted({ command: 'remove.ab-test', exit_reason: 'success' });
172164
});
173165

174166
it('remove returns error for non-existent test', async () => {
175-
const result = await runCLI(['remove', 'ab-test', '--name', 'DoesNotExist', '--json'], project.projectPath, {
176-
env: telemetry.env,
177-
});
178-
expect(result.exitCode).toBe(1);
179-
const json = JSON.parse(result.stdout);
167+
const json = await runFailure(['remove', 'ab-test', '--name', 'DoesNotExist', '--json'], project.projectPath);
180168
expect(json.error).toContain('not found');
181-
telemetry.assertMetricEmitted({ command: 'remove.ab-test', exit_reason: 'failure' });
182169
});
183170
});

integ-tests/add-remove-config-bundle.test.ts

Lines changed: 17 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,10 @@ import {
77
runFailure,
88
runSuccess,
99
} from '../src/test-utils/index.js';
10-
import { createTelemetryHelper } from '../src/test-utils/telemetry-helper.js';
1110
import { writeFile } from 'node:fs/promises';
1211
import { join } from 'node:path';
1312
import { afterAll, beforeAll, describe, expect, it } from 'vitest';
1413

15-
const telemetry = createTelemetryHelper();
16-
1714
describe('integration: add and remove config-bundle', () => {
1815
let project: TestProject;
1916

@@ -23,7 +20,6 @@ describe('integration: add and remove config-bundle', () => {
2320

2421
afterAll(async () => {
2522
await project.cleanup();
26-
telemetry.destroy();
2723
});
2824

2925
// ── Add lifecycle ─────────────────────────────────────────────────────
@@ -44,7 +40,7 @@ describe('integration: add and remove config-bundle', () => {
4440
expect(json.bundleName).toBe('InlineBundle');
4541

4642
const config = await readProjectConfig(project.projectPath);
47-
const bundle = config.configBundles.find(b => b.name === 'InlineBundle');
43+
const bundle = config.configBundles!.find(b => b.name === 'InlineBundle');
4844
expect(bundle).toBeDefined();
4945
expect(bundle!.type).toBe('ConfigurationBundle');
5046
expect(bundle!.branchName).toBe('mainline');
@@ -72,7 +68,7 @@ describe('integration: add and remove config-bundle', () => {
7268
expect(json.bundleName).toBe('FileBundle');
7369

7470
const config = await readProjectConfig(project.projectPath);
75-
const bundle = config.configBundles.find(b => b.name === 'FileBundle');
71+
const bundle = config.configBundles!.find(b => b.name === 'FileBundle');
7672
expect(bundle).toBeDefined();
7773
expect(Object.keys(bundle!.components)).toHaveLength(2);
7874
});
@@ -106,7 +102,7 @@ describe('integration: add and remove config-bundle', () => {
106102
expect(json.bundleName).toBe('FullOptsBundle');
107103

108104
const config = await readProjectConfig(project.projectPath);
109-
const bundle = config.configBundles.find(b => b.name === 'FullOptsBundle');
105+
const bundle = config.configBundles!.find(b => b.name === 'FullOptsBundle');
110106
expect(bundle).toBeDefined();
111107
expect(bundle!.description).toBe('A bundle with all optional fields');
112108
expect(bundle!.branchName).toBe('feature-branch');
@@ -131,7 +127,7 @@ describe('integration: add and remove config-bundle', () => {
131127
expect(json.bundleName).toBe('PlaceholderBundle');
132128

133129
const config = await readProjectConfig(project.projectPath);
134-
const bundle = config.configBundles.find(b => b.name === 'PlaceholderBundle');
130+
const bundle = config.configBundles!.find(b => b.name === 'PlaceholderBundle');
135131
expect(bundle).toBeDefined();
136132
const keys = Object.keys(bundle!.components);
137133
expect(keys).toContain('{{runtime:AgentA}}');
@@ -232,45 +228,37 @@ describe('integration: add and remove config-bundle', () => {
232228

233229
describe('remove config-bundle', () => {
234230
it('removes an existing config bundle', async () => {
235-
const result = await runCLI(
231+
const json = await runSuccess(
236232
['remove', 'config-bundle', '--name', 'InlineBundle', '--json'],
237-
project.projectPath,
238-
{ env: telemetry.env }
233+
project.projectPath
239234
);
240235

241-
expect(result.exitCode).toBe(0);
242-
const json = JSON.parse(result.stdout);
243236
expect(json.success).toBe(true);
244237

245238
const config = await readProjectConfig(project.projectPath);
246-
const bundle = config.configBundles.find(b => b.name === 'InlineBundle');
239+
const bundle = config.configBundles!.find(b => b.name === 'InlineBundle');
247240
expect(bundle).toBeUndefined();
248-
telemetry.assertMetricEmitted({ command: 'remove.config-bundle', exit_reason: 'success' });
249241
});
250242

251243
it('returns error for non-existent bundle', async () => {
252-
const result = await runCLI(
244+
const json = await runFailure(
253245
['remove', 'config-bundle', '--name', 'DoesNotExist', '--json'],
254-
project.projectPath,
255-
{ env: telemetry.env }
246+
project.projectPath
256247
);
257248

258-
expect(result.exitCode).toBe(1);
259-
const json = JSON.parse(result.stdout);
260249
expect(json.error).toContain('not found');
261-
telemetry.assertMetricEmitted({ command: 'remove.config-bundle', exit_reason: 'failure' });
262250
});
263251

264252
it('removes all remaining config bundles one by one', async () => {
265253
const configBefore = await readProjectConfig(project.projectPath);
266-
const remaining = configBefore.configBundles.map(b => b.name);
254+
const remaining = configBefore.configBundles!.map(b => b.name);
267255

268256
for (const name of remaining) {
269257
await runSuccess(['remove', 'config-bundle', '--name', name, '--json'], project.projectPath);
270258
}
271259

272260
const configAfter = await readProjectConfig(project.projectPath);
273-
expect(configAfter.configBundles).toHaveLength(0);
261+
expect(configAfter.configBundles!).toHaveLength(0);
274262
});
275263
});
276264

@@ -294,21 +282,21 @@ describe('integration: add and remove config-bundle', () => {
294282
}
295283

296284
const config = await readProjectConfig(project.projectPath);
297-
expect(config.configBundles).toHaveLength(bundleNames.length);
285+
expect(config.configBundles!).toHaveLength(bundleNames.length);
298286

299287
for (const name of bundleNames) {
300-
expect(config.configBundles.find(b => b.name === name)).toBeDefined();
288+
expect(config.configBundles!.find(b => b.name === name)).toBeDefined();
301289
}
302290
});
303291

304292
it('removing one bundle does not affect others', async () => {
305293
await runSuccess(['remove', 'config-bundle', '--name', 'BundleBeta', '--json'], project.projectPath);
306294

307295
const config = await readProjectConfig(project.projectPath);
308-
expect(config.configBundles).toHaveLength(2);
309-
expect(config.configBundles.find(b => b.name === 'BundleAlpha')).toBeDefined();
310-
expect(config.configBundles.find(b => b.name === 'BundleGamma')).toBeDefined();
311-
expect(config.configBundles.find(b => b.name === 'BundleBeta')).toBeUndefined();
296+
expect(config.configBundles!).toHaveLength(2);
297+
expect(config.configBundles!.find(b => b.name === 'BundleAlpha')).toBeDefined();
298+
expect(config.configBundles!.find(b => b.name === 'BundleGamma')).toBeDefined();
299+
expect(config.configBundles!.find(b => b.name === 'BundleBeta')).toBeUndefined();
312300
});
313301

314302
afterAll(async () => {

integ-tests/add-remove-resources.test.ts

Lines changed: 6 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ describe('integration: add and remove resources', () => {
4141
const found = memories!.some((m: Record<string, unknown>) => m.name === memoryName);
4242
expect(found, `Memory "${memoryName}" should be in config`).toBe(true);
4343

44+
// Verify telemetry
4445
telemetry.assertMetricEmitted({ command: 'add.memory', exit_reason: 'success' });
4546
});
4647

@@ -70,6 +71,7 @@ describe('integration: add and remove resources', () => {
7071
expect(episodic!.reflectionNamespaces, 'Should have reflectionNamespaces').toBeDefined();
7172
expect(episodic!.reflectionNamespaces!.length).toBeGreaterThan(0);
7273

74+
// Verify telemetry
7375
telemetry.assertMetricEmitted({
7476
command: 'add.memory',
7577
exit_reason: 'success',
@@ -82,9 +84,7 @@ describe('integration: add and remove resources', () => {
8284
});
8385

8486
it('removes the memory resource', async () => {
85-
const result = await runCLI(['remove', 'memory', '--name', memoryName, '--json'], project.projectPath, {
86-
env: telemetry.env,
87-
});
87+
const result = await runCLI(['remove', 'memory', '--name', memoryName, '--json'], project.projectPath);
8888

8989
expect(result.exitCode, `stdout: ${result.stdout}, stderr: ${result.stderr}`).toBe(0);
9090
const json = JSON.parse(result.stdout);
@@ -95,8 +95,6 @@ describe('integration: add and remove resources', () => {
9595
const memories = (config.memories as Record<string, unknown>[] | undefined) ?? [];
9696
const found = memories.some((m: Record<string, unknown>) => m.name === memoryName);
9797
expect(found, `Memory "${memoryName}" should be removed from config`).toBe(false);
98-
99-
telemetry.assertMetricEmitted({ command: 'remove.memory', exit_reason: 'success' });
10098
});
10199
});
102100

@@ -121,6 +119,7 @@ describe('integration: add and remove resources', () => {
121119
const found = credentials!.some((c: Record<string, unknown>) => c.name === credentialName);
122120
expect(found, `Credential "${credentialName}" should be in config`).toBe(true);
123121

122+
// Verify telemetry
124123
telemetry.assertMetricEmitted({
125124
command: 'add.credential',
126125
exit_reason: 'success',
@@ -129,9 +128,7 @@ describe('integration: add and remove resources', () => {
129128
});
130129

131130
it('removes the credential resource', async () => {
132-
const result = await runCLI(['remove', 'credential', '--name', credentialName, '--json'], project.projectPath, {
133-
env: telemetry.env,
134-
});
131+
const result = await runCLI(['remove', 'credential', '--name', credentialName, '--json'], project.projectPath);
135132

136133
expect(result.exitCode, `stdout: ${result.stdout}, stderr: ${result.stderr}`).toBe(0);
137134
const json = JSON.parse(result.stdout);
@@ -142,8 +139,6 @@ describe('integration: add and remove resources', () => {
142139
const credentials = (config.credentials as Record<string, unknown>[] | undefined) ?? [];
143140
const found = credentials.some((c: Record<string, unknown>) => c.name === credentialName);
144141
expect(found, `Credential "${credentialName}" should be removed from config`).toBe(false);
145-
146-
telemetry.assertMetricEmitted({ command: 'remove.credential', exit_reason: 'success' });
147142
});
148143
});
149144

@@ -167,46 +162,9 @@ describe('integration: add and remove resources', () => {
167162
});
168163

169164
it('removes the policy engine resource', async () => {
170-
const result = await runCLI(['remove', 'policy-engine', '--name', engineName, '--json'], project.projectPath, {
171-
env: telemetry.env,
172-
});
165+
const result = await runCLI(['remove', 'policy-engine', '--name', engineName, '--json'], project.projectPath);
173166

174167
expect(result.exitCode, `stdout: ${result.stdout}, stderr: ${result.stderr}`).toBe(0);
175-
176-
telemetry.assertMetricEmitted({ command: 'remove.policy-engine', exit_reason: 'success' });
177-
});
178-
});
179-
180-
describe('remove failure telemetry', () => {
181-
it('emits failure telemetry for non-existent memory', async () => {
182-
const result = await runCLI(['remove', 'memory', '--name', 'DoesNotExist', '--json'], project.projectPath, {
183-
env: telemetry.env,
184-
});
185-
186-
expect(result.exitCode).toBe(1);
187-
telemetry.assertMetricEmitted({ command: 'remove.memory', exit_reason: 'failure' });
188-
});
189-
190-
it('emits failure telemetry for non-existent credential', async () => {
191-
const result = await runCLI(['remove', 'credential', '--name', 'DoesNotExist', '--json'], project.projectPath, {
192-
env: telemetry.env,
193-
});
194-
195-
expect(result.exitCode).toBe(1);
196-
telemetry.assertMetricEmitted({ command: 'remove.credential', exit_reason: 'failure' });
197-
});
198-
});
199-
200-
describe('remove all', () => {
201-
it('resets all schemas and emits telemetry', async () => {
202-
const result = await runCLI(['remove', 'all', '--yes', '--json'], project.projectPath, {
203-
env: telemetry.env,
204-
});
205-
206-
expect(result.exitCode).toBe(0);
207-
const json = JSON.parse(result.stdout);
208-
expect(json.success).toBe(true);
209-
telemetry.assertMetricEmitted({ command: 'remove.all', exit_reason: 'success' });
210168
});
211169
});
212170
});

0 commit comments

Comments
 (0)