Skip to content

Commit ab66222

Browse files
authored
Merge pull request #618 from phani-srikar/cb
Split E2E tests into batches
2 parents 8fb4331 + f79745d commit ab66222

14 files changed

+636
-24
lines changed

.circleci/config.base.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,7 @@ jobs:
303303
yarn clean-e2e-resources
304304
no_output_timeout: 20m
305305
- store_artifacts:
306-
path: ~/repo/packages/amplify-e2e-tests/amplify-e2e-reports
306+
path: ~/repo/packages/amplify-codegen-e2e-tests/amplify-e2e-reports
307307
working_directory: ~/repo
308308

309309
verify-api-extract:

.circleci/config.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,7 @@ jobs:
306306
yarn clean-e2e-resources
307307
no_output_timeout: 20m
308308
- store_artifacts:
309-
path: ~/repo/packages/amplify-e2e-tests/amplify-e2e-reports
309+
path: ~/repo/packages/amplify-codegen-e2e-tests/amplify-e2e-reports
310310
verify-api-extract:
311311
docker: *ref_4
312312
working_directory: ~/repo

.codebuild/cleanup_workflow.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,4 @@ phases:
99
build:
1010
commands:
1111
- yarn production-build
12-
- cd packages/amplify-e2e-tests && yarn clean-cb-e2e-resources
12+
- cd packages/amplify-codegen-e2e-tests && yarn clean-cb-e2e-resources

.codebuild/e2e_workflow.yml

Lines changed: 83 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1+
# auto generated file. DO NOT EDIT manually
12
version: 0.2
23
env:
34
shell: bash
45
compute-type: BUILD_GENERAL1_MEDIUM
5-
66
batch:
77
fast-fail: false
88
build-graph:
@@ -28,3 +28,85 @@ batch:
2828
compute-type: BUILD_GENERAL1_MEDIUM
2929
depend-on:
3030
- build_linux
31+
- identifier: >-
32+
add_codegen_ios_configure_codegen_android_configure_codegen_js_graphql_codegen_android
33+
buildspec: .codebuild/run_e2e_tests.yml
34+
env:
35+
compute-type: BUILD_GENERAL1_MEDIUM
36+
variables:
37+
TEST_SUITE: >-
38+
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
39+
CLI_REGION: us-east-1
40+
depend-on:
41+
- publish_to_local_registry
42+
- identifier: >-
43+
graphql_codegen_js_remove_codegen_android_remove_codegen_ios_add_codegen_android
44+
buildspec: .codebuild/run_e2e_tests.yml
45+
env:
46+
compute-type: BUILD_GENERAL1_MEDIUM
47+
variables:
48+
TEST_SUITE: >-
49+
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
50+
CLI_REGION: us-east-2
51+
depend-on:
52+
- publish_to_local_registry
53+
- identifier: >-
54+
configure_codegen_ios_datastore_modelgen_android_datastore_modelgen_js_feature_flags
55+
buildspec: .codebuild/run_e2e_tests.yml
56+
env:
57+
compute-type: BUILD_GENERAL1_MEDIUM
58+
variables:
59+
TEST_SUITE: >-
60+
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
61+
CLI_REGION: us-west-2
62+
depend-on:
63+
- publish_to_local_registry
64+
- identifier: >-
65+
graphql_codegen_ios_add_codegen_js_datastore_modelgen_ios_remove_codegen_js
66+
buildspec: .codebuild/run_e2e_tests.yml
67+
env:
68+
compute-type: BUILD_GENERAL1_MEDIUM
69+
variables:
70+
TEST_SUITE: >-
71+
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
72+
CLI_REGION: eu-west-2
73+
depend-on:
74+
- publish_to_local_registry
75+
- identifier: >-
76+
datastore_modelgen_flutter_env_codegen_model_introspection_codegen_pull_codegen
77+
buildspec: .codebuild/run_e2e_tests.yml
78+
env:
79+
compute-type: BUILD_GENERAL1_MEDIUM
80+
variables:
81+
TEST_SUITE: >-
82+
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
83+
CLI_REGION: eu-central-1
84+
depend-on:
85+
- publish_to_local_registry
86+
- identifier: >-
87+
push_codegen_ios_push_codegen_android_graphql_documents_generator_push_codegen_js
88+
buildspec: .codebuild/run_e2e_tests.yml
89+
env:
90+
compute-type: BUILD_GENERAL1_MEDIUM
91+
variables:
92+
TEST_SUITE: >-
93+
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
94+
CLI_REGION: ap-northeast-1
95+
depend-on:
96+
- publish_to_local_registry
97+
- identifier: build_app_ts
98+
buildspec: .codebuild/run_e2e_tests.yml
99+
env:
100+
compute-type: BUILD_GENERAL1_MEDIUM
101+
variables:
102+
TEST_SUITE: src/__tests__/build-app-ts.test.ts
103+
CLI_REGION: ap-southeast-1
104+
depend-on:
105+
- publish_to_local_registry
106+
- identifier: cleanup_e2e_resources
107+
buildspec: .codebuild/cleanup_e2e_resources.yml
108+
env:
109+
compute-type: BUILD_GENERAL1_SMALL
110+
depend-on:
111+
- >-
112+
add_codegen_ios_configure_codegen_android_configure_codegen_js_graphql_codegen_android

.codebuild/scripts/artifact-storage-path-allow-list-codebuild.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@
99
*
1010
artifacts:
1111
files:
12-
- $CODEBUILD_SRC_DIR/packages/amplify-e2e-tests/amplify-e2e-reports/*
12+
- $CODEBUILD_SRC_DIR/packages/amplify-codegen-e2e-tests/amplify-e2e-reports/*
1313
*
1414
* From the above job, 'path' includes the following:
15-
* $CODEBUILD_SRC_DIR/packages/amplify-e2e-tests/amplify-e2e-reports
15+
* $CODEBUILD_SRC_DIR/packages/amplify-codegen-e2e-tests/amplify-e2e-reports
1616
*
1717
* Those paths must be included in this list.
1818
*
@@ -27,6 +27,6 @@
2727
* will automatically normalize these paths for Windows if it detects it.
2828
*/
2929
export const ARTIFACT_STORAGE_PATH_ALLOW_LIST_CODEBUILD = [
30-
'$CODEBUILD_SRC_DIR/packages/amplify-e2e-tests/',
31-
'$CODEBUILD_SRC_DIR/packages/amplify-e2e-tests/amplify-e2e-reports'
30+
'$CODEBUILD_SRC_DIR/packages/amplify-codegen-e2e-tests/',
31+
'$CODEBUILD_SRC_DIR/packages/amplify-codegen-e2e-tests/amplify-e2e-reports'
3232
];

.codebuild/scripts/local_publish_helpers.sh

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,9 @@ function unsetSudoNpmRegistryUrl {
4444

4545
function changeNpmGlobalPath {
4646
mkdir -p ~/.npm-global
47-
npm config set prefix '~/.npm-global'
47+
if [ -z $SKIP_SET_NPM_PREFIX ]; then
48+
npm config set prefix '~/.npm-global'
49+
fi
4850
export PATH=~/.npm-global/bin:$PATH
4951
}
5052

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,5 @@ test.out.log
2626
*.tsbuildinfo
2727
package-lock.json
2828
.idea
29-
scripts/.env
29+
scripts/.env
30+
scripts/cci/job.data.json

package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,9 @@
3939
"view-test-artifact": "./scripts/view-test-artifacts.sh",
4040
"cleanup-stale-resources": "source ./scripts/cloud-utils.sh && cleanupStaleResources",
4141
"cloud-e2e-cb": "source scripts/cloud-utils.sh && cloudE2E",
42-
"cloud-e2e-cb-beta": "source scripts/cloud-utils.sh && cloudE2EBeta"
42+
"cloud-e2e-cb-beta": "source scripts/cloud-utils.sh && cloudE2EBeta",
43+
"split-codebuild-e2e-tests": "yarn ts-node ./scripts/split-e2e-tests-codebuild.ts && git add .codebuild/e2e_workflow.yml",
44+
"update-test-timing-data": "ts-node ./scripts/cci/get-test-timing-from-cci-job-metrics.ts"
4345
},
4446
"bugs": {
4547
"url": "https://github.com/aws-amplify/amplify-codegen/issues"
@@ -55,7 +57,7 @@
5557
"hooks": {
5658
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS",
5759
"pre-push": "npm run lint && npm run test-changed",
58-
"pre-commit": "yarn split-e2e-tests && pretty-quick --staged"
60+
"pre-commit": "yarn split-codebuild-e2e-tests"
5961
}
6062
},
6163
"author": "Amazon Web Services",

scripts/cci/api.ts

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
import axios from 'axios';
2+
3+
type ReportingWindow = 'last-7-days' | 'last-90-days' | 'last-24-hours' | 'last-30-days' | 'last-60-days';
4+
export type CircleCIClientDefaults = {
5+
defaultBranch: string;
6+
defaultWorkflow: string;
7+
vcs: string;
8+
projectSlug: string;
9+
projectName: string;
10+
};
11+
export class CircleCIAPIClient {
12+
private headers;
13+
private options: CircleCIClientDefaults;
14+
private slug: string;
15+
constructor(token: string, options: CircleCIClientDefaults) {
16+
this.headers = {
17+
'Circle-Token': token,
18+
};
19+
this.options = options;
20+
this.slug = `${options.vcs}/${options.projectSlug}/${options.projectName}`;
21+
}
22+
23+
/**
24+
* Returns a sequence of jobs for a workflow.
25+
*
26+
* https://circleci.com/docs/api/v2/index.html#operation/listWorkflowJobs
27+
* @returns
28+
*/
29+
getWorkflowJobs = async (workflowId: string = this.options.defaultWorkflow) => {
30+
const result = await axios.get(`https://circleci.com/api/v2/workflow/${workflowId}/job`, {
31+
headers: this.headers,
32+
});
33+
return result.data;
34+
};
35+
/**
36+
* Returns a job's details.
37+
*
38+
* https://circleci.com/docs/api/v2/index.html#operation/getJobDetails
39+
* @param jobId
40+
* @returns
41+
*/
42+
getJobDetails = async (jobId: string) => {
43+
const result = await axios.get(`https://circleci.com/api/v2/project/${this.slug}/job/${jobId}`, {
44+
headers: this.headers,
45+
});
46+
return result.data;
47+
};
48+
/**
49+
* Returns a single job's artifacts.
50+
*
51+
* https://circleci.com/docs/api/v2/index.html#operation/getJobArtifacts
52+
* @param jobId
53+
* @returns
54+
*/
55+
getJobArtifacts = async (jobId: string) => {
56+
const result = await axios.get(`https://circleci.com/api/v2/project/${this.slug}/${jobId}/artifacts`, {
57+
headers: this.headers,
58+
});
59+
return result.data;
60+
};
61+
/**
62+
* Get test metadata for a single job
63+
*
64+
* https://circleci.com/docs/api/v2/index.html#operation/getTests
65+
* @param jobId
66+
* @returns
67+
*/
68+
getJobTests = async (jobId: string) => {
69+
const result = await axios.get(`https://circleci.com/api/v2/project/${this.slug}/${jobId}/tests`, {
70+
headers: this.headers,
71+
});
72+
return result.data;
73+
};
74+
/**
75+
* Get summary metrics for a project workflow's jobs.
76+
*
77+
* https://circleci.com/docs/api/v2/index.html#operation/getProjectWorkflowJobMetrics
78+
*
79+
* @param workflowName
80+
* @param branch
81+
* @param reportingWindow
82+
* @returns
83+
*/
84+
getAllJobMetrics = async (
85+
workflowName: string = this.options.defaultWorkflow,
86+
branch: string = this.options.defaultBranch,
87+
reportingWindow: ReportingWindow = 'last-30-days',
88+
) => {
89+
const result = await axios.get(`https://circleci.com/api/v2/insights/${this.slug}/workflows/${workflowName}/jobs`, {
90+
headers: this.headers,
91+
params: {
92+
branch: branch,
93+
'reporting-window': reportingWindow,
94+
},
95+
});
96+
return result.data;
97+
};
98+
99+
/**
100+
* Get test metrics for a project's workflows.
101+
*
102+
* https://circleci.com/docs/api/v2/index.html#operation/getProjectWorkflowTestMetrics
103+
* @param workflowName
104+
* @param branch
105+
* @param reportingWindow
106+
* @returns
107+
*/
108+
getAllTestMetrics = async (workflowName: string = this.options.defaultWorkflow, branch: string = this.options.defaultBranch) => {
109+
const result = await axios.get(`https://circleci.com/api/v2/insights/${this.slug}/workflows/${workflowName}/test-metrics`, {
110+
headers: this.headers,
111+
params: {
112+
branch: branch,
113+
},
114+
});
115+
return result.data;
116+
};
117+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { join } from 'path';
2+
import { REPO_ROOT, getCCIClient, getTestFiles, getTestNameFromPath, getTimingsFromJobsData, saveJobMetrics, saveTestTimings } from './utils';
3+
4+
async function main(): Promise<void> {
5+
const client = getCCIClient();
6+
console.log('Fetching job metrics...');
7+
const data = await client.getAllJobMetrics();
8+
saveJobMetrics(data);
9+
10+
const testSuites = getTestFiles(join(REPO_ROOT, 'packages', 'amplify-codegen-e2e-tests'));
11+
12+
const jobTimings = getTimingsFromJobsData();
13+
const testRuntimes = testSuites.map(t => {
14+
const oldName = getTestNameFromPath(t);
15+
if (jobTimings.has(oldName)) {
16+
return {
17+
test: t,
18+
medianRuntime: jobTimings.get(oldName) as number,
19+
};
20+
} else {
21+
console.log('Could not find timing for:', t);
22+
return {
23+
test: t,
24+
medianRuntime: 10, // default for unknown
25+
};
26+
}
27+
});
28+
testRuntimes.sort((a, b) => {
29+
return a.medianRuntime - b.medianRuntime;
30+
});
31+
saveTestTimings({
32+
lastUpdated: new Date().toISOString(),
33+
totalTestFiles: testRuntimes.length,
34+
timingData: testRuntimes,
35+
});
36+
}
37+
main();

0 commit comments

Comments
 (0)