create-qpq-app 0.1.17 → 0.1.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +3 -3
- package/template/apps/qpqjs/packages/constants/src/QpqjsServiceEnum.ts +2 -0
- package/template/apps/qpqjs/packages/constants/src/index.ts +1 -0
- package/template/apps/qpqjs/packages/constants/src/smokeProbe.ts +13 -0
- package/template/apps/qpqjs/services/test/config/package.json +22 -0
- package/template/apps/qpqjs/services/test/config/src/index.ts +2 -0
- package/template/apps/qpqjs/services/test/config/tsconfig.json +18 -0
- package/template/apps/qpqjs/services/test/config/tsconfig.lib.json +19 -0
- package/template/apps/qpqjs/services/test/models/package.json +22 -0
- package/template/apps/qpqjs/services/test/models/src/SmokeProbeRecord.ts +8 -0
- package/template/apps/qpqjs/services/test/models/src/SmokeRun.ts +14 -0
- package/template/apps/qpqjs/services/test/models/src/SmokeRunStatus.ts +5 -0
- package/template/apps/qpqjs/services/test/models/src/SmokeRunSummary.ts +8 -0
- package/template/apps/qpqjs/services/test/models/src/SmokeRunWithSummary.ts +7 -0
- package/template/apps/qpqjs/services/test/models/src/SmokeTestResult.ts +15 -0
- package/template/apps/qpqjs/services/test/models/src/SmokeTestStatus.ts +6 -0
- package/template/apps/qpqjs/services/test/models/src/index.ts +7 -0
- package/template/apps/qpqjs/services/test/models/tsconfig.json +18 -0
- package/template/apps/qpqjs/services/test/models/tsconfig.lib.json +19 -0
- package/template/apps/qpqjs/services/test/service/package.json +9 -0
- package/template/apps/qpqjs/services/test/service/src/infrastructure.ts +19 -0
- package/template/apps/qpqjs/services/test/service/src/smoke/config/defineSmoke.ts +102 -0
- package/template/apps/qpqjs/services/test/service/src/smoke/config/index.ts +1 -0
- package/template/apps/qpqjs/services/test/service/src/smoke/constants/SMOKE_RUNS_STORE.ts +2 -0
- package/template/apps/qpqjs/services/test/service/src/smoke/constants/githubOidc.ts +19 -0
- package/template/apps/qpqjs/services/test/service/src/smoke/constants/index.ts +4 -0
- package/template/apps/qpqjs/services/test/service/src/smoke/constants/smokeProbe.ts +14 -0
- package/template/apps/qpqjs/services/test/service/src/smoke/constants/smokeRunQueue.ts +6 -0
- package/template/apps/qpqjs/services/test/service/src/smoke/controller/askGetSmokeRun.ts +27 -0
- package/template/apps/qpqjs/services/test/service/src/smoke/controller/askRunSmokeTests.ts +19 -0
- package/template/apps/qpqjs/services/test/service/src/smoke/controller/index.ts +2 -0
- package/template/apps/qpqjs/services/test/service/src/smoke/data/askGetSmokeRunById.ts +16 -0
- package/template/apps/qpqjs/services/test/service/src/smoke/data/askSaveSmokeRun.ts +9 -0
- package/template/apps/qpqjs/services/test/service/src/smoke/data/index.ts +2 -0
- package/template/apps/qpqjs/services/test/service/src/smoke/index.ts +9 -0
- package/template/apps/qpqjs/services/test/service/src/smoke/logic/github/index.ts +1 -0
- package/template/apps/qpqjs/services/test/service/src/smoke/logic/github/verifyGithubOidcToken.ts +105 -0
- package/template/apps/qpqjs/services/test/service/src/smoke/logic/index.ts +2 -0
- package/template/apps/qpqjs/services/test/service/src/smoke/logic/smokeRun/askExecuteSmokeRun.ts +81 -0
- package/template/apps/qpqjs/services/test/service/src/smoke/logic/smokeRun/askFindSmokeRun.ts +11 -0
- package/template/apps/qpqjs/services/test/service/src/smoke/logic/smokeRun/askStartSmokeRun.ts +62 -0
- package/template/apps/qpqjs/services/test/service/src/smoke/logic/smokeRun/index.ts +4 -0
- package/template/apps/qpqjs/services/test/service/src/smoke/logic/smokeRun/summarizeSmokeRun.ts +25 -0
- package/template/apps/qpqjs/services/test/service/src/smoke/models/GithubOidcClaims.ts +11 -0
- package/template/apps/qpqjs/services/test/service/src/smoke/models/SmokeProbeEventQueueEvent.ts +9 -0
- package/template/apps/qpqjs/services/test/service/src/smoke/models/SmokeRunRequestedQueueEvent.ts +9 -0
- package/template/apps/qpqjs/services/test/service/src/smoke/models/index.ts +3 -0
- package/template/apps/qpqjs/services/test/service/src/smoke/processors/github/getGithubOidcAuthProcessors.ts +67 -0
- package/template/apps/qpqjs/services/test/service/src/smoke/processors/github/index.ts +1 -0
- package/template/apps/qpqjs/services/test/service/src/smoke/processors/index.ts +1 -0
- package/template/apps/qpqjs/services/test/service/src/smoke/queue/index.ts +2 -0
- package/template/apps/qpqjs/services/test/service/src/smoke/queue/onSmokeProbeEvent.ts +27 -0
- package/template/apps/qpqjs/services/test/service/src/smoke/queue/onSmokeRunRequested.ts +15 -0
- package/template/apps/qpqjs/services/test/service/src/smoke/tests/SmokeTestDefinition.ts +8 -0
- package/template/apps/qpqjs/services/test/service/src/smoke/tests/askSmokeAssert.ts +12 -0
- package/template/apps/qpqjs/services/test/service/src/smoke/tests/crossService/askRunCrossServiceKeyValueStoreTest.ts +47 -0
- package/template/apps/qpqjs/services/test/service/src/smoke/tests/crossService/askRunCrossServiceStorageDriveTest.ts +46 -0
- package/template/apps/qpqjs/services/test/service/src/smoke/tests/crossService/index.ts +2 -0
- package/template/apps/qpqjs/services/test/service/src/smoke/tests/eventBus/askRunEventBusTest.ts +57 -0
- package/template/apps/qpqjs/services/test/service/src/smoke/tests/eventBus/index.ts +1 -0
- package/template/apps/qpqjs/services/test/service/src/smoke/tests/index.ts +10 -0
- package/template/apps/qpqjs/services/test/service/src/smoke/tests/keyValueStore/askRunKeyValueStoreTest.ts +71 -0
- package/template/apps/qpqjs/services/test/service/src/smoke/tests/keyValueStore/index.ts +1 -0
- package/template/apps/qpqjs/services/test/service/src/smoke/tests/noop/askRunNoopTest.ts +7 -0
- package/template/apps/qpqjs/services/test/service/src/smoke/tests/noop/index.ts +1 -0
- package/template/apps/qpqjs/services/test/service/src/smoke/tests/parameter/askRunParameterTest.ts +27 -0
- package/template/apps/qpqjs/services/test/service/src/smoke/tests/parameter/index.ts +1 -0
- package/template/apps/qpqjs/services/test/service/src/smoke/tests/secret/askRunSecretTest.ts +16 -0
- package/template/apps/qpqjs/services/test/service/src/smoke/tests/secret/index.ts +1 -0
- package/template/apps/qpqjs/services/test/service/src/smoke/tests/smokeTestRegistry.ts +29 -0
- package/template/apps/qpqjs/services/test/service/src/smoke/tests/storageDrive/askRunStorageDriveTest.ts +46 -0
- package/template/apps/qpqjs/services/test/service/src/smoke/tests/storageDrive/index.ts +1 -0
- package/template/apps/qpqjs/services/test/service/tsconfig.app.json +17 -0
- package/template/apps/qpqjs/services/test/service/tsconfig.json +8 -0
- package/template/apps/qpqjs/services/test/service-utils/package.json +22 -0
- package/template/apps/qpqjs/services/test/service-utils/src/index.ts +2 -0
- package/template/apps/qpqjs/services/test/service-utils/tsconfig.json +18 -0
- package/template/apps/qpqjs/services/test/service-utils/tsconfig.lib.json +19 -0
- package/template/apps/qpqjs/services/test/shared-logic/package.json +22 -0
- package/template/apps/qpqjs/services/test/shared-logic/src/index.ts +2 -0
- package/template/apps/qpqjs/services/test/shared-logic/tsconfig.json +18 -0
- package/template/apps/qpqjs/services/test/shared-logic/tsconfig.lib.json +19 -0
- package/template/apps/qpqjs/services/test/x-logic/package.json +22 -0
- package/template/apps/qpqjs/services/test/x-logic/src/index.ts +2 -0
- package/template/apps/qpqjs/services/test/x-logic/tsconfig.json +18 -0
- package/template/apps/qpqjs/services/test/x-logic/tsconfig.lib.json +19 -0
- package/template/apps/qpqjs/services/test/x-models/package.json +22 -0
- package/template/apps/qpqjs/services/test/x-models/src/index.ts +2 -0
- package/template/apps/qpqjs/services/test/x-models/tsconfig.json +18 -0
- package/template/apps/qpqjs/services/test/x-models/tsconfig.lib.json +19 -0
- package/template/apps/qpqjs/services/testa/config/package.json +22 -0
- package/template/apps/qpqjs/services/testa/config/src/index.ts +2 -0
- package/template/apps/qpqjs/services/testa/config/tsconfig.json +18 -0
- package/template/apps/qpqjs/services/testa/config/tsconfig.lib.json +19 -0
- package/template/apps/qpqjs/services/testa/models/package.json +22 -0
- package/template/apps/qpqjs/services/testa/models/src/CrossServiceKeyValueStoreProbeResult.ts +5 -0
- package/template/apps/qpqjs/services/testa/models/src/CrossServiceProbePayload.ts +4 -0
- package/template/apps/qpqjs/services/testa/models/src/CrossServiceStorageDriveProbeResult.ts +6 -0
- package/template/apps/qpqjs/services/testa/models/src/index.ts +3 -0
- package/template/apps/qpqjs/services/testa/models/tsconfig.json +18 -0
- package/template/apps/qpqjs/services/testa/models/tsconfig.lib.json +19 -0
- package/template/apps/qpqjs/services/testa/service/package.json +9 -0
- package/template/apps/qpqjs/services/testa/service/src/crossServiceProbe/config/defineCrossServiceProbe.ts +52 -0
- package/template/apps/qpqjs/services/testa/service/src/crossServiceProbe/config/index.ts +1 -0
- package/template/apps/qpqjs/services/testa/service/src/crossServiceProbe/entry/index.ts +1 -0
- package/template/apps/qpqjs/services/testa/service/src/crossServiceProbe/entry/serviceFunction/index.ts +2 -0
- package/template/apps/qpqjs/services/testa/service/src/crossServiceProbe/entry/serviceFunction/smokeCrossServiceKeyValueStoreProbe.ts +16 -0
- package/template/apps/qpqjs/services/testa/service/src/crossServiceProbe/entry/serviceFunction/smokeCrossServiceStorageDriveProbe.ts +16 -0
- package/template/apps/qpqjs/services/testa/service/src/crossServiceProbe/index.ts +3 -0
- package/template/apps/qpqjs/services/testa/service/src/crossServiceProbe/logic/askProbeForeignKeyValueStore.ts +39 -0
- package/template/apps/qpqjs/services/testa/service/src/crossServiceProbe/logic/askProbeForeignStorageDrive.ts +30 -0
- package/template/apps/qpqjs/services/testa/service/src/crossServiceProbe/logic/index.ts +2 -0
- package/template/apps/qpqjs/services/testa/service/src/infrastructure.ts +22 -0
- package/template/apps/qpqjs/services/testa/service/tsconfig.app.json +17 -0
- package/template/apps/qpqjs/services/testa/service/tsconfig.json +8 -0
- package/template/apps/qpqjs/services/testa/service-utils/package.json +22 -0
- package/template/apps/qpqjs/services/testa/service-utils/src/index.ts +2 -0
- package/template/apps/qpqjs/services/testa/service-utils/tsconfig.json +18 -0
- package/template/apps/qpqjs/services/testa/service-utils/tsconfig.lib.json +19 -0
- package/template/apps/qpqjs/services/testa/shared-logic/package.json +22 -0
- package/template/apps/qpqjs/services/testa/shared-logic/src/index.ts +2 -0
- package/template/apps/qpqjs/services/testa/shared-logic/tsconfig.json +18 -0
- package/template/apps/qpqjs/services/testa/shared-logic/tsconfig.lib.json +19 -0
- package/template/apps/qpqjs/services/testa/x-logic/package.json +22 -0
- package/template/apps/qpqjs/services/testa/x-logic/src/index.ts +2 -0
- package/template/apps/qpqjs/services/testa/x-logic/tsconfig.json +18 -0
- package/template/apps/qpqjs/services/testa/x-logic/tsconfig.lib.json +19 -0
- package/template/apps/qpqjs/services/testa/x-models/package.json +22 -0
- package/template/apps/qpqjs/services/testa/x-models/src/index.ts +2 -0
- package/template/apps/qpqjs/services/testa/x-models/tsconfig.json +18 -0
- package/template/apps/qpqjs/services/testa/x-models/tsconfig.lib.json +19 -0
- package/template/docusaurus/docs/actions/webserver/route-auth-validation/ask-route-auth-validation-decode.md +21 -10
- package/template/scripts/deployedSmoke.mjs +134 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-qpq-app",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.18",
|
|
4
4
|
"description": "Scaffold a new quidproquo app: npx create-qpq-app my-app",
|
|
5
5
|
"main": "./lib/commonjs/index.js",
|
|
6
6
|
"module": "./lib/esm/index.js",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"build:esm": "tsc -p tsconfig.esm.json",
|
|
27
27
|
"build:bin-perms": "node -e \"require('fs').chmodSync('lib/commonjs/bin/createQpqApp.js', 0o755)\"",
|
|
28
28
|
"snapshot-template": "node ./scripts/snapshotTemplate.mjs",
|
|
29
|
-
"
|
|
29
|
+
"scaffold-test": "node ./scripts/scaffoldTest.mjs",
|
|
30
30
|
"prepack": "npm run snapshot-template",
|
|
31
31
|
"lint": "npx eslint .",
|
|
32
32
|
"lint:fix": "npx eslint . --fix",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
},
|
|
56
56
|
"devDependencies": {
|
|
57
57
|
"@types/node": "^22.13.13",
|
|
58
|
-
"quidproquo-tsconfig": "0.1.
|
|
58
|
+
"quidproquo-tsconfig": "0.1.18"
|
|
59
59
|
},
|
|
60
60
|
"bin": {
|
|
61
61
|
"create-qpq-app": "./lib/commonjs/bin/createQpqApp.js"
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// Smoke probe resources owned by the test service and reached cross-service
|
|
2
|
+
// by testa (which declares them with owner: { module: test }). App-level
|
|
3
|
+
// because both services must agree on the names.
|
|
4
|
+
export const SMOKE_PROBE_STORE = 'smokeProbe';
|
|
5
|
+
// Lowercase with a hyphen: this becomes an S3 bucket name, which must be lowercase.
|
|
6
|
+
export const SMOKE_PROBE_DRIVE = 'smoke-probe';
|
|
7
|
+
|
|
8
|
+
// The testa service functions the cross-service smoke tests invoke, one per
|
|
9
|
+
// foreign grant (the store and the drive are separate IAM statements).
|
|
10
|
+
export const SMOKE_CROSS_SERVICE_KEY_VALUE_STORE_PROBE_FUNCTION_NAME =
|
|
11
|
+
'crossKvsProbe';
|
|
12
|
+
export const SMOKE_CROSS_SERVICE_STORAGE_DRIVE_PROBE_FUNCTION_NAME =
|
|
13
|
+
'crossDriveProbe';
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@qpqjs/test-config",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"dependencies": {
|
|
5
|
+
"tslib": "^2.3.0"
|
|
6
|
+
},
|
|
7
|
+
"type": "commonjs",
|
|
8
|
+
"main": "./dist/src/index.js",
|
|
9
|
+
"typings": "./dist/src/index.d.ts",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"types": "./dist/src/index.d.ts",
|
|
13
|
+
"default": "./dist/src/index.js"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist"
|
|
18
|
+
],
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "tsc -b"
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "../../../../../tsconfig.base.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"module": "commonjs",
|
|
5
|
+
"forceConsistentCasingInFileNames": true,
|
|
6
|
+
"strict": true,
|
|
7
|
+
"noImplicitOverride": true,
|
|
8
|
+
"noImplicitReturns": true,
|
|
9
|
+
"noFallthroughCasesInSwitch": true
|
|
10
|
+
},
|
|
11
|
+
"files": [],
|
|
12
|
+
"include": [],
|
|
13
|
+
"references": [
|
|
14
|
+
{
|
|
15
|
+
"path": "./tsconfig.lib.json"
|
|
16
|
+
}
|
|
17
|
+
]
|
|
18
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "./tsconfig.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"outDir": "./dist",
|
|
5
|
+
"declaration": true,
|
|
6
|
+
"types": [
|
|
7
|
+
"node"
|
|
8
|
+
],
|
|
9
|
+
"rootDir": ".",
|
|
10
|
+
"composite": true
|
|
11
|
+
},
|
|
12
|
+
"include": [
|
|
13
|
+
"src/**/*.ts"
|
|
14
|
+
],
|
|
15
|
+
"exclude": [
|
|
16
|
+
"jest.config.ts",
|
|
17
|
+
"src/**/*.spec.ts"
|
|
18
|
+
]
|
|
19
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@qpqjs/test-models",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"dependencies": {
|
|
5
|
+
"tslib": "^2.3.0"
|
|
6
|
+
},
|
|
7
|
+
"type": "commonjs",
|
|
8
|
+
"main": "./dist/src/index.js",
|
|
9
|
+
"typings": "./dist/src/index.d.ts",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"types": "./dist/src/index.d.ts",
|
|
13
|
+
"default": "./dist/src/index.js"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist"
|
|
18
|
+
],
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "tsc -b"
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
// A row in the smokeProbe store. `category` is the store's GSI partition key,
|
|
2
|
+
// so querying by it proves index access under the tag-conditioned grant.
|
|
3
|
+
// External: testa writes these rows cross-service.
|
|
4
|
+
export type SmokeProbeRecord = {
|
|
5
|
+
probeId: string;
|
|
6
|
+
category: string;
|
|
7
|
+
value: number;
|
|
8
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Nullable } from 'quidproquo';
|
|
2
|
+
|
|
3
|
+
import { SmokeRunStatus } from './SmokeRunStatus';
|
|
4
|
+
import { SmokeTestResult } from './SmokeTestResult';
|
|
5
|
+
|
|
6
|
+
// One smoke run: POST /smoke/run creates it, GET /smoke/run/{runId} polls it.
|
|
7
|
+
// The shape is the part-2 contract; part 3 only grows what `tests` contains.
|
|
8
|
+
export type SmokeRun = {
|
|
9
|
+
runId: string;
|
|
10
|
+
status: SmokeRunStatus;
|
|
11
|
+
startedAt: string;
|
|
12
|
+
finishedAt: Nullable<string>;
|
|
13
|
+
tests: SmokeTestResult[];
|
|
14
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Nullable } from 'quidproquo';
|
|
2
|
+
|
|
3
|
+
import { SmokeTestStatus } from './SmokeTestStatus';
|
|
4
|
+
|
|
5
|
+
// One registered test's entry in a run. `name` is the stable key; `id` is the
|
|
6
|
+
// test's 1-based position in the registry, for humans, and shifts if the
|
|
7
|
+
// registry is reordered, so nothing should key on it.
|
|
8
|
+
export type SmokeTestResult = {
|
|
9
|
+
id: number;
|
|
10
|
+
name: string;
|
|
11
|
+
status: SmokeTestStatus;
|
|
12
|
+
message: string;
|
|
13
|
+
startedAt: Nullable<string>;
|
|
14
|
+
finishedAt: Nullable<string>;
|
|
15
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "../../../../../tsconfig.base.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"module": "commonjs",
|
|
5
|
+
"forceConsistentCasingInFileNames": true,
|
|
6
|
+
"strict": true,
|
|
7
|
+
"noImplicitOverride": true,
|
|
8
|
+
"noImplicitReturns": true,
|
|
9
|
+
"noFallthroughCasesInSwitch": true
|
|
10
|
+
},
|
|
11
|
+
"files": [],
|
|
12
|
+
"include": [],
|
|
13
|
+
"references": [
|
|
14
|
+
{
|
|
15
|
+
"path": "./tsconfig.lib.json"
|
|
16
|
+
}
|
|
17
|
+
]
|
|
18
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "./tsconfig.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"outDir": "./dist",
|
|
5
|
+
"declaration": true,
|
|
6
|
+
"types": [
|
|
7
|
+
"node"
|
|
8
|
+
],
|
|
9
|
+
"rootDir": ".",
|
|
10
|
+
"composite": true
|
|
11
|
+
},
|
|
12
|
+
"include": [
|
|
13
|
+
"src/**/*.ts"
|
|
14
|
+
],
|
|
15
|
+
"exclude": [
|
|
16
|
+
"jest.config.ts",
|
|
17
|
+
"src/**/*.spec.ts"
|
|
18
|
+
]
|
|
19
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { defineDevServerOptions } from 'quidproquo-dev-server/config';
|
|
2
|
+
|
|
3
|
+
import { QpqjsServiceEnum } from '@qpqjs/constants';
|
|
4
|
+
import { defineQpqjsService } from '@qpqjs/service-utils';
|
|
5
|
+
|
|
6
|
+
import { defineSmoke } from './smoke/config/defineSmoke';
|
|
7
|
+
|
|
8
|
+
export default [
|
|
9
|
+
defineDevServerOptions({ port: 3083 }),
|
|
10
|
+
|
|
11
|
+
// never change the app name, it will result in a new stack!
|
|
12
|
+
defineQpqjsService(
|
|
13
|
+
QpqjsServiceEnum.Test,
|
|
14
|
+
__dirname,
|
|
15
|
+
'../../../../../../dist/apps/qpqjs/services/test/service'
|
|
16
|
+
),
|
|
17
|
+
|
|
18
|
+
defineSmoke(),
|
|
19
|
+
];
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import {
|
|
2
|
+
defineEventBus,
|
|
3
|
+
defineKeyValueStore,
|
|
4
|
+
defineParameter,
|
|
5
|
+
defineQueue,
|
|
6
|
+
defineRoute,
|
|
7
|
+
defineSecret,
|
|
8
|
+
defineStorageDrive,
|
|
9
|
+
QPQConfig,
|
|
10
|
+
QpqFunctionRuntime,
|
|
11
|
+
} from 'quidproquo';
|
|
12
|
+
|
|
13
|
+
import { SMOKE_PROBE_DRIVE, SMOKE_PROBE_STORE } from '@qpqjs/constants';
|
|
14
|
+
import { SmokeProbeRecord } from '@qpqjs/test-models';
|
|
15
|
+
|
|
16
|
+
import { SMOKE_RUNS_STORE } from '../constants/SMOKE_RUNS_STORE';
|
|
17
|
+
import {
|
|
18
|
+
SMOKE_PROBE_EVENT_BUS,
|
|
19
|
+
SMOKE_PROBE_EVENT_QUEUE,
|
|
20
|
+
SMOKE_PROBE_EVENT_TYPE,
|
|
21
|
+
SMOKE_PROBE_PARAMETER,
|
|
22
|
+
SMOKE_PROBE_PARAMETER_VALUE,
|
|
23
|
+
SMOKE_PROBE_SECRET,
|
|
24
|
+
} from '../constants/smokeProbe';
|
|
25
|
+
import {
|
|
26
|
+
SMOKE_RUN_QUEUE,
|
|
27
|
+
SMOKE_RUN_REQUESTED_MESSAGE_TYPE,
|
|
28
|
+
} from '../constants/smokeRunQueue';
|
|
29
|
+
|
|
30
|
+
// Everything the smoke feature needs: the run store, the queue runs execute
|
|
31
|
+
// on, and the two routes. Runtimes are located relative to this file, so the
|
|
32
|
+
// module can move as a unit.
|
|
33
|
+
//
|
|
34
|
+
// The routes look public (no user directory, no api keys) but carry a
|
|
35
|
+
// per-runtime action processor override that swaps the route auth decode for
|
|
36
|
+
// the GitHub OIDC validator - so ONLY a GitHub Actions run of our repo,
|
|
37
|
+
// holding an OIDC token with the qpq-smoke audience and matching pinned
|
|
38
|
+
// claims, gets past the preamble. Everything else 401s, tokenless included.
|
|
39
|
+
export const defineSmoke = (): QPQConfig => {
|
|
40
|
+
const githubOidcAuth: QpqFunctionRuntime[] = [
|
|
41
|
+
{
|
|
42
|
+
basePath: __dirname,
|
|
43
|
+
relativePath: '../processors/github/getGithubOidcAuthProcessors',
|
|
44
|
+
functionName: 'getGithubOidcAuthProcessors',
|
|
45
|
+
},
|
|
46
|
+
];
|
|
47
|
+
|
|
48
|
+
return [
|
|
49
|
+
// One record per run, keyed by runId; the queue entry updates it as tests
|
|
50
|
+
// complete and the GET route polls it.
|
|
51
|
+
defineKeyValueStore(SMOKE_RUNS_STORE, 'runId'),
|
|
52
|
+
|
|
53
|
+
defineQueue(SMOKE_RUN_QUEUE, {
|
|
54
|
+
[SMOKE_RUN_REQUESTED_MESSAGE_TYPE]: {
|
|
55
|
+
basePath: __dirname,
|
|
56
|
+
relativePath: '../queue/onSmokeRunRequested',
|
|
57
|
+
functionName: 'onSmokeRunRequested',
|
|
58
|
+
},
|
|
59
|
+
}),
|
|
60
|
+
|
|
61
|
+
// Throwaway probe resources, one per kind of owned resource the tag-based
|
|
62
|
+
// IAM grants cover. The store's `category` index is what the KVS test
|
|
63
|
+
// queries through, proving the `table/*/index/*` half of the grant.
|
|
64
|
+
defineKeyValueStore<SmokeProbeRecord>(SMOKE_PROBE_STORE, 'probeId', [], {
|
|
65
|
+
indexes: ['category'],
|
|
66
|
+
}),
|
|
67
|
+
defineParameter(SMOKE_PROBE_PARAMETER, {
|
|
68
|
+
value: SMOKE_PROBE_PARAMETER_VALUE,
|
|
69
|
+
}),
|
|
70
|
+
defineSecret(SMOKE_PROBE_SECRET),
|
|
71
|
+
defineStorageDrive(SMOKE_PROBE_DRIVE),
|
|
72
|
+
|
|
73
|
+
// Event bus test path: publish to the bus, the subscribed queue's entry
|
|
74
|
+
// writes a marker into the probe store, the test polls for it.
|
|
75
|
+
defineEventBus(SMOKE_PROBE_EVENT_BUS),
|
|
76
|
+
defineQueue(
|
|
77
|
+
SMOKE_PROBE_EVENT_QUEUE,
|
|
78
|
+
{
|
|
79
|
+
[SMOKE_PROBE_EVENT_TYPE]: {
|
|
80
|
+
basePath: __dirname,
|
|
81
|
+
relativePath: '../queue/onSmokeProbeEvent',
|
|
82
|
+
functionName: 'onSmokeProbeEvent',
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
{ eventBusSubscriptions: [SMOKE_PROBE_EVENT_BUS] }
|
|
86
|
+
),
|
|
87
|
+
|
|
88
|
+
defineRoute('POST', '/smoke/run', {
|
|
89
|
+
basePath: __dirname,
|
|
90
|
+
relativePath: '../controller/askRunSmokeTests',
|
|
91
|
+
functionName: 'askRunSmokeTests',
|
|
92
|
+
actionProcessors: githubOidcAuth,
|
|
93
|
+
}),
|
|
94
|
+
|
|
95
|
+
defineRoute('GET', '/smoke/run/{runId}', {
|
|
96
|
+
basePath: __dirname,
|
|
97
|
+
relativePath: '../controller/askGetSmokeRun',
|
|
98
|
+
functionName: 'askGetSmokeRun',
|
|
99
|
+
actionProcessors: githubOidcAuth,
|
|
100
|
+
}),
|
|
101
|
+
];
|
|
102
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './defineSmoke';
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// The pinned claims for GitHub Actions OIDC tokens accepted by the smoke
|
|
2
|
+
// endpoint. All public, none secret.
|
|
3
|
+
|
|
4
|
+
// The only issuer GitHub Actions OIDC tokens can come from.
|
|
5
|
+
export const GITHUB_OIDC_ISSUER = 'https://token.actions.githubusercontent.com';
|
|
6
|
+
|
|
7
|
+
// Where GitHub publishes the signing keys for its Actions OIDC tokens.
|
|
8
|
+
export const GITHUB_OIDC_JWKS_URL =
|
|
9
|
+
'https://token.actions.githubusercontent.com/.well-known/jwks';
|
|
10
|
+
|
|
11
|
+
// Dedicated audience the deployed-smoke workflow job requests its token with.
|
|
12
|
+
// Tokens minted for any other purpose (e.g. the AWS deploy role) carry a
|
|
13
|
+
// different audience and are rejected.
|
|
14
|
+
export const GITHUB_OIDC_AUDIENCE = 'qpq-smoke';
|
|
15
|
+
|
|
16
|
+
// The immutable GitHub id of qpqjs/quidproquo, fetched once with
|
|
17
|
+
// `gh api repos/qpqjs/quidproquo --jq .id`. Pinned instead of the repo NAME
|
|
18
|
+
// because names can be reassigned; ids cannot.
|
|
19
|
+
export const GITHUB_REPOSITORY_ID = '571382961';
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// Throwaway resources the smoke tests exercise, one per kind of owned
|
|
2
|
+
// resource the service role is granted by tag / name convention (see the
|
|
3
|
+
// tag-based IAM grants in quidproquo-deploy-awscdk). Nothing else uses them.
|
|
4
|
+
// The store and drive names live in @qpqjs/constants because testa reaches
|
|
5
|
+
// them cross-service.
|
|
6
|
+
export const SMOKE_PROBE_PARAMETER = 'smokeProbe';
|
|
7
|
+
export const SMOKE_PROBE_PARAMETER_VALUE = 'smoke-probe-parameter';
|
|
8
|
+
export const SMOKE_PROBE_SECRET = 'smokeProbe';
|
|
9
|
+
export const SMOKE_PROBE_EVENT_BUS = 'smokeProbe';
|
|
10
|
+
|
|
11
|
+
// The queue subscribed to the probe event bus, and the message type that
|
|
12
|
+
// flows bus -> queue -> store marker for the event bus test.
|
|
13
|
+
export const SMOKE_PROBE_EVENT_QUEUE = 'smokeProbeEvents';
|
|
14
|
+
export const SMOKE_PROBE_EVENT_TYPE = 'smokeProbeEvent';
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// The queue a smoke run is executed from, and the one message type on it.
|
|
2
|
+
// POST /smoke/run creates the run record and sends this message; the queue
|
|
3
|
+
// entry picks it up and runs the registered tests, so the request returns at
|
|
4
|
+
// once and polling shows real progress.
|
|
5
|
+
export const SMOKE_RUN_QUEUE = 'smokeRuns';
|
|
6
|
+
export const SMOKE_RUN_REQUESTED_MESSAGE_TYPE = 'smokeRunRequested';
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AskResponse,
|
|
3
|
+
HTTPEvent,
|
|
4
|
+
HTTPEventResponse,
|
|
5
|
+
qpqWebServerUtils,
|
|
6
|
+
} from 'quidproquo';
|
|
7
|
+
|
|
8
|
+
import { askFindSmokeRun } from '../logic/smokeRun/askFindSmokeRun';
|
|
9
|
+
import { summarizeSmokeRun } from '../logic/smokeRun/summarizeSmokeRun';
|
|
10
|
+
|
|
11
|
+
// GET /smoke/run/{runId}. The deployed-smoke script polls this until the run
|
|
12
|
+
// leaves 'running' or its deadline passes.
|
|
13
|
+
export function* askGetSmokeRun(
|
|
14
|
+
event: HTTPEvent,
|
|
15
|
+
params: { runId: string }
|
|
16
|
+
): AskResponse<HTTPEventResponse> {
|
|
17
|
+
const smokeRun = yield* askFindSmokeRun(params.runId);
|
|
18
|
+
|
|
19
|
+
if (!smokeRun) {
|
|
20
|
+
return qpqWebServerUtils.toJsonEventResponse(
|
|
21
|
+
{ message: `no smoke run [${params.runId}]` },
|
|
22
|
+
404
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return qpqWebServerUtils.toJsonEventResponse(summarizeSmokeRun(smokeRun));
|
|
27
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AskResponse,
|
|
3
|
+
HTTPEvent,
|
|
4
|
+
HTTPEventResponse,
|
|
5
|
+
qpqWebServerUtils,
|
|
6
|
+
} from 'quidproquo';
|
|
7
|
+
|
|
8
|
+
import { askStartSmokeRun } from '../logic/smokeRun/askStartSmokeRun';
|
|
9
|
+
|
|
10
|
+
// POST /smoke/run. Auth happened in the route preamble via the GitHub OIDC
|
|
11
|
+
// decode override attached to this route's runtime. Starts the run on the
|
|
12
|
+
// queue and hands back the runId; status is polled separately.
|
|
13
|
+
export function* askRunSmokeTests(
|
|
14
|
+
event: HTTPEvent
|
|
15
|
+
): AskResponse<HTTPEventResponse> {
|
|
16
|
+
const smokeRun = yield* askStartSmokeRun();
|
|
17
|
+
|
|
18
|
+
return qpqWebServerUtils.toJsonEventResponse({ runId: smokeRun.runId });
|
|
19
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { askKeyValueStoreGet, AskResponse, Nullable } from 'quidproquo';
|
|
2
|
+
|
|
3
|
+
import { SmokeRun } from '@qpqjs/test-models';
|
|
4
|
+
|
|
5
|
+
import { SMOKE_RUNS_STORE } from '../constants/SMOKE_RUNS_STORE';
|
|
6
|
+
|
|
7
|
+
export function* askGetSmokeRunById(
|
|
8
|
+
runId: string
|
|
9
|
+
): AskResponse<Nullable<SmokeRun>> {
|
|
10
|
+
const smokeRun = yield* askKeyValueStoreGet<SmokeRun>(
|
|
11
|
+
SMOKE_RUNS_STORE,
|
|
12
|
+
runId
|
|
13
|
+
);
|
|
14
|
+
|
|
15
|
+
return smokeRun || null;
|
|
16
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { askKeyValueStoreUpsert, AskResponse } from 'quidproquo';
|
|
2
|
+
|
|
3
|
+
import { SmokeRun } from '@qpqjs/test-models';
|
|
4
|
+
|
|
5
|
+
import { SMOKE_RUNS_STORE } from '../constants/SMOKE_RUNS_STORE';
|
|
6
|
+
|
|
7
|
+
export function* askSaveSmokeRun(smokeRun: SmokeRun): AskResponse<void> {
|
|
8
|
+
yield* askKeyValueStoreUpsert<SmokeRun>(SMOKE_RUNS_STORE, smokeRun);
|
|
9
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './verifyGithubOidcToken';
|