-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Adds agent-hub and runner-hub and run-in-batch cli arg (#169)
* wip: hub agent/runner communicating through the same socket * fix: upload benchmark file when start running * fix: add spec config for the hubs, also changes config * fix: simplify server logic * feat: auth in hub based on jsonwebtoken * feat: add README md * feat: add agents api: add endpoint * feat: add config in the example config * feat: autoregister agent with hub * fix: better messages for agent registration * Revert "wip: one at the time crazyness" This reverts commit 5739bbf8ea734074661d066c2a8291b4acc0d499. * feat: add runInBatch option to run builds in batches in the runner * wip: working state check point * fix: refactor hub runner adds cancel timeout in agent * fix: upload jobs to random folder to avoid collisions * feat: start using the agent as soon as is added to the hub * fix: remove extra abstraction on socket * fix: lint errors
- Loading branch information
Showing
37 changed files
with
1,819 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,174 @@ | ||
# Best Hub | ||
|
||
A best hub represents a remote runner who relies/abstract other best-agents. These are the main benefits of using the agent hub: | ||
|
||
1. Abstract clients (projects using best) from configuring specific remotes: you just need the hub address, an authorization token, and specify the browser name and version to run the tests. | ||
2. Allows to run concurrently multiple benchmarks, improving performance on projects with many measures. | ||
3. Allows to share resources among different projects: Ex: suppose you have project A, B and C. for each one you have a dedicated chrome best agent running (mA, mB, mC). Project X will always run in machine mX. With the hub, these 3 machines can be shared, and jobs from A, B and C can run in the hub. | ||
|
||
## Getting Started | ||
|
||
### Starting the hub | ||
|
||
To start the hub server, simply run in your command line: | ||
|
||
```bash | ||
node bin/best-agent-hub.js | ||
``` | ||
|
||
This command will start the hub server using the following configuration: | ||
|
||
- Running port: `6000`. It can be overridden by setting `env.PORT` to the desired port. | ||
- Tokens secret: `secret`. It's recommended to override it by setting `env.TOKEN_SECRET` to the desired secret used authenticate clients. See [Generating hub access tokens for clients](#generating-hub-access-tokens-for-clients). | ||
|
||
### Configuring hub in startup. | ||
|
||
You can configure a preset of agents when the hub starts by setting `env.CONFIG` to a json string representing the config for the hub. | ||
|
||
The configuration of the hub is an array of hubs agents. Each agent represents a remote best agent like: | ||
|
||
```javascript | ||
const config = { | ||
agents: [ | ||
{ | ||
spec: { | ||
browser: "chrome", // Browser name | ||
version: "76" // Browser version (major) | ||
}, | ||
host: "http://localhost:5000", // Required. Url used to connect to the agent. | ||
options: { path: "/best" }, // Connection | ||
remoteRunner: "@best/runner-headless", // Required. The runner which the agent will use when running the job. | ||
remoteRunnerConfig: {}, // Required (may be an empty object). The Runner config for the remote runner in the agent. | ||
}, | ||
{ | ||
spec: { | ||
browser: "ie", | ||
version: "11" | ||
}, | ||
host: "http://127.0.0.1:5002", | ||
options: { path: "/best" }, | ||
remoteRunner: "@best/runner-webdriver", | ||
remoteRunnerConfig: { | ||
"webdriverOptions": { | ||
"desiredCapabilities": { | ||
"platform": "WINDOWS", | ||
"browserName": "internet explorer", | ||
"version": "11", | ||
"ignoreZoomSetting": true, | ||
"initialBrowserUrl": "about:blank", | ||
"nativeEvents": false, | ||
} | ||
} | ||
}, | ||
} | ||
] | ||
} | ||
|
||
// set env.CONFIG=JSON.stringify(config); | ||
``` | ||
|
||
**Note:** All agents with the same spec, should have the same configuration and hardware characteristics, this must be ensured given that a job to be run with these specs, can run in any of the agents, and they should return same results. | ||
|
||
## How to use the hub your project | ||
|
||
Add a new runner config section on your best.config: | ||
|
||
```javascript | ||
// Replace this token with a generated one for the used TOKEN_SECRET when starting the hub server | ||
const hubAuthenticationToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzY29wZSI6ImNsaWVudCIsImlhdCI6MTU2MTYwNzI1OCwiZXhwIjoxNTY0MTk5MjU4fQ.BER-PIIlsf6NWNBctWrmS1YWB4QkI2aYiNp0BE6aASU'; | ||
|
||
module.exports = { | ||
projectName: 'simple-benchmark-chrome', | ||
benchmarkOnClient: true, | ||
"runnerConfig": [ | ||
{ | ||
"runner": "@best/runner-headless", | ||
"alias": "default" | ||
}, | ||
// Configs to use the hub | ||
{ | ||
"runner": "@best/runner-hub", | ||
"alias": "hub-chrome", | ||
"config": { | ||
"host": "http://localhost:6000", | ||
"options": { | ||
path: "/hub", | ||
query: { | ||
token: hubAuthenticationToken | ||
} | ||
}, | ||
"spec": { | ||
"browser": "chrome", | ||
"version": "76" | ||
} | ||
} | ||
}, | ||
{ | ||
"runner": "@best/runner-hub", | ||
"alias": "hub-ie11", | ||
"config": { | ||
"host": "http://localhost:6000", | ||
"options": { | ||
path: "/hub", | ||
query: { | ||
token: hubAuthenticationToken | ||
} | ||
}, | ||
"spec": { | ||
"browser": "ie", | ||
"version": "11" | ||
} | ||
} | ||
}, | ||
], | ||
}; | ||
``` | ||
|
||
Then you can run your measures in your project: | ||
|
||
```bash | ||
# Measures in chrome: | ||
best --runner hub-chrome | ||
|
||
# Measures in ie11: | ||
best --runner hub-ie11 | ||
``` | ||
|
||
### Generating hub access tokens for clients | ||
|
||
The hub authentication is based on [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519) standard using (https://github.com/auth0/node-jsonwebtoken) | ||
|
||
Once you start your hub using a TOKEN_SECRET (for example: password) you will need to generate a token for the client connecting the hub. You can do that using the `generate-client-token` tool included with the `@best/agent-hub` | ||
|
||
To display the help on the tool run: | ||
```bash | ||
node bin/generate-client-token --help | ||
``` | ||
|
||
Example using the tool: (generate a client token for the hub using `password` as secret, the token will expire in 45 days) | ||
|
||
```bash | ||
node bin/generate-client-token.js -s password -c --ttl "45 days" | ||
``` | ||
|
||
### Adding agents to the hub once started | ||
|
||
Once the hub has already started you can add agents by doing a post request to `/api/v1/agents`. Example: | ||
|
||
```bash | ||
curl -X POST \ | ||
http://localhost:6000/api/v1/agents \ | ||
-H 'authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzY29wZSI6ImFnZW50IiwiaWF0IjoxNTYxNjE0MjM3LCJleHAiOjE1NzcxNjYyMzd9.IjdCBSPPIGSgpYHN8Pxhusaiv48T1t6rmxR2xzdp17M' \ | ||
-H 'cache-control: no-cache' \ | ||
-H 'content-type: application/json' \ | ||
-d '{ | ||
"host":"http://localhost:5000", | ||
"options":{"path":"/best"}, | ||
"remoteRunner":"@best/runner-headless", | ||
"remoteRunnerConfig":{}, | ||
"spec": { | ||
"browser": "chrome", | ||
"version": "76" | ||
} | ||
}' | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
#!/usr/bin/env node | ||
|
||
if (process.env.NODE_ENV == null) { | ||
process.env.NODE_ENV = 'perf'; | ||
} | ||
|
||
require('../build/cli').run(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
#!/usr/bin/env node | ||
|
||
const argv = require('yargs') | ||
.usage('Usage: $0 <command> [options]') | ||
.command('gen-token', 'Generates hub access tokens') | ||
.example('$0 gen -s hubSecret -c', 'Generates a key for a client') | ||
.alias('s', 'secret') | ||
.alias('c', 'client') | ||
.alias('a', 'agent') | ||
.alias('t', 'ttl') | ||
.nargs('s', 1) | ||
.describe('s', 'Hub secret') | ||
.describe('c', 'If this key is meant to be used by a client accessing the hub. Is exclusive with option "a". Defaults true') | ||
.describe('a', 'If this key is meant to be used by an agent accessing the hub') | ||
.describe('t', 'Time to live for the token in zeit/ms (check https://github.com/zeit/ms). For clients default is 30 days, for agents 180 days.') | ||
.demandOption(['s']) | ||
.boolean('c').default('c', true) | ||
.boolean('a').default('a', false) | ||
.string('t') | ||
.help('h') | ||
.alias('h', 'help') | ||
.epilog('copyright 2019') | ||
.argv; | ||
|
||
const payload = { | ||
scope: 'client' | ||
}; | ||
let ttl = argv.ttl || '30 days'; | ||
|
||
if (argv.agent) { | ||
payload.scope = 'agent'; | ||
ttl = argv.ttl || '180 days'; | ||
} | ||
|
||
// nothing to do for client since has the defaults. | ||
|
||
const jwt = require('jsonwebtoken'); | ||
|
||
const token = jwt.sign( | ||
payload, | ||
argv.secret, | ||
{ expiresIn: ttl } | ||
); | ||
|
||
console.log(token); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
{ | ||
"name": "@best/agent-hub", | ||
"version": "4.0.0", | ||
"description": "Best Agent Hub", | ||
"keywords": [ | ||
"Best", | ||
"performance", | ||
"Hub" | ||
], | ||
"main": "build/cli/index.js", | ||
"dependencies": { | ||
"@best/runner-remote": "4.0.0", | ||
"@best/utils": "4.0.0", | ||
"jsonwebtoken": "^8.5.1", | ||
"@types/jsonwebtoken": "^8.3.2", | ||
"express": "~4.16.2", | ||
"socket.io": "~2.2.0", | ||
"socket.io-file": "~2.0.31", | ||
"yargs": "^13.2.4" | ||
} | ||
} |
Oops, something went wrong.