UNPKG

@wdio/lambda-runner

Version:
98 lines (97 loc) 4.57 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const fs_1 = __importDefault(require("fs")); const tmp_1 = __importDefault(require("tmp")); const path_1 = __importDefault(require("path")); const shelljs_1 = __importDefault(require("shelljs")); const events_1 = __importDefault(require("events")); const find_node_modules_1 = __importDefault(require("find-node-modules")); const logger_1 = __importDefault(require("@wdio/logger")); const constants_1 = require("./constants"); const log = logger_1.default('@wdio/lambda-runner'); class AWSLambdaRunner extends events_1.default { constructor(configFile, config, capabilities, specs) { super(); const { AWS_ACCESS_KEY, AWS_ACCESS_KEY_ID } = process.env; if (!AWS_ACCESS_KEY || !AWS_ACCESS_KEY_ID) { throw new Error('Please provide AWS_ACCESS_KEY, AWS_ACCESS_KEY_ID, AWS_BUCKET in your environment'); } this.instances = []; this.configFile = configFile; this.config = config; this.capabilities = capabilities; this.specs = specs; this.nodeModulesDir = path_1.default.resolve(find_node_modules_1.default()[0]); this.pwd = shelljs_1.default.pwd().stdout; this.serverlessBinPath = path_1.default.resolve(require.resolve('serverless'), '..', '..', 'bin', 'serverless'); } async initialise() { this.serviceDir = tmp_1.default.dirSync({ prefix: '.wdio-runner-service', dir: process.cwd(), mode: '0750' }); log.info('Generating temporary AWS Lamdba service directory at %s', this.serviceDir.name); this.link(this.nodeModulesDir, path_1.default.resolve(this.serviceDir.name, 'node_modules')); this.link(path_1.default.resolve(process.cwd(), this.configFile), path_1.default.resolve(this.serviceDir.name, this.configFile)); this.specs.forEach((spec) => { this.link(spec, path_1.default.join(this.serviceDir.name, spec.replace(process.cwd(), ''))); }); const runnerConfig = Object.assign(constants_1.DEFAULT_CONFIG, { environment: { DEBUG: 1 }, package: { include: [], exclude: [] } }); shelljs_1.default.cp(path_1.default.resolve(__dirname, '..', 'config', 'serverless.yml'), path_1.default.resolve(this.serviceDir.name, 'serverless.yml')); shelljs_1.default.cp(path_1.default.resolve(__dirname, 'handler.js'), path_1.default.resolve(this.serviceDir.name, 'handler.js')); fs_1.default.writeFileSync(path_1.default.resolve(this.serviceDir.name, 'runner-config.json'), JSON.stringify(runnerConfig, null, 4)); shelljs_1.default.cd(this.serviceDir.name); await this.exec(`${this.serverlessBinPath} deploy --verbose`); shelljs_1.default.cd(this.pwd); } kill() { } async run(options) { options.specs = options.specs.map((spec) => spec.replace(process.cwd(), '.')); shelljs_1.default.cd(this.serviceDir.name); let result; try { result = await this.exec(`${this.serverlessBinPath} invoke -f run --data '${JSON.stringify(options)}' --verbose`); } catch (e) { log.error(`Failed to run Lambda process for cid ${options.cid}`); } shelljs_1.default.cd(this.pwd); this.emit(this.cid, result.failures === 0 ? 0 : 1); } link(source, dest) { log.debug('Linking: ', source, dest); fs_1.default.symlinkSync(source, dest); } exec(script) { log.debug(`Run script "${script}"`); return new Promise((resolve, reject) => { const child = shelljs_1.default.exec(script, { async: true, silent: true }); child.stdout.on('data', (stdout) => { const trimmedStdout = stdout.trim().replace(/^Serverless: /, ''); if (trimmedStdout.startsWith('{')) { return resolve(JSON.parse(trimmedStdout)); } log.debug(trimmedStdout); }); child.stderr.on('data', log.error.bind(log)); child.on('close', (code) => { if (code === 0) { return resolve(code); } reject(new Error(`script failed with exit code ${code}`)); }); }); } } exports.default = AWSLambdaRunner;