diff --git a/.changeset/wet-tips-swim.md b/.changeset/wet-tips-swim.md new file mode 100644 index 0000000000..a845151cc8 --- /dev/null +++ b/.changeset/wet-tips-swim.md @@ -0,0 +1,2 @@ +--- +--- diff --git a/packages/integration-tests/src/process-controller/process_controller.ts b/packages/integration-tests/src/process-controller/process_controller.ts index f5c71d2603..9248e77511 100644 --- a/packages/integration-tests/src/process-controller/process_controller.ts +++ b/packages/integration-tests/src/process-controller/process_controller.ts @@ -1,4 +1,4 @@ -import { Options, execa } from 'execa'; +import { Options, execa, execaSync } from 'execa'; import readline from 'readline'; import { PredicatedActionBuilder } from './predicated_action_queue_builder.js'; import { ActionType } from './predicated_action.js'; @@ -117,16 +117,18 @@ export const amplifyCli = ( args: string[] = [], dir: string, options?: { - installationType?: 'global' | 'local'; env?: Record; } ): ProcessController => { - let command: string; - if (options?.installationType === 'local') { - command = 'npx'; - args = ['amplify'].concat(args); - } else { - command = 'amplify'; + // TODO This is a workaround to lookup locally installed binary as seen by npx + // We're using binary directly because signals (Ctrl+C) don't propagate + // to child processes without TTY emulator. + // See: https://github.com/aws-amplify/amplify-backend/issues/582 + const command = execaSync('npx', ['which', 'amplify'], { + cwd: dir, + }).stdout.trim(); + if (!command) { + throw new Error('Unable to locate amplify binary'); } return new ProcessController(command, args, { cwd: dir, diff --git a/packages/integration-tests/src/test-live-dependency-health-checks/health_checks.test.ts b/packages/integration-tests/src/test-live-dependency-health-checks/health_checks.test.ts index 480d621a30..b734b398b7 100644 --- a/packages/integration-tests/src/test-live-dependency-health-checks/health_checks.test.ts +++ b/packages/integration-tests/src/test-live-dependency-health-checks/health_checks.test.ts @@ -11,6 +11,12 @@ import { CloudFormationClient, DeleteStackCommand, } from '@aws-sdk/client-cloudformation'; +import { + confirmDeleteSandbox, + interruptSandbox, + rejectCleanupSandbox, + waitForSandboxDeploymentToPrintTotalTime, +} from '../process-controller/predicated_action_macros.js'; const cfnClient = new CloudFormationClient(); @@ -21,10 +27,7 @@ const cfnClient = new CloudFormationClient(); * * These tests intentionally do not use local npm registry (verdaccio). */ -void describe('Live dependency health checks', () => { - let tempDir: string; - let testBranch: TestBranch; - +void describe('Live dependency health checks', { concurrency: true }, () => { before(async () => { // nuke the npx cache to ensure we are installing latest versions of packages from the npm const { stdout } = await execa('npm', ['config', 'get', 'cache']); @@ -35,50 +38,86 @@ void describe('Live dependency health checks', () => { } }); - beforeEach(async () => { - tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'test-amplify')); - testBranch = await amplifyAppPool.createTestBranch(); - }); + void describe('pipeline deployment', () => { + let tempDir: string; + let testBranch: TestBranch; + beforeEach(async () => { + tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'test-amplify')); + testBranch = await amplifyAppPool.createTestBranch(); + }); + + afterEach(async () => { + await fs.rm(tempDir, { recursive: true }); + const stackName = `amplify-${testBranch.appId}-${testBranch.branchName}`; + try { + await cfnClient.send( + new DeleteStackCommand({ + StackName: stackName, + }) + ); + } catch (e) { + console.log(`Failed to delete ${stackName}`); + console.log(e); + } + }); + + void it('end to end flow', async () => { + await execa('npm', ['create', 'amplify', '--yes'], { + cwd: tempDir, + stdio: 'inherit', + }); + + await amplifyCli( + [ + 'pipeline-deploy', + '--branch', + testBranch.branchName, + '--appId', + testBranch.appId, + ], + tempDir, + { + env: { CI: 'true' }, + } + ).run(); - afterEach(async () => { - await fs.rm(tempDir, { recursive: true }); - const stackName = `amplify-${testBranch.appId}-${testBranch.branchName}`; - try { - await cfnClient.send( - new DeleteStackCommand({ - StackName: stackName, - }) + const clientConfigStats = await fs.stat( + path.join(tempDir, 'amplifyconfiguration.json') ); - } catch (e) { - console.log(`Failed to delete ${stackName}`); - console.log(e); - } + assert.ok(clientConfigStats.isFile()); + }); }); - void it('end to end flow with pipeline deployment', async () => { - await execa('npm', ['create', 'amplify', '--yes'], { - cwd: tempDir, - stdio: 'inherit', + void describe('sandbox deployment', () => { + let tempDir: string; + beforeEach(async () => { + tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'test-amplify')); }); - await amplifyCli( - [ - 'pipeline-deploy', - '--branch', - testBranch.branchName, - '--appId', - testBranch.appId, - ], - tempDir, - { - installationType: 'local', - env: { CI: 'true' }, - } - ).run(); + afterEach(async () => { + await fs.rm(tempDir, { recursive: true }); + }); + + void it('end to end flow', async () => { + await execa('npm', ['create', 'amplify', '--yes'], { + cwd: tempDir, + stdio: 'inherit', + }); - const clientConfigStats = await fs.stat( - path.join(tempDir, 'amplifyconfiguration.json') - ); - assert.ok(clientConfigStats.isFile()); + await amplifyCli(['sandbox'], tempDir) + .do(waitForSandboxDeploymentToPrintTotalTime()) + .do(interruptSandbox()) + .do(rejectCleanupSandbox()) + .run(); + + const clientConfigStats = await fs.stat( + path.join(tempDir, 'amplifyconfiguration.json') + ); + assert.ok(clientConfigStats.isFile()); + + await amplifyCli(['sandbox', 'delete'], tempDir) + .do(confirmDeleteSandbox()) + .run(); + }); }); });