Skip to content

Commit 4401d1d

Browse files
authoredNov 16, 2022
feat: add basic browser support (#26)
- use shims + browser field to support - add registerTestcaseResult to communicate end of test with a node runner when running in-browser - Expose getEnvParameters to let a client gather and move testground variables (used for browser support). - Supersede #25, having applies all the previous feedback.
1 parent 6a9f213 commit 4401d1d

14 files changed

+286
-27
lines changed
 

‎package-lock.json

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎package.json

+7-1
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,11 @@
5151
"engines": {
5252
"node": ">=14.0.0"
5353
},
54+
"browser": {
55+
"os": "./src/shims/os.js",
56+
"./src/env/env": "./src/shims/env/env.js",
57+
"./src/runtime/logger": "./src/shims/runtime/logger.js"
58+
},
5459
"aegir": {
5560
"test": {
5661
"target": [
@@ -66,6 +71,7 @@
6671
},
6772
"contributors": [
6873
"Henrique Dias <hacdias@gmail.com>",
69-
"Laurent Senta <Laurent.Senta@gmail.com>"
74+
"Laurent Senta <Laurent.Senta@gmail.com>",
75+
"Glen De Cauwsemaecker <glen@littlebearlabs.io>"
7076
]
7177
}

‎src/env/env.js

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
'use strict'
2+
3+
/**
4+
* Gets the environment that can be used by the environment
5+
* to create the runtime.
6+
*
7+
* @returns {Record<string, string|undefined>}
8+
*/
9+
function getProcessEnv () {
10+
return process.env
11+
}
12+
13+
/**
14+
* @param {unknown} _result
15+
*/
16+
function registerTestcaseResult (_result) {
17+
// function is used in the browser shim
18+
// to gain the ability to wait until invokeMap is finished
19+
}
20+
21+
module.exports = {
22+
getProcessEnv,
23+
registerTestcaseResult
24+
}

‎src/env/index.js

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
'use strict'
2+
3+
const runtime = require('./runtime')
4+
const sync = require('./sync')
5+
const { getProcessEnv } = require('./env')
6+
7+
const ENV_TEST_PARAMETERS = [
8+
runtime.ENV_TEST_BRANCH,
9+
runtime.ENV_TEST_CASE,
10+
runtime.ENV_TEST_GROUP_ID,
11+
runtime.ENV_TEST_GROUP_INSTANCE_COUNT,
12+
runtime.ENV_TEST_INSTANCE_COUNT,
13+
runtime.ENV_TEST_INSTANCE_PARAMS,
14+
runtime.ENV_TEST_INSTANCE_ROLE,
15+
runtime.ENV_TEST_OUTPUTS_PATH,
16+
runtime.ENV_TEST_PLAN,
17+
runtime.ENV_TEST_REPO,
18+
runtime.ENV_TEST_RUN,
19+
runtime.ENV_TEST_SIDECAR,
20+
runtime.ENV_TEST_START_TIME,
21+
runtime.ENV_TEST_SUBNET,
22+
runtime.ENV_TEST_TAG,
23+
24+
sync.ENV_SYNC_SERVICE_HOST,
25+
sync.ENV_SYNC_SERVICE_PORT
26+
]
27+
28+
/**
29+
* Gets the parameters from the environment
30+
* that can be used by the environment to create the runtime.
31+
*
32+
* @returns {Record<string, string|undefined>}
33+
*/
34+
function getEnvParameters () {
35+
const env = getProcessEnv()
36+
return Object.keys(env)
37+
.filter(key => ENV_TEST_PARAMETERS.includes(key))
38+
.reduce((/** @type {Record<string, string|undefined>} */params, key) => {
39+
params[key] = env[key]
40+
return params
41+
}, {})
42+
}
43+
44+
module.exports = {
45+
getEnvParameters
46+
}

‎src/env/runtime.js

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
'use strict'
2+
3+
const ENV_TEST_BRANCH = 'TEST_BRANCH'
4+
const ENV_TEST_CASE = 'TEST_CASE'
5+
const ENV_TEST_GROUP_ID = 'TEST_GROUP_ID'
6+
const ENV_TEST_GROUP_INSTANCE_COUNT = 'TEST_GROUP_INSTANCE_COUNT'
7+
const ENV_TEST_INSTANCE_COUNT = 'TEST_INSTANCE_COUNT'
8+
const ENV_TEST_INSTANCE_PARAMS = 'TEST_INSTANCE_PARAMS'
9+
const ENV_TEST_INSTANCE_ROLE = 'TEST_INSTANCE_ROLE'
10+
const ENV_TEST_OUTPUTS_PATH = 'TEST_OUTPUTS_PATH'
11+
const ENV_TEST_PLAN = 'TEST_PLAN'
12+
const ENV_TEST_REPO = 'TEST_REPO'
13+
const ENV_TEST_RUN = 'TEST_RUN'
14+
const ENV_TEST_SIDECAR = 'TEST_SIDECAR'
15+
const ENV_TEST_START_TIME = 'TEST_START_TIME'
16+
const ENV_TEST_SUBNET = 'TEST_SUBNET'
17+
const ENV_TEST_TAG = 'TEST_TAG'
18+
19+
module.exports = {
20+
ENV_TEST_BRANCH,
21+
ENV_TEST_CASE,
22+
ENV_TEST_GROUP_ID,
23+
ENV_TEST_GROUP_INSTANCE_COUNT,
24+
ENV_TEST_INSTANCE_COUNT,
25+
ENV_TEST_INSTANCE_PARAMS,
26+
ENV_TEST_INSTANCE_ROLE,
27+
ENV_TEST_OUTPUTS_PATH,
28+
ENV_TEST_PLAN,
29+
ENV_TEST_REPO,
30+
ENV_TEST_RUN,
31+
ENV_TEST_SIDECAR,
32+
ENV_TEST_START_TIME,
33+
ENV_TEST_SUBNET,
34+
ENV_TEST_TAG
35+
}

‎src/env/sync.js

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
'use strict'
2+
3+
const ENV_SYNC_SERVICE_HOST = 'SYNC_SERVICE_HOST'
4+
const ENV_SYNC_SERVICE_PORT = 'SYNC_SERVICE_PORT'
5+
6+
module.exports = {
7+
ENV_SYNC_SERVICE_HOST,
8+
ENV_SYNC_SERVICE_PORT
9+
}

‎src/index.js

+25-2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
const runtime = require('./runtime')
44
const sync = require('./sync')
55
const network = require('./network')
6+
const env = require('./env')
7+
8+
const { registerTestcaseResult } = require('./env/env')
69

710
/** @typedef {import('./runtime').RunEnv} RunEnv */
811
/** @typedef {import('./sync').SyncClient} SyncClient */
@@ -17,12 +20,28 @@ async function invokeMap (cases) {
1720
const runenv = runtime.currentRunEnv()
1821

1922
if (cases[runenv.testCase]) {
20-
await invokeHelper(runenv, cases[runenv.testCase])
23+
try {
24+
await invokeHelper(runenv, cases[runenv.testCase])
25+
} catch (err) {
26+
registerAndMessageTestcaseResult(err, runenv)
27+
throw err
28+
}
2129
} else {
22-
throw new Error(`unrecognized test case: ${runenv.testCase}`)
30+
const err = new Error(`unrecognized test case: ${runenv.testCase}`)
31+
registerAndMessageTestcaseResult(err, runenv)
32+
throw err
2333
}
2434
}
2535

36+
/**
37+
* @param {unknown} result
38+
* @param {RunEnv} runenv
39+
*/
40+
function registerAndMessageTestcaseResult (result, runenv) {
41+
runenv.recordMessage(`registerTestcaseResult: ${result}`)
42+
registerTestcaseResult(result)
43+
}
44+
2645
/**
2746
* Runs the passed test-case and reports the result.
2847
*
@@ -47,22 +66,26 @@ async function invokeHelper (runenv, fn) {
4766

4867
await runenv.recordStart()
4968

69+
let /** @type {unknown} */ testResult = true
5070
try {
5171
await fn(runenv, client)
5272
await runenv.recordSuccess()
5373
} catch (err) {
5474
await runenv.recordFailure(err)
75+
testResult = err
5576
} finally {
5677
if (client) {
5778
client.close()
5879
}
80+
registerAndMessageTestcaseResult(testResult, runenv)
5981
}
6082
}
6183

6284
module.exports = {
6385
invoke,
6486
invokeMap,
6587

88+
env,
6689
network,
6790
runtime,
6891
sync

‎src/runtime/events.js

+4
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ function newEvents (runParams, logger, getSignalEmitter) {
4747

4848
logger.info('', { event })
4949
return emitEvent(event)
50+
// eslint-disable-next-line no-warning-comments
5051
// TODO(metrics): re.metrics.recordEvent(&evt)
5152
},
5253
recordSuccess: () => {
@@ -58,6 +59,7 @@ function newEvents (runParams, logger, getSignalEmitter) {
5859

5960
logger.info('', { event })
6061
return emitEvent(event)
62+
// eslint-disable-next-line no-warning-comments
6163
// TODO(metrics): re.metrics.recordEvent(&evt)
6264
},
6365
recordFailure: (err) => {
@@ -70,6 +72,7 @@ function newEvents (runParams, logger, getSignalEmitter) {
7072

7173
logger.info('', { event })
7274
return emitEvent(event)
75+
// eslint-disable-next-line no-warning-comments
7376
// TODO(metrics): re.metrics.recordEvent(&evt)
7477
},
7578
recordCrash: (err) => {
@@ -83,6 +86,7 @@ function newEvents (runParams, logger, getSignalEmitter) {
8386

8487
logger.info('', { event })
8588
return emitEvent(event)
89+
// eslint-disable-next-line no-warning-comments
8690
// TODO(metrics): re.metrics.recordEvent(&evt)
8791
}
8892
}

‎src/runtime/index.js

+5-2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
const { getLogger } = require('./logger')
44
const { newEvents } = require('./events')
55
const { parseRunParams } = require('./params')
6+
const { getEnvParameters } = require('../env')
67

78
/** @typedef {import('./types').RunParams} RunParams */
89
/** @typedef {import('./types').SignalEmitter} SignalEmitter */
@@ -14,7 +15,8 @@ const { parseRunParams } = require('./params')
1415
* @returns {RunEnv}
1516
*/
1617
function currentRunEnv () {
17-
return parseRunEnv(process.env)
18+
const env = getEnvParameters()
19+
return parseRunEnv(env)
1820
}
1921

2022
/**
@@ -52,5 +54,6 @@ function newRunEnv (params) {
5254
module.exports = {
5355
newRunEnv,
5456
currentRunEnv,
55-
parseRunEnv
57+
parseRunEnv,
58+
getEnvParameters
5659
}

‎src/runtime/params.js

+18-16
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,25 @@
22

33
const ipaddr = require('ipaddr.js')
44

5-
/** @typedef {import('./types').RunParams} RunParams */
5+
const {
6+
ENV_TEST_BRANCH,
7+
ENV_TEST_CASE,
8+
ENV_TEST_GROUP_ID,
9+
ENV_TEST_GROUP_INSTANCE_COUNT,
10+
ENV_TEST_INSTANCE_COUNT,
11+
ENV_TEST_INSTANCE_PARAMS,
12+
ENV_TEST_INSTANCE_ROLE,
13+
ENV_TEST_OUTPUTS_PATH,
14+
ENV_TEST_PLAN,
15+
ENV_TEST_REPO,
16+
ENV_TEST_RUN,
17+
ENV_TEST_SIDECAR,
18+
ENV_TEST_START_TIME,
19+
ENV_TEST_SUBNET,
20+
ENV_TEST_TAG
21+
} = require('../env/runtime')
622

7-
const ENV_TEST_BRANCH = 'TEST_BRANCH'
8-
const ENV_TEST_CASE = 'TEST_CASE'
9-
const ENV_TEST_GROUP_ID = 'TEST_GROUP_ID'
10-
const ENV_TEST_GROUP_INSTANCE_COUNT = 'TEST_GROUP_INSTANCE_COUNT'
11-
const ENV_TEST_INSTANCE_COUNT = 'TEST_INSTANCE_COUNT'
12-
const ENV_TEST_INSTANCE_PARAMS = 'TEST_INSTANCE_PARAMS'
13-
const ENV_TEST_INSTANCE_ROLE = 'TEST_INSTANCE_ROLE'
14-
const ENV_TEST_OUTPUTS_PATH = 'TEST_OUTPUTS_PATH'
15-
const ENV_TEST_PLAN = 'TEST_PLAN'
16-
const ENV_TEST_REPO = 'TEST_REPO'
17-
const ENV_TEST_RUN = 'TEST_RUN'
18-
const ENV_TEST_SIDECAR = 'TEST_SIDECAR'
19-
const ENV_TEST_START_TIME = 'TEST_START_TIME'
20-
const ENV_TEST_SUBNET = 'TEST_SUBNET'
21-
const ENV_TEST_TAG = 'TEST_TAG'
23+
/** @typedef {import('./types').RunParams} RunParams */
2224

2325
/**
2426
* @param {Record<string, string|undefined>} env

‎src/shims/env/env.js

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
'use strict'
2+
3+
/**
4+
* Gets the environment that can be used by the environment
5+
* to create the runtime.
6+
*
7+
* @returns {Record<string, string|undefined>}
8+
*/
9+
function getProcessEnv () {
10+
// @ts-ignore
11+
return (window.testground || {}).env
12+
}
13+
/**
14+
* @param {unknown} result
15+
*/
16+
function registerTestcaseResult (result) {
17+
// @ts-ignore
18+
if (!window.testground) {
19+
// @ts-ignore
20+
window.testground = {}
21+
}
22+
// @ts-ignore
23+
window.testground.result = result
24+
}
25+
26+
module.exports = {
27+
getProcessEnv,
28+
registerTestcaseResult
29+
}

‎src/shims/os.js

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
'use strict'
2+
3+
/**
4+
* @returns {any[]}
5+
*/
6+
function networkInterfaces () {
7+
return []
8+
}
9+
10+
/**
11+
* @returns {string}
12+
*/
13+
function hostname () {
14+
return 'browser'
15+
}
16+
17+
module.exports = {
18+
networkInterfaces,
19+
hostname
20+
}

0 commit comments

Comments
 (0)
Please sign in to comment.