From 8ec490d721e6b8587c34fa8e312962b9f71ab43e Mon Sep 17 00:00:00 2001 From: Dane Pilcher Date: Tue, 31 Oct 2023 08:18:48 -0600 Subject: [PATCH] ci: e2e tests on windows (#750) --- .codebuild/e2e_workflow.yml | 129 ++++++++++++++++-- .codebuild/run_e2e_tests_windows.yml | 24 ++++ .codebuild/scripts/e2e_test_windows.sh | 8 ++ .codebuild/scripts/local_publish_helpers.sh | 2 +- .codebuild/scripts/post_e2e_test.sh | 8 ++ .../amplify-codegen-e2e-core/package.json | 2 +- .../src/categories/api.ts | 16 +-- .../amplify-codegen-e2e-core/src/index.ts | 13 +- .../amplify-codegen-e2e-core/src/init/cra.ts | 10 +- .../src/utils/getCommandPath.ts | 10 ++ .../src/utils/index.ts | 2 + .../src/utils/isWindows.ts | 5 + .../graphql-documents-generator.test.ts | 8 +- .../src/__tests__/pull-codegen.test.ts | 31 +++-- scripts/split-e2e-tests.ts | 86 ++++++++---- shared-scripts.sh | 33 ++++- yarn.lock | 8 +- 17 files changed, 311 insertions(+), 84 deletions(-) create mode 100644 .codebuild/run_e2e_tests_windows.yml create mode 100755 .codebuild/scripts/e2e_test_windows.sh create mode 100755 .codebuild/scripts/post_e2e_test.sh create mode 100644 packages/amplify-codegen-e2e-core/src/utils/getCommandPath.ts create mode 100644 packages/amplify-codegen-e2e-core/src/utils/isWindows.ts diff --git a/.codebuild/e2e_workflow.yml b/.codebuild/e2e_workflow.yml index 1c420534c..c82adc814 100644 --- a/.codebuild/e2e_workflow.yml +++ b/.codebuild/e2e_workflow.yml @@ -63,7 +63,7 @@ batch: depend-on: - publish_to_local_registry - identifier: >- - add_codegen_ios_configure_codegen_android_configure_codegen_js_graphql_codegen_android + l_add_codegen_ios_configure_codegen_android_configure_codegen_js_graphql_codegen_android buildspec: .codebuild/run_e2e_tests.yml env: compute-type: BUILD_GENERAL1_LARGE @@ -74,7 +74,7 @@ batch: depend-on: - publish_to_local_registry - identifier: >- - graphql_codegen_js_remove_codegen_android_remove_codegen_ios_add_codegen_android + l_graphql_codegen_js_remove_codegen_android_remove_codegen_ios_add_codegen_android buildspec: .codebuild/run_e2e_tests.yml env: compute-type: BUILD_GENERAL1_LARGE @@ -85,7 +85,7 @@ batch: depend-on: - publish_to_local_registry - identifier: >- - configure_codegen_ios_datastore_modelgen_android_datastore_modelgen_js_feature_flags + l_configure_codegen_ios_datastore_modelgen_android_datastore_modelgen_js_feature_flags buildspec: .codebuild/run_e2e_tests.yml env: compute-type: BUILD_GENERAL1_LARGE @@ -96,7 +96,7 @@ batch: depend-on: - publish_to_local_registry - identifier: >- - graphql_codegen_ios_add_codegen_js_datastore_modelgen_ios_remove_codegen_js + l_graphql_codegen_ios_add_codegen_js_datastore_modelgen_ios_remove_codegen_js buildspec: .codebuild/run_e2e_tests.yml env: compute-type: BUILD_GENERAL1_LARGE @@ -107,7 +107,7 @@ batch: depend-on: - publish_to_local_registry - identifier: >- - datastore_modelgen_flutter_env_codegen_model_introspection_codegen_pull_codegen + l_datastore_modelgen_flutter_env_codegen_model_introspection_codegen_pull_codegen buildspec: .codebuild/run_e2e_tests.yml env: compute-type: BUILD_GENERAL1_LARGE @@ -118,7 +118,7 @@ batch: depend-on: - publish_to_local_registry - identifier: >- - push_codegen_ios_push_codegen_android_graphql_documents_generator_push_codegen_js + l_push_codegen_ios_push_codegen_android_graphql_documents_generator_push_codegen_js buildspec: .codebuild/run_e2e_tests.yml env: compute-type: BUILD_GENERAL1_LARGE @@ -129,7 +129,7 @@ batch: depend-on: - publish_to_local_registry - identifier: >- - build_app_ts_uninitialized_project_codegen_js_uninitialized_project_modelgen_android_uninitialized_project_modelgen_flutter + l_build_app_ts_uninitialized_project_codegen_js_uninitialized_project_modelgen_android_uninitialized_project_modelgen_flutter buildspec: .codebuild/run_e2e_tests.yml env: compute-type: BUILD_GENERAL1_LARGE @@ -139,7 +139,7 @@ batch: CLI_REGION: ap-southeast-1 depend-on: - publish_to_local_registry - - identifier: uninitialized_project_modelgen_ios_uninitialized_project_modelgen_js + - identifier: l_uninitialized_project_modelgen_ios_uninitialized_project_modelgen_js buildspec: .codebuild/run_e2e_tests.yml env: compute-type: BUILD_GENERAL1_LARGE @@ -149,10 +149,121 @@ batch: CLI_REGION: ap-southeast-2 depend-on: - publish_to_local_registry + - identifier: >- + w_add_codegen_ios_configure_codegen_android_configure_codegen_js_graphql_codegen_android + buildspec: .codebuild/run_e2e_tests_windows.yml + env: + compute-type: BUILD_GENERAL1_LARGE + image: $WINDOWS_IMAGE_2019 + type: WINDOWS_SERVER_2019_CONTAINER + variables: + TEST_SUITE: >- + src/__tests__/add-codegen-ios.test.ts|src/__tests__/configure-codegen-android.test.ts|src/__tests__/configure-codegen-js.test.ts|src/__tests__/graphql-codegen-android.test.ts + CLI_REGION: us-east-1 + depend-on: + - publish_to_local_registry + - build_windows + - identifier: >- + w_graphql_codegen_js_remove_codegen_android_remove_codegen_ios_add_codegen_android + buildspec: .codebuild/run_e2e_tests_windows.yml + env: + compute-type: BUILD_GENERAL1_LARGE + image: $WINDOWS_IMAGE_2019 + type: WINDOWS_SERVER_2019_CONTAINER + variables: + TEST_SUITE: >- + src/__tests__/graphql-codegen-js.test.ts|src/__tests__/remove-codegen-android.test.ts|src/__tests__/remove-codegen-ios.test.ts|src/__tests__/add-codegen-android.test.ts + CLI_REGION: us-east-1 + depend-on: + - publish_to_local_registry + - build_windows + - identifier: >- + w_configure_codegen_ios_datastore_modelgen_android_datastore_modelgen_js_feature_flags + buildspec: .codebuild/run_e2e_tests_windows.yml + env: + compute-type: BUILD_GENERAL1_LARGE + image: $WINDOWS_IMAGE_2019 + type: WINDOWS_SERVER_2019_CONTAINER + variables: + TEST_SUITE: >- + src/__tests__/configure-codegen-ios.test.ts|src/__tests__/datastore-modelgen-android.test.ts|src/__tests__/datastore-modelgen-js.test.ts|src/__tests__/feature-flags.test.ts + CLI_REGION: us-east-1 + depend-on: + - publish_to_local_registry + - build_windows + - identifier: >- + w_graphql_codegen_ios_add_codegen_js_datastore_modelgen_ios_remove_codegen_js + buildspec: .codebuild/run_e2e_tests_windows.yml + env: + compute-type: BUILD_GENERAL1_LARGE + image: $WINDOWS_IMAGE_2019 + type: WINDOWS_SERVER_2019_CONTAINER + variables: + TEST_SUITE: >- + src/__tests__/graphql-codegen-ios.test.ts|src/__tests__/add-codegen-js.test.ts|src/__tests__/datastore-modelgen-ios.test.ts|src/__tests__/remove-codegen-js.test.ts + CLI_REGION: us-east-1 + depend-on: + - publish_to_local_registry + - build_windows + - identifier: >- + w_datastore_modelgen_flutter_env_codegen_model_introspection_codegen_pull_codegen + buildspec: .codebuild/run_e2e_tests_windows.yml + env: + compute-type: BUILD_GENERAL1_LARGE + image: $WINDOWS_IMAGE_2019 + type: WINDOWS_SERVER_2019_CONTAINER + variables: + TEST_SUITE: >- + src/__tests__/datastore-modelgen-flutter.test.ts|src/__tests__/env-codegen.test.ts|src/__tests__/model-introspection-codegen.test.ts|src/__tests__/pull-codegen.test.ts + CLI_REGION: us-east-1 + depend-on: + - publish_to_local_registry + - build_windows + - identifier: >- + w_push_codegen_ios_push_codegen_android_graphql_documents_generator_push_codegen_js + buildspec: .codebuild/run_e2e_tests_windows.yml + env: + compute-type: BUILD_GENERAL1_LARGE + image: $WINDOWS_IMAGE_2019 + type: WINDOWS_SERVER_2019_CONTAINER + variables: + TEST_SUITE: >- + src/__tests__/push-codegen-ios.test.ts|src/__tests__/push-codegen-android.test.ts|src/__tests__/graphql-documents-generator.test.ts|src/__tests__/push-codegen-js.test.ts + CLI_REGION: us-east-1 + depend-on: + - publish_to_local_registry + - build_windows + - identifier: >- + w_build_app_ts_uninitialized_project_codegen_js_uninitialized_project_modelgen_android_uninitialized_project_modelgen_flutter + buildspec: .codebuild/run_e2e_tests_windows.yml + env: + compute-type: BUILD_GENERAL1_LARGE + image: $WINDOWS_IMAGE_2019 + type: WINDOWS_SERVER_2019_CONTAINER + variables: + TEST_SUITE: >- + src/__tests__/build-app-ts.test.ts|src/__tests__/uninitialized-project-codegen-js.test.ts|src/__tests__/uninitialized-project-modelgen-android.test.ts|src/__tests__/uninitialized-project-modelgen-flutter.test.ts + CLI_REGION: us-east-1 + depend-on: + - publish_to_local_registry + - build_windows + - identifier: w_uninitialized_project_modelgen_ios_uninitialized_project_modelgen_js + buildspec: .codebuild/run_e2e_tests_windows.yml + env: + compute-type: BUILD_GENERAL1_LARGE + image: $WINDOWS_IMAGE_2019 + type: WINDOWS_SERVER_2019_CONTAINER + variables: + TEST_SUITE: >- + src/__tests__/uninitialized-project-modelgen-ios.test.ts|src/__tests__/uninitialized-project-modelgen-js.test.ts + CLI_REGION: us-east-1 + depend-on: + - publish_to_local_registry + - build_windows - identifier: cleanup_e2e_resources buildspec: .codebuild/cleanup_e2e_resources.yml env: compute-type: BUILD_GENERAL1_MEDIUM depend-on: - >- - add_codegen_ios_configure_codegen_android_configure_codegen_js_graphql_codegen_android + l_add_codegen_ios_configure_codegen_android_configure_codegen_js_graphql_codegen_android diff --git a/.codebuild/run_e2e_tests_windows.yml b/.codebuild/run_e2e_tests_windows.yml new file mode 100644 index 000000000..6884bdfa7 --- /dev/null +++ b/.codebuild/run_e2e_tests_windows.yml @@ -0,0 +1,24 @@ +version: 0.2 +env: + shell: powershell.exe + variables: + AMPLIFY_DIR: /root/.npm-global/lib/node_modules/@aws-amplify/cli-internal/bin + AMPLIFY_PATH: /root/.npm-global/lib/node_modules/@aws-amplify/cli-internal/bin/amplify + CI: true + CODEBUILD: true + NODE_OPTIONS: --max-old-space-size=8096 + SKIP_SET_NPM_PREFIX: true +phases: + build: + commands: + # commands need to be run in stand-alone bash scripts so that bash can be used on windows + - bash ./.codebuild/scripts/e2e_test_windows.sh + post_build: + commands: + # commands need to be run in stand-alone bash scripts so that bash can be used on windows + - bash ./.codebuild/scripts/post_e2e_test.sh + +artifacts: + files: + - '**/*' + base-directory: $Env:CODEBUILD_SRC_DIR\packages\amplify-codegen-e2e-tests\amplify-e2e-reports diff --git a/.codebuild/scripts/e2e_test_windows.sh b/.codebuild/scripts/e2e_test_windows.sh new file mode 100755 index 000000000..1cdcee9fb --- /dev/null +++ b/.codebuild/scripts/e2e_test_windows.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +# set exit on error to true +set -e + +source ./shared-scripts.sh && _setupE2ETestsWindows +codebuild-breakpoint +source ./shared-scripts.sh && _runE2ETestsWindows diff --git a/.codebuild/scripts/local_publish_helpers.sh b/.codebuild/scripts/local_publish_helpers.sh index fa45b52a6..15d968e44 100644 --- a/.codebuild/scripts/local_publish_helpers.sh +++ b/.codebuild/scripts/local_publish_helpers.sh @@ -7,7 +7,7 @@ function startLocalRegistry { # Start local registry tmp_registry_log="$(mktemp)" echo "Registry output file: $tmp_registry_log" - (cd && nohup npx ${VERDACCIO_PACKAGE:-$default_verdaccio_package} -c $1 &>$tmp_registry_log &) + nohup npx ${VERDACCIO_PACKAGE:-$default_verdaccio_package} -c $1 &>$tmp_registry_log & # Wait for Verdaccio to boot grep -q 'http address' <(tail -f $tmp_registry_log) } diff --git a/.codebuild/scripts/post_e2e_test.sh b/.codebuild/scripts/post_e2e_test.sh new file mode 100755 index 000000000..a9dd7a490 --- /dev/null +++ b/.codebuild/scripts/post_e2e_test.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +# set exit on error to true +set -e + +source ./shared-scripts.sh && _unassumeTestAccountCredentials +aws sts get-caller-identity +source ./shared-scripts.sh && _scanArtifacts diff --git a/packages/amplify-codegen-e2e-core/package.json b/packages/amplify-codegen-e2e-core/package.json index bdb812969..7a4282849 100644 --- a/packages/amplify-codegen-e2e-core/package.json +++ b/packages/amplify-codegen-e2e-core/package.json @@ -32,7 +32,7 @@ "jest-circus": "^27.5.1", "jest-environment-node": "^26.6.2", "lodash": "^4.17.19", - "node-pty": "beta", + "node-pty": "1.0.0", "retimer": "2.0.0", "rimraf": "^3.0.0", "strip-ansi": "^6.0.0", diff --git a/packages/amplify-codegen-e2e-core/src/categories/api.ts b/packages/amplify-codegen-e2e-core/src/categories/api.ts index bd5c8982b..c2f90ae97 100644 --- a/packages/amplify-codegen-e2e-core/src/categories/api.ts +++ b/packages/amplify-codegen-e2e-core/src/categories/api.ts @@ -49,9 +49,7 @@ export function addApiWithoutSchema(cwd: string, opts: Partial { if (!err) { resolve(); @@ -79,10 +77,8 @@ export function addApiWithBlankSchema(cwd: string, opts: Partial { if (!err) { @@ -112,10 +108,8 @@ export function addApiWithBlankSchemaAndConflictDetection(cwd: string) { .sendKeyDown(2) .sendCarriageReturn() .wait('Do you want to edit the schema now?') - .sendLine('n') - .wait( - '"amplify publish" will build all your local backend and frontend resources (if you have hosting category added) and provision it in the cloud', - ) + .sendConfirmNo() + .wait('"amplify publish" will build all your local backend and frontend resources') .run((err: Error) => { if (!err) { resolve(); diff --git a/packages/amplify-codegen-e2e-core/src/index.ts b/packages/amplify-codegen-e2e-core/src/index.ts index 32159adf8..ab689f25d 100644 --- a/packages/amplify-codegen-e2e-core/src/index.ts +++ b/packages/amplify-codegen-e2e-core/src/index.ts @@ -5,6 +5,7 @@ import { spawnSync, execSync } from 'child_process'; import { v4 as uuid } from 'uuid'; import * as ini from 'ini'; import { pathManager } from '@aws-amplify/amplify-cli-core'; +import { getCommandPath } from './utils'; export * from './configure/'; export * from './init/'; @@ -24,14 +25,16 @@ declare global { const amplifyTestsDir = 'amplify-codegen-e2e-tests'; export function getCLIPath(testingWithLatestCodebase = false) { + let commandName = 'amplify-dev'; if (isCI() && !testingWithLatestCodebase) { - return 'amplify'; + commandName = 'amplify'; } - return 'amplify-dev'; + + return getCommandPath(commandName); } export function isCI(): boolean { - return process.env.CI && (process.env.CODEBUILD) ? true : false; + return process.env.CI && process.env.CODEBUILD ? true : false; } export function injectSessionToken(profileName: string) { @@ -57,7 +60,9 @@ export async function createNewProjectDir( projectName: string, prefix = path.join(fs.realpathSync(os.tmpdir()), amplifyTestsDir), ): Promise { - const currentHash = execSync('git rev-parse --short HEAD', { cwd: __dirname }).toString().trim(); + const currentHash = execSync('git rev-parse --short HEAD', { cwd: __dirname }) + .toString() + .trim(); let projectDir; do { const randomId = await global.getRandomId(); diff --git a/packages/amplify-codegen-e2e-core/src/init/cra.ts b/packages/amplify-codegen-e2e-core/src/init/cra.ts index 0614bf12d..648f01931 100644 --- a/packages/amplify-codegen-e2e-core/src/init/cra.ts +++ b/packages/amplify-codegen-e2e-core/src/init/cra.ts @@ -1,5 +1,5 @@ /* commands for a Create React App */ -import { nspawn as spawn } from '..'; +import { nspawn as spawn, getCommandPath } from '..'; const defaultSettings = { disableCIDetection: false, @@ -8,7 +8,7 @@ const defaultSettings = { export function craInstall(cwd: string, settings: Object = {}): Promise { return new Promise((resolve, reject) => { const s = { ...defaultSettings, ...settings }; - const chain = spawn('npm', ['install'], { cwd, stripColors: true, disableCIDetection: s.disableCIDetection }); + const chain = spawn(getCommandPath('npm'), ['install'], { cwd, stripColors: true, disableCIDetection: s.disableCIDetection }); chain.run((err: Error) => { if (err) { @@ -23,7 +23,7 @@ export function craInstall(cwd: string, settings: Object = {}): Promise { export function craBuild(cwd: string, settings: Object = {}): Promise { return new Promise((resolve, reject) => { const s = { ...defaultSettings, ...settings }; - const chain = spawn('npm', ['run', 'build'], { cwd, stripColors: true, disableCIDetection: s.disableCIDetection }); + const chain = spawn(getCommandPath('npm'), ['run', 'build'], { cwd, stripColors: true, disableCIDetection: s.disableCIDetection }); chain.run((err: Error) => { if (err) { @@ -41,8 +41,8 @@ export function cypressRun(cwd: string, settings: any = {}): Promise { const args = ['cypress', 'run']; if (s?.componentsTesting) { args.push('--component'); - }; - const chain = spawn('npx', args, { cwd, stripColors: true, disableCIDetection: s.disableCIDetection }); + } + const chain = spawn(getCommandPath('npx'), args, { cwd, stripColors: true, disableCIDetection: s.disableCIDetection }); chain.run((err: Error) => { if (err) { diff --git a/packages/amplify-codegen-e2e-core/src/utils/getCommandPath.ts b/packages/amplify-codegen-e2e-core/src/utils/getCommandPath.ts new file mode 100644 index 000000000..c078e7ac6 --- /dev/null +++ b/packages/amplify-codegen-e2e-core/src/utils/getCommandPath.ts @@ -0,0 +1,10 @@ +import { execSync } from 'child_process'; +/* Get the full absolute path of a command with `which` + * + * Windows executors on CB fail to spawn a command with custom nexpect unless the full path is used. + */ +export function getCommandPath(command: string): string { + return execSync(`which ${command}`) + .toString() + .trim(); +} diff --git a/packages/amplify-codegen-e2e-core/src/utils/index.ts b/packages/amplify-codegen-e2e-core/src/utils/index.ts index f2583e257..66a38a53d 100644 --- a/packages/amplify-codegen-e2e-core/src/utils/index.ts +++ b/packages/amplify-codegen-e2e-core/src/utils/index.ts @@ -23,6 +23,8 @@ export * from './transformConfig'; export * from './admin-ui'; export * from './frontend-config-helper'; export * from './graphql-config-helper'; +export * from './getCommandPath'; +export * from './isWindows'; // run dotenv config to update env variable config(); diff --git a/packages/amplify-codegen-e2e-core/src/utils/isWindows.ts b/packages/amplify-codegen-e2e-core/src/utils/isWindows.ts new file mode 100644 index 000000000..2d48cd9fe --- /dev/null +++ b/packages/amplify-codegen-e2e-core/src/utils/isWindows.ts @@ -0,0 +1,5 @@ +import os from 'os'; + +export function isWindows(): boolean { + return os.platform() === 'win32' +} diff --git a/packages/amplify-codegen-e2e-tests/src/__tests__/graphql-documents-generator.test.ts b/packages/amplify-codegen-e2e-tests/src/__tests__/graphql-documents-generator.test.ts index fee96ce66..0f20ace6f 100644 --- a/packages/amplify-codegen-e2e-tests/src/__tests__/graphql-documents-generator.test.ts +++ b/packages/amplify-codegen-e2e-tests/src/__tests__/graphql-documents-generator.test.ts @@ -7,7 +7,8 @@ import { craBuild, amplifyPush, cypressRun, - deleteProject + deleteProject, + isWindows, } from '@aws-amplify/amplify-codegen-e2e-core'; import { readdirSync, rmSync } from 'fs'; import { readFileSync } from 'fs-extra'; @@ -31,9 +32,10 @@ describe('GraphQL documents generator e2e tests', () => { }); const schemaFileName = 'schema.graphql'; - it('generates valid GraphQL documents for given schema', async () => { + // skip cypress test on windows + (isWindows() ? it.skip : it)('generates valid GraphQL documents for given schema', async () => { const schemaPath = path.resolve('test-apps', 'docsgen-react-app', 'public', schemaFileName); - const schemaText = readFileSync(schemaPath, { encoding: 'utf8'}); + const schemaText = readFileSync(schemaPath, { encoding: 'utf8' }); updateApiSchemaWithText(projectRoot, apiName, schemaText); await amplifyPush(projectRoot); diff --git a/packages/amplify-codegen-e2e-tests/src/__tests__/pull-codegen.test.ts b/packages/amplify-codegen-e2e-tests/src/__tests__/pull-codegen.test.ts index 1506d4925..31dc3e88f 100644 --- a/packages/amplify-codegen-e2e-tests/src/__tests__/pull-codegen.test.ts +++ b/packages/amplify-codegen-e2e-tests/src/__tests__/pull-codegen.test.ts @@ -18,6 +18,7 @@ import { amplifyPullSandbox, getProjectSchema, AmplifyFrontend, + isWindows, } from '@aws-amplify/amplify-codegen-e2e-core'; import { existsSync } from 'fs'; import path from 'path'; @@ -71,18 +72,22 @@ describe('Amplify pull in amplify app with codegen tests', () => { }); frontendConfigs.forEach(config => { - it(`should generate models and do not delete user files by amplify pull in an empty folder of ${config.frontendType} app`, async () => { - //generate pre existing user file - const userSourceCodePath = generateSourceCode(emptyProjectRoot, config.srcDir); - // Flutter projects need min dart version to be met for modelgen to succeed. - if (config?.frontendType === AmplifyFrontend.flutter) { - createPubspecLockFile(emptyProjectRoot); - }; - //amplify pull in a new project - await amplifyPull(emptyProjectRoot, { emptyDir: true, appId, frontendConfig: config }); - expect(existsSync(userSourceCodePath)).toBe(true); - expect(isNotEmptyDir(path.join(emptyProjectRoot, config.modelgenDir))).toBe(true); - }); + // skip ios test on windows + (isWindows() && config.frontendType === 'ios' ? it.skip : it)( + `should generate models and do not delete user files by amplify pull in an empty folder of ${config.frontendType} app`, + async () => { + //generate pre existing user file + const userSourceCodePath = generateSourceCode(emptyProjectRoot, config.srcDir); + // Flutter projects need min dart version to be met for modelgen to succeed. + if (config?.frontendType === AmplifyFrontend.flutter) { + createPubspecLockFile(emptyProjectRoot); + } + //amplify pull in a new project + await amplifyPull(emptyProjectRoot, { emptyDir: true, appId, frontendConfig: config }); + expect(existsSync(userSourceCodePath)).toBe(true); + expect(isNotEmptyDir(path.join(emptyProjectRoot, config.modelgenDir))).toBe(true); + }, + ); }); }); }); @@ -119,7 +124,7 @@ describe('Amplify pull in sandbox app with codegen tests', () => { // Flutter projects need min dart version to be met for modelgen to succeed. if (config?.frontendType === AmplifyFrontend.flutter) { createPubspecLockFile(projectRoot); - }; + } //pull sandbox app await amplifyPullSandbox(projectRoot, { appType: config.frontendType, diff --git a/scripts/split-e2e-tests.ts b/scripts/split-e2e-tests.ts index 445ecebdd..567459af2 100644 --- a/scripts/split-e2e-tests.ts +++ b/scripts/split-e2e-tests.ts @@ -71,7 +71,11 @@ type CandidateJob = { runSolo: boolean; }; const createJob = (os: OS_TYPE, jobIdx: number, runSolo: boolean = false): CandidateJob => { - const region = AWS_REGIONS_TO_RUN_TESTS[jobIdx % AWS_REGIONS_TO_RUN_TESTS.length]; + // The bash terminal for Windows on CodeBuild is non-interactive. + // amplify-configure will always choose us-east-1 for the region. + // This will set all Windows jobs to use us-east-1 to avoid region mismatch. + // We will come back to this later to properly fix the testing issue. + const region = os === 'w' ? 'us-east-1' : AWS_REGIONS_TO_RUN_TESTS[jobIdx % AWS_REGIONS_TO_RUN_TESTS.length]; return { region, os, @@ -92,6 +96,7 @@ const getTestNameFromPath = (testSuitePath: string): string => { }; const splitTests = ( baseJobLinux: any, + baseJobWindows: any, testDirectory: string, pickTests?: ((testSuites: string[]) => string[]), ) => { @@ -148,46 +153,71 @@ const splitTests = ( return [...osJobs, ...soloJobs]; }; const linuxJobs = generateJobsForOS('l'); - const getIdentifier = (os: string, names: string) => { - const jobName = `${names.replace(/-/g, '_')}`.substring(0, 127); - return jobName; - }; + const windowsJobs = generateJobsForOS('w'); const result: any[] = []; linuxJobs.forEach((j) => { if (j.tests.length !== 0) { - const names = j.tests.map((tn) => getTestNameFromPath(tn)).join('_'); - const tmp = { - ...JSON.parse(JSON.stringify(baseJobLinux)), // deep clone base job - identifier: getIdentifier(j.os, names), - }; - tmp.env.variables = {}; - tmp.env.variables.TEST_SUITE = j.tests.join('|'); - tmp.env.variables.CLI_REGION = j.region; - if (j.useParentAccount) { - tmp.env.variables.USE_PARENT_ACCOUNT = 1; - } - if (j.runSolo) { - tmp.env['compute-type'] = 'BUILD_GENERAL1_LARGE'; - } - result.push(tmp); + result.push(basicE2EJob(j, baseJobLinux)); + } + }); + windowsJobs.forEach((j) => { + if (j.tests.length !== 0) { + result.push(basicE2EJob(j, baseJobWindows)); } }); + return result; }; +function basicE2EJob(inputJob: any, baseJob: string) { + const names = inputJob.tests.map((tn) => getTestNameFromPath(tn)).join('_'); + const job = { + ...JSON.parse(JSON.stringify(baseJob)), // deep clone base job + identifier: getIdentifier(inputJob.os, names), + }; + job.env.variables = {}; + job.env.variables.TEST_SUITE = inputJob.tests.join('|'); + job.env.variables.CLI_REGION = inputJob.region; + if (inputJob.useParentAccount) { + job.env.variables.USE_PARENT_ACCOUNT = 1; + } + if (inputJob.runSolo) { + job.env['compute-type'] = 'BUILD_GENERAL1_LARGE'; + } + return job; +} + +function getIdentifier(os: string, names: string) { + const jobName = `${os}_${names.replace(/-/g, '_')}`.substring(0, 127); + return jobName; +}; + function main(): void { const filteredTests = process.argv.slice(2); const configBase: any = loadConfigBase(); const baseBuildGraph = configBase.batch['build-graph']; - const splitE2ETests = splitTests( - { - identifier: 'run_e2e_tests', - buildspec: '.codebuild/run_e2e_tests.yml', - env: { - 'compute-type': 'BUILD_GENERAL1_LARGE', - }, - 'depend-on': ['publish_to_local_registry'], + const baseJobLinux = { + identifier: 'run_e2e_tests', + buildspec: '.codebuild/run_e2e_tests.yml', + env: { + 'compute-type': 'BUILD_GENERAL1_LARGE', }, + 'depend-on': ['publish_to_local_registry'], + }; + const baseJobWindows = { + identifier: 'run_e2e_tests', + buildspec: '.codebuild/run_e2e_tests_windows.yml', + env: { + 'compute-type': 'BUILD_GENERAL1_LARGE', + image: '$WINDOWS_IMAGE_2019', + type: 'WINDOWS_SERVER_2019_CONTAINER', + }, + 'depend-on': ['publish_to_local_registry', 'build_windows'], + }; + + const splitE2ETests = splitTests( + baseJobLinux, + baseJobWindows, join(REPO_ROOT, 'packages', 'amplify-codegen-e2e-tests'), (testSuites) => testSuites.filter((ts) => !EXCLUDE_TESTS.includes(ts)), ); diff --git a/shared-scripts.sh b/shared-scripts.sh index 78f7f9eec..f120513d8 100644 --- a/shared-scripts.sh +++ b/shared-scripts.sh @@ -205,9 +205,18 @@ function _publishToLocalRegistry { } function _installCLIFromLocalRegistry { + environment="$1" echo "Start verdaccio, install CLI" source .codebuild/scripts/local_publish_helpers.sh - startLocalRegistry "$(pwd)/.codebuild/scripts/verdaccio.yaml" + + # absolute paths do not work with verdaccio on windows + if [[ $environment == "windows" ]]; then + echo "Starting local registry for Windows" + startLocalRegistry .codebuild/scripts/verdaccio.yaml + else + echo "Starting local registry for Linux" + startLocalRegistry "$(pwd)/.codebuild/scripts/verdaccio.yaml" + fi setNpmRegistryUrlToLocal changeNpmGlobalPath npm install -g @aws-amplify/cli-internal@cdk228withdata3 @@ -235,18 +244,32 @@ function _setupE2ETestsLinux { echo "Setup E2E Tests Linux" loadCacheFromLinuxBuildJob loadCache verdaccio-cache $CODEBUILD_SRC_DIR/../verdaccio-cache - _installCLIFromLocalRegistry + _installCLIFromLocalRegistry + _loadTestAccountCredentials + _setShell +} + +function _setupE2ETestsWindows { + echo "Setup E2E Tests Windows" + loadCacheFromWindowsBuildJob + _installCLIFromLocalRegistry windows _loadTestAccountCredentials _setShell } + function _runE2ETestsLinux { echo "RUN E2E Tests Linux" retry runE2eTest } +function _runE2ETestsWindows { + echo "RUN E2E Tests Windows" + retry runE2eTest +} + function _scanArtifacts { - if ! yarn ts-node .codebuild/scripts/scan_artifacts.ts; then + if ! npx ts-node .codebuild/scripts/scan_artifacts.ts; then echo "Cleaning the repository" git clean -fdx exit 1 @@ -377,9 +400,9 @@ function runE2eTest { if [ -f $FAILED_TEST_REGEX_FILE ]; then # read the content of failed tests failedTests=$(<$FAILED_TEST_REGEX_FILE) - yarn run e2e --maxWorkers=4 $TEST_SUITE -t "$failedTests" + npm run e2e --maxWorkers=4 $TEST_SUITE -t "$failedTests" else - yarn run e2e --maxWorkers=4 $TEST_SUITE + npm run e2e --maxWorkers=4 $TEST_SUITE fi } diff --git a/yarn.lock b/yarn.lock index c88449fe6..d04c42431 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11852,10 +11852,10 @@ node-int64@^0.4.0: resolved "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" integrity sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw== -node-pty@beta: - version "1.1.0-beta5" - resolved "https://registry.npmjs.org/node-pty/-/node-pty-1.1.0-beta5.tgz#364386b7058a93070234064f13164ec1ef914993" - integrity sha512-j3QdgFHnLY0JWxztrvM3g67RaQLOGvytv+C6mFu0PqD+JILlzqfwuoyqRqVxdZZjoOTUXPfSRj1qPVCaCH+eOw== +node-pty@1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/node-pty/-/node-pty-1.0.0.tgz#7daafc0aca1c4ca3de15c61330373af4af5861fd" + integrity sha512-wtBMWWS7dFZm/VgqElrTvtfMq4GzJ6+edFI0Y0zyzygUSZMgZdraDUMUhCIvkjhJjme15qWmbyJbtAx4ot4uZA== dependencies: nan "^2.17.0"