Skip to content

Commit c2e88a4

Browse files
chore(codegen): generate and run SSDK protocol tests during CI (#2558)
This sets up a server-only mode for generate-clients, and a set of yarn targets that generate and run server protocol tests. The CodeBuild CI for clients uses Node 10, while SSDKs require Node 14, so this sets up an additional GitHub action for running the SSDK protocol tests and excludes SSDK protocol tests from the client targets. When the client is updated to support 14 as a minimum version, this distinction can be removed.
1 parent dff5cd4 commit c2e88a4

File tree

7 files changed

+142
-6
lines changed

7 files changed

+142
-6
lines changed
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
name: server-protocol-tests
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
pull_request:
7+
branches: [ main ]
8+
9+
jobs:
10+
build:
11+
runs-on: ubuntu-latest
12+
13+
steps:
14+
- uses: actions/checkout@v2
15+
16+
- uses: actions/setup-java@v1
17+
with:
18+
java-version: '11'
19+
20+
- uses: actions/setup-node@v2
21+
with:
22+
node-version: '14'
23+
cache: 'yarn'
24+
25+
- name: build and publish smithy-typescript
26+
run: |
27+
git clone --depth 1 https://github.com/awslabs/smithy-typescript.git
28+
cd smithy-typescript
29+
./gradlew clean build publishToMavenLocal
30+
cd ..
31+
32+
- name: install dependencies
33+
run: |
34+
yarn install
35+
36+
- name: generate protocol tests
37+
run: |
38+
yarn generate-clients --server-artifacts
39+
40+
# there are new dependencies as a result of generating server protocol tests
41+
- name: install dependencies again
42+
run: |
43+
yarn install
44+
45+
- name: run protocol tests
46+
run: |
47+
yarn test:server-protocols
48+
49+

codegen/protocol-test-codegen/smithy-build.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,11 @@
118118
"license": "Apache-2.0"
119119
},
120120
"private": true
121+
},
122+
"typescript-ssdk-codegen": {
123+
"package": "@aws-sdk/aws-restjson-server",
124+
"packageVersion": "1.0.0-alpha.1",
125+
"disableDefaultValidation": true
121126
}
122127
}
123128
},

codegen/smithy-aws-typescript-codegen/src/main/java/software/amazon/smithy/aws/typescript/codegen/AwsProtocolUtils.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,16 @@ private static boolean filterProtocolTests(
293293
if (testCase.getId().equals("QueryCustomizedError")) {
294294
return true;
295295
}
296+
if (testCase.getId().equals("RestJsonStreamingTraitsRequireLengthWithBlob") && settings.generateServerSdk()) {
297+
return true;
298+
}
299+
//TODO: enable with Smithy 1.10
300+
if ((testCase.getId().equals("RestJsonAllQueryStringTypes")
301+
|| testCase.getId().equals("RestJsonQueryStringEscaping"))
302+
&& settings.generateServerSdk()) {
303+
return true;
304+
}
305+
296306
return false;
297307
}
298308
}

package.json

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,17 @@
1313
"clear-build-info": "rimraf ./packages/**/*.tsbuildinfo ./clients/**/*.tsbuildinfo ./lib/**/*.tsbuildinfo",
1414
"remove-documentation": "rimraf ./docs",
1515
"build:crypto-dependencies": "lerna run --scope '@aws-sdk/{types,util-utf8-browser,util-locate-window,hash-node}' --include-dependencies build",
16-
"build:protocols": "yarn build:crypto-dependencies && lerna run --scope '@aws-sdk/aws-*' --include-dependencies build",
16+
"build:protocols": "yarn build:crypto-dependencies && lerna run --scope '@aws-sdk/aws-*' --ignore '@aws-sdk/*-server' --include-dependencies build",
17+
"build:server-protocols": "yarn build:crypto-dependencies && lerna run --scope '@aws-sdk/*-server' --include-dependencies build",
1718
"build:all": "yarn build:crypto-dependencies && lerna run build",
1819
"build-documentation": "yarn remove-documentation && typedoc",
1920
"pretest:all": "yarn build:all",
2021
"test:all": "jest --coverage --passWithNoTests && lerna run test --scope '@aws-sdk/{fetch-http-handler,hash-blob-browser}'",
2122
"test:functional": "jest --config tests/functional/jest.config.js --passWithNoTests",
2223
"test:integration-legacy": "cucumber-js --fail-fast",
2324
"test:integration": "jest --config jest.config.integ.js --passWithNoTests",
24-
"test:protocols": "yarn build:protocols && lerna run test --scope '@aws-sdk/aws-*'",
25+
"test:protocols": "yarn build:protocols && lerna run test --scope '@aws-sdk/aws-*' --ignore '@aws-sdk/*-server'",
26+
"test:server-protocols": "yarn build:server-protocols && lerna run test --scope '@aws-sdk/*-server'",
2527
"pretest:e2e": "yarn build:crypto-dependencies && lerna run --scope '@aws-sdk/{client-cloudformation,karma-credential-loader}' --include-dependencies build",
2628
"test:e2e": "node ./tests/e2e/index.js",
2729
"local-publish": "node ./scripts/verdaccio-publish/index.js"
@@ -118,4 +120,4 @@
118120
],
119121
"**/*.{ts,js,md,json}": "prettier --write"
120122
}
121-
}
123+
}

scripts/generate-clients/code-prettify.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,16 @@
22
const { spawnProcess } = require("../utils/spawn-process");
33
const path = require("path");
44

5-
const prettifyCode = async (dir) =>
6-
spawnProcess(path.join(__dirname, "..", "..", "node_modules", ".bin", "pprettier"), [
5+
const prettifyCode = async (dir) => {
6+
await spawnProcess(path.join(__dirname, "..", "..", "node_modules", ".bin", "pprettier"), [
77
"--write",
88
`${dir}/*/typescript-codegen/**/*.{ts,js,md,json}`,
99
]);
10+
await spawnProcess(path.join(__dirname, "..", "..", "node_modules", ".bin", "pprettier"), [
11+
"--write",
12+
`${dir}/*/typescript-ssdk-codegen/**/*.{ts,js,md,json}`,
13+
]);
14+
};
1015

1116
module.exports = {
1217
prettifyCode,

scripts/generate-clients/copy-to-clients.js

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,53 @@ const copyToClients = async (sourceDir, destinationDir) => {
151151
}
152152
};
153153

154+
const copyServerTests = async (sourceDir, destinationDir) => {
155+
for (const modelName of readdirSync(sourceDir)) {
156+
if (modelName === "source") continue;
157+
158+
const artifactPath = join(sourceDir, modelName, "typescript-ssdk-codegen");
159+
const packageManifestPath = join(artifactPath, "package.json");
160+
if (!existsSync(packageManifestPath)) {
161+
console.error(`${modelName} generates empty server, skip.`);
162+
continue;
163+
}
164+
165+
const packageManifest = JSON.parse(readFileSync(packageManifestPath).toString());
166+
const packageName = packageManifest.name;
167+
const testName = packageName.replace("@aws-sdk/", "");
168+
169+
console.log(`copying ${packageName} from ${artifactPath} to ${destinationDir}`);
170+
const destPath = join(destinationDir, testName);
171+
const overwritablePredicate = getOverwritablePredicate(packageName);
172+
173+
for (const packageSub of readdirSync(artifactPath)) {
174+
const packageSubPath = join(artifactPath, packageSub);
175+
const destSubPath = join(destPath, packageSub);
176+
177+
if (packageSub === "package.json") {
178+
//copy manifest file
179+
const destManifest = existsSync(destSubPath) ? JSON.parse(readFileSync(destSubPath).toString()) : {};
180+
const mergedManifest = {
181+
...mergeManifest(packageManifest, destManifest),
182+
homepage: `https://github.com/aws/aws-sdk-js-v3/tree/main/protocol_tests/${testName}`,
183+
repository: {
184+
type: "git",
185+
url: "https://github.com/aws/aws-sdk-js-v3.git",
186+
directory: `protocol_tests/${testName}`,
187+
},
188+
};
189+
writeFileSync(destSubPath, JSON.stringify(mergedManifest, null, 2).concat(`\n`));
190+
} else if (overwritablePredicate(packageSub) || !existsSync(destSubPath)) {
191+
if (lstatSync(packageSubPath).isDirectory()) removeSync(destSubPath);
192+
copySync(packageSubPath, destSubPath, {
193+
overwrite: true,
194+
});
195+
}
196+
}
197+
}
198+
};
199+
154200
module.exports = {
155201
copyToClients,
202+
copyServerTests,
156203
};

scripts/generate-clients/index.js

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ const yargs = require("yargs");
33
const path = require("path");
44
const { emptyDirSync, rmdirSync } = require("fs-extra");
55
const { generateClients, generateProtocolTests } = require("./code-gen");
6-
const { copyToClients } = require("./copy-to-clients");
6+
const { copyToClients, copyServerTests } = require("./copy-to-clients");
77
const {
88
CODE_GEN_SDK_OUTPUT_DIR,
99
CODE_GEN_PROTOCOL_TESTS_OUTPUT_DIR,
@@ -19,6 +19,7 @@ const {
1919
globs,
2020
output: clientsDir,
2121
noProtocolTest,
22+
s: serverOnly,
2223
} = yargs
2324
.alias("m", "models")
2425
.string("m")
@@ -34,10 +35,27 @@ const {
3435
.alias("n", "noProtocolTest")
3536
.boolean("n")
3637
.describe("n", "Disable generating protocol test files")
38+
.alias("s", "server-artifacts")
39+
.boolean("s")
40+
.describe("s", "Generate server artifacts instead of client ones")
41+
.default("s", false)
42+
.conflicts("s", ["m", "g", "n"])
3743
.help().argv;
3844

3945
(async () => {
4046
try {
47+
if (serverOnly) {
48+
await generateProtocolTests();
49+
await prettifyCode(CODE_GEN_PROTOCOL_TESTS_OUTPUT_DIR);
50+
await copyServerTests(CODE_GEN_PROTOCOL_TESTS_OUTPUT_DIR, PROTOCOL_TESTS_CLIENTS_DIR);
51+
52+
emptyDirSync(CODE_GEN_PROTOCOL_TESTS_OUTPUT_DIR);
53+
emptyDirSync(TEMP_CODE_GEN_INPUT_DIR);
54+
55+
rmdirSync(TEMP_CODE_GEN_INPUT_DIR);
56+
return;
57+
}
58+
4159
await generateClients(models || globs);
4260
if (!noProtocolTest) await generateProtocolTests();
4361

0 commit comments

Comments
 (0)