Introduce the concept of suite in authelia-scripts.

This commit is contained in:
Clement Michaud 2019-02-04 23:23:59 +01:00
parent e37cca5d45
commit c5af4498ab
9 changed files with 424 additions and 20 deletions

281
package-lock.json generated
View File

@ -622,6 +622,16 @@
"integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8=",
"dev": true
},
"anymatch": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz",
"integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==",
"dev": true,
"requires": {
"micromatch": "3.1.10",
"normalize-path": "2.1.1"
}
},
"apidoc": {
"version": "0.17.6",
"resolved": "https://registry.npmjs.org/apidoc/-/apidoc-0.17.6.tgz",
@ -702,6 +712,12 @@
"sprintf-js": "1.0.3"
}
},
"arr-diff": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
"integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
"dev": true
},
"arr-flatten": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz",
@ -739,6 +755,12 @@
"resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.2.tgz",
"integrity": "sha1-X8w3OSB3VyPP1k1lxkvvU7+eum0="
},
"array-unique": {
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
"integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
"dev": true
},
"arrify": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
@ -1093,6 +1115,35 @@
"concat-map": "0.0.1"
}
},
"braces": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
"integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
"dev": true,
"requires": {
"arr-flatten": "1.1.0",
"array-unique": "0.3.2",
"extend-shallow": "2.0.1",
"fill-range": "4.0.0",
"isobject": "3.0.1",
"repeat-element": "1.1.2",
"snapdragon": "0.8.2",
"snapdragon-node": "2.1.1",
"split-string": "3.1.0",
"to-regex": "3.0.2"
},
"dependencies": {
"extend-shallow": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
"integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
"dev": true,
"requires": {
"is-extendable": "0.1.1"
}
}
}
},
"browser-stdout": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz",
@ -1232,6 +1283,27 @@
"strip-ansi": "0.1.1"
}
},
"chokidar": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.4.tgz",
"integrity": "sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ==",
"dev": true,
"requires": {
"anymatch": "2.0.0",
"async-each": "1.0.1",
"braces": "2.3.2",
"fsevents": "1.2.4",
"glob-parent": "3.1.0",
"inherits": "2.0.3",
"is-binary-path": "1.0.1",
"is-glob": "4.0.0",
"lodash.debounce": "4.0.8",
"normalize-path": "2.1.1",
"path-is-absolute": "1.0.1",
"readdirp": "2.1.0",
"upath": "1.1.0"
}
},
"chromedriver": {
"version": "2.38.2",
"resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-2.38.2.tgz",
@ -2280,6 +2352,41 @@
"integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=",
"dev": true
},
"expand-brackets": {
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
"integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
"dev": true,
"requires": {
"debug": "2.6.9",
"define-property": "0.2.5",
"extend-shallow": "2.0.1",
"posix-character-classes": "0.1.1",
"regex-not": "1.0.2",
"snapdragon": "0.8.2",
"to-regex": "3.0.2"
},
"dependencies": {
"define-property": {
"version": "0.2.5",
"resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
"integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
"dev": true,
"requires": {
"is-descriptor": "0.1.6"
}
},
"extend-shallow": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
"integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
"dev": true,
"requires": {
"is-extendable": "0.1.1"
}
}
}
},
"expect-ct": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/expect-ct/-/expect-ct-0.1.0.tgz",
@ -2380,6 +2487,77 @@
}
}
},
"extglob": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
"integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==",
"dev": true,
"requires": {
"array-unique": "0.3.2",
"define-property": "1.0.0",
"expand-brackets": "2.1.4",
"extend-shallow": "2.0.1",
"fragment-cache": "0.2.1",
"regex-not": "1.0.2",
"snapdragon": "0.8.2",
"to-regex": "3.0.2"
},
"dependencies": {
"define-property": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
"integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
"dev": true,
"requires": {
"is-descriptor": "1.0.2"
}
},
"extend-shallow": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
"integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
"dev": true,
"requires": {
"is-extendable": "0.1.1"
}
},
"is-accessor-descriptor": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
"integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
"dev": true,
"requires": {
"kind-of": "6.0.2"
}
},
"is-data-descriptor": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
"integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
"dev": true,
"requires": {
"kind-of": "6.0.2"
}
},
"is-descriptor": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
"integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
"dev": true,
"requires": {
"is-accessor-descriptor": "1.0.0",
"is-data-descriptor": "1.0.0",
"kind-of": "6.0.2"
}
},
"kind-of": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
"integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
"dev": true
}
}
},
"extract-zip": {
"version": "1.6.6",
"resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.6.tgz",
@ -2464,6 +2642,29 @@
"integrity": "sha1-peeo/7+kk7Q7kju9TKiaU7Y7YSs=",
"dev": true
},
"fill-range": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
"integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
"dev": true,
"requires": {
"extend-shallow": "2.0.1",
"is-number": "3.0.0",
"repeat-string": "1.6.1",
"to-regex-range": "2.1.1"
},
"dependencies": {
"extend-shallow": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
"integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
"dev": true,
"requires": {
"is-extendable": "0.1.1"
}
}
}
},
"finalhandler": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz",
@ -3168,6 +3369,27 @@
"path-is-absolute": "1.0.1"
}
},
"glob-parent": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
"integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=",
"dev": true,
"requires": {
"is-glob": "3.1.0",
"path-dirname": "1.0.2"
},
"dependencies": {
"is-glob": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
"integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=",
"dev": true,
"requires": {
"is-extglob": "2.1.1"
}
}
}
},
"global-dirs": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz",
@ -3931,6 +4153,12 @@
"integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=",
"dev": true
},
"is-extglob": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
"integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
"dev": true
},
"is-finite": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz",
@ -3952,6 +4180,15 @@
"integrity": "sha1-wUwhBX7TbjKNuANHlmxpP4hjifM=",
"dev": true
},
"is-glob": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz",
"integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=",
"dev": true,
"requires": {
"is-extglob": "2.1.1"
}
},
"is-installed-globally": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.1.0.tgz",
@ -3968,6 +4205,15 @@
"integrity": "sha1-8vtjpl5JBbQGyGBydloaTceTufQ=",
"dev": true
},
"is-number": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
"integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
"dev": true,
"requires": {
"kind-of": "3.2.2"
}
},
"is-obj": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz",
@ -4063,6 +4309,12 @@
"integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
"dev": true
},
"isobject": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
"integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
"dev": true
},
"isstream": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
@ -4660,6 +4912,35 @@
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
"integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4="
},
"micromatch": {
"version": "3.1.10",
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
"integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
"dev": true,
"requires": {
"arr-diff": "4.0.0",
"array-unique": "0.3.2",
"braces": "2.3.2",
"define-property": "2.0.2",
"extend-shallow": "3.0.2",
"extglob": "2.0.4",
"fragment-cache": "0.2.1",
"kind-of": "6.0.2",
"nanomatch": "1.2.13",
"object.pick": "1.3.0",
"regex-not": "1.0.2",
"snapdragon": "0.8.2",
"to-regex": "3.0.2"
},
"dependencies": {
"kind-of": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
"integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
"dev": true
}
}
},
"mime": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz",

View File

@ -85,6 +85,7 @@
"@types/winston": "^2.3.2",
"@types/yamljs": "^0.2.30",
"apidoc": "^0.17.6",
"chokidar": "^2.0.4",
"chromedriver": "^2.37.0",
"commander": "^2.19.0",
"concurrently": "^4.1.0",

View File

@ -1,20 +1,105 @@
#!/bin/bash
#!/usr/bin/env node
config_path=$1
var program = require('commander');
var exec = require('child_process').execSync;
var spawn = require('child_process').spawn;
var chokidar = require('chokidar');
var fs = require('fs');
if [ "$config_path" == "" ];
then
echo "Please provide a configuration file."
exit 1
fi
program
.option('-s, --suite <suite>', 'The suite to run Authelia for. This suite represents a configuration for Authelia and a set of tests for that configuration.')
.parse(process.argv)
./example/compose/nginx/portal/render.js
if (!program.suite) {
throw new Error('Please provide a suite.');
}
./scripts/utils/prepare-environment.sh
const ENVIRONMENT_FILENAME = '.suite';
./node_modules/.bin/typescript-json-schema -o server/src/lib/configuration/Configuration.schema.json --strictNullChecks --required server/tsconfig.json Configuration
server_watcher="./node_modules/.bin/nodemon -e yml,js,ts,json --exec ./scripts/run-dev-server.sh $config_path 2>&1 /tmp/authelia-server.log"
client_watcher="cd client && BROWSER=none npm run start > /tmp/authelia-client.log"
var tsWatcher = chokidar.watch(['server', 'shared/**/*.ts', 'node_modules'], {
persistent: true,
ignoreInitial: true,
});
// Properly cleanup server and client if ctrl-c is hit
process.on('SIGINT', function() {
killServer();
killClient();
fs.unlinkSync(ENVIRONMENT_FILENAME);
process.exit();
});
let serverProcess;
function reloadServer() {
killServer(() => {
startServer();
});
}
function startServer() {
serverProcess = spawn('./scripts/run-dev-server.sh', [`test/suites/${program.suite}/config.yml`], {detached: true});
serverProcess.stdout.pipe(process.stdout);
serverProcess.stderr.pipe(process.stderr);
}
let clientProcess;
function startClient() {
clientProcess = spawn('npm', ['run', 'start'], {
detached: true,
cwd: './client',
env: {
...process.env,
'BROWSER': 'none'
}
});
clientProcess.stdout.pipe(process.stdout);
clientProcess.stderr.pipe(process.stderr);
}
function killServer(onExit) {
if (serverProcess) {
process.kill(-serverProcess.pid);
serverProcess.on('exit', () => {
serverProcess = undefined;
onExit();
});
}
}
function killClient(onExit) {
if (clientProcess) {
process.kill(-clientProcess.pid);
clientProcess.on('exit', () => {
clientProcess = undefined;
onExit();
});
}
}
function generateConfigurationSchema() {
exec('./node_modules/.bin/typescript-json-schema -o server/src/lib/configuration/Configuration.schema.json --strictNullChecks --required server/tsconfig.json Configuration');
}
function reload(path) {
console.log(`File ${path} has been changed, reloading...`);
if (path.startsWith('server/src/lib/configuration/schema')) {
console.log('Schema needs to be regenerated.');
generateConfigurationSchema();
}
reloadServer();
}
fs.writeFileSync(ENVIRONMENT_FILENAME, program.suite);
exec('./example/compose/nginx/portal/render.js');
exec('./scripts/utils/prepare-environment.sh');
console.log('Start watching');
tsWatcher.on('add', reload);
tsWatcher.on('remove', reload);
tsWatcher.on('change', reload);
startServer();
startClient();
./node_modules/.bin/concurrently "$server_watcher" "$client_watcher"

View File

@ -2,16 +2,44 @@
var program = require('commander');
var spawn = require('child_process').spawn;
var fs = require('fs');
var execSync = require('child_process').execSync;
program
.option('--with-server', 'Spawn Authelia before running the tests.')
.option('--headless', 'Run in headless mode.')
.parse(process.argv);
mocha = spawn('./node_modules/.bin/mocha', ['--exit', '--colors', '--require', 'ts-node/register', ...program.args], {
let suite;
let withServer = false;
let args = [];
const ENVIRONMENT_FILENAME = '.suite';
if (fs.existsSync(ENVIRONMENT_FILENAME)) {
const suite = fs.readFileSync(ENVIRONMENT_FILENAME);
console.log('Suite %s detected (dev env running). Running test related to this suite.', suite);
args.push('test/suites/' + suite + '/*.ts');
}
else if (program.args.length > 0) {
console.log('No suite detected. Running selected tests against built server.');
withServer = true;
args = program.args;
// Render the production version of the nginx portal configuration
// execSync('./example/compose/nginx/portal/render.js --production');
// Prepare the environment
// execSync('./scripts/utils/prepare-environment.sh');
}
else {
console.log('No suite detected but no tests have been selected...');
process.exit(1);
}
mocha = spawn('./node_modules/.bin/mocha', ['--exit', '--colors', '--require', 'ts-node/register', ...args], {
env: {
...process.env,
TS_NODE_PROJECT: 'test/tsconfig.json',
WITH_SERVER: (program.withServer) ? 'y' : 'n',
WITH_SERVER: (withServer) ? 'y' : 'n',
HEADLESS: (program.headless) ? 'y' : 'n',
}
});
@ -22,4 +50,3 @@ mocha.stdout.on('data', (data) => {
mocha.stderr.on('data', (data) => {
process.stderr.write(`${data}`);
});
// TS_NODE_PROJECT=server/tsconfig.json ./node_modules/.bin/mocha --colors --require ts-node/register server/src/**/*.spec.ts

View File

@ -12,6 +12,7 @@ function AutheliaSuiteBase(description: string, configPath: string,
cb: (this: Mocha.ISuiteCallbackContext) => void,
context: (description: string, ctx: (this: Mocha.ISuiteCallbackContext) => void) => Mocha.ISuite) {
if (!running && process.env['WITH_SERVER'] == 'y') {
console.log('Spawning Authelia server with configuration %s.', configPath);
WithAutheliaRunning(configPath);
running = true;
}

View File

@ -8,6 +8,10 @@ export default function WithAutheliaRunning(configPath: string, waitTimeout: num
'./scripts/authelia-scripts',
['serve', '--no-watch', '--config', configPath],
{detached: true});
authelia.on('exit', function() {
console.log('Server terminated.');
});
this.authelia = authelia;
const waitPromise = new Promise((resolve, reject) => setTimeout(() => resolve(), waitTimeout));

View File

@ -3,12 +3,16 @@ import chrome from 'selenium-webdriver/chrome';
import SeleniumWebdriver from "selenium-webdriver";
export default function() {
const options = new chrome.Options().addArguments('headless');
let options = new chrome.Options();
if (process.env['HEADLESS'] == 'y') {
options = options.headless();
}
beforeEach(function() {
const driver = new SeleniumWebdriver.Builder()
.forBrowser("chrome")
// .setChromeOptions(new chrome.Options().headless())
.setChromeOptions(options)
.build();
this.driver = driver;
});

View File

@ -2,7 +2,7 @@ import AutheliaSuite from "../../helpers/context/AutheliaSuite";
import MongoConnectionRecovery from "./scenarii/MongoConnectionRecovery";
import EnforceInternalRedirectionsOnly from "./scenarii/EnforceInternalRedirectionsOnly";
AutheliaSuite('Complete configuration', __dirname + 'config.yml', function() {
AutheliaSuite('Complete configuration', __dirname + '/config.yml', function() {
this.timeout(10000);
describe('Mongo broken connection recovery', MongoConnectionRecovery);

View File

@ -5,6 +5,7 @@ import child_process from 'child_process';
export default function() {
it("should be able to login after mongo restarts", async function() {
this.timeout(30000);
const secret = await LoginAndRegisterTotp(this.driver, "john", true);
child_process.execSync("./scripts/dc-dev.sh restart mongo");
await FullLogin(this.driver, "https://admin.example.com:8080/secret.html", "john", secret);