in packages/@aws-cdk/integ-runner/lib/cli.ts [101:204]
export async function main(args: string[]) {
const options = parseCliArgs(args);
const testsFromArgs = await new IntegrationTests(path.resolve(options.directory)).fromCliOptions(options);
// List only prints the discovered tests
if (options.list) {
process.stdout.write(testsFromArgs.map(t => t.discoveryRelativeFileName).join('\n') + '\n');
return;
}
const pool = workerpool.pool(path.join(__dirname, '..', 'lib', 'workers', 'extract', 'index.js'), {
maxWorkers: options.watch ? 1 : options.maxWorkers,
});
const testsToRun: IntegTestWorkerConfig[] = [];
let destructiveChanges: boolean = false;
let failedSnapshots: IntegTestWorkerConfig[] = [];
let testsSucceeded = false;
validateWatchArgs({
...options,
testRegions: options.originalRegions,
tests: testsFromArgs,
});
try {
if (!options.watch) {
// always run snapshot tests, but if '--force' is passed then
// run integration tests on all failed tests, not just those that
// failed snapshot tests
failedSnapshots = await runSnapshotTests(pool, testsFromArgs, {
retain: options.inspectFailures,
verbose: options.verbose,
});
for (const failure of failedSnapshots) {
logger.warning(`Failed: ${failure.fileName}`);
if (failure.destructiveChanges && failure.destructiveChanges.length > 0) {
printDestructiveChanges(failure.destructiveChanges);
destructiveChanges = true;
}
}
if (!options.force) {
testsToRun.push(...failedSnapshots);
} else {
// if any of the test failed snapshot tests, keep those results
// and merge with the rest of the tests from args
testsToRun.push(...mergeTests(testsFromArgs.map(t => t.info), failedSnapshots));
}
} else {
testsToRun.push(...testsFromArgs.map(t => t.info));
}
// run integration tests if `--update-on-failed` OR `--force` is used
if (options.runUpdateOnFailed || options.force) {
const { success, metrics } = await runIntegrationTests({
pool,
tests: testsToRun,
regions: options.testRegions,
profiles: options.profiles,
clean: options.clean,
dryRun: options.dryRun,
verbosity: options.verbosity,
updateWorkflow: !options.disableUpdateWorkflow,
watch: options.watch,
});
testsSucceeded = success;
if (options.clean === false) {
logger.warning('Not cleaning up stacks since "--no-clean" was used');
}
if (Boolean(options.verbose)) {
printMetrics(metrics);
}
if (!success) {
throw new Error('Some integration tests failed!');
}
} else if (options.watch) {
await watchIntegrationTest(pool, {
watch: true,
verbosity: options.verbosity,
...testsToRun[0],
profile: options.profiles ? options.profiles[0] : undefined,
region: options.testRegions[0],
});
}
} finally {
void pool.terminate();
}
if (destructiveChanges) {
throw new Error('Some changes were destructive!');
}
if (failedSnapshots.length > 0) {
let message = '';
if (!options.runUpdateOnFailed) {
message = 'To re-run failed tests run: integ-runner --update-on-failed';
}
if (!testsSucceeded) {
throw new Error(`Some tests failed!\n${message}`);
}
}
}