UNPKG

@iobroker/testing

Version:

Shared utilities for adapter and module testing in ioBroker

239 lines (238 loc) 10 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.ControllerSetup = void 0; // Add debug logging for tests const debug_1 = __importDefault(require("debug")); const fs_extra_1 = require("fs-extra"); const net_1 = require("net"); const path = __importStar(require("path")); const adapterTools_1 = require("../../../lib/adapterTools"); const executeCommand_1 = require("../../../lib/executeCommand"); const tools_1 = require("./tools"); const debug = (0, debug_1.default)('testing:integration:ControllerSetup'); class ControllerSetup { constructor(adapterDir, testDir) { this.adapterDir = adapterDir; this.testDir = testDir; debug('Creating ControllerSetup...'); this.adapterName = (0, adapterTools_1.getAdapterName)(this.adapterDir); this.appName = (0, adapterTools_1.getAppName)(this.adapterDir); this.testAdapterDir = (0, tools_1.getTestAdapterDir)(this.adapterDir, this.testDir); this.testControllerDir = (0, tools_1.getTestControllerDir)(this.appName, this.testDir); this.testDataDir = (0, tools_1.getTestDataDir)(this.appName, this.testDir); debug(` directories:`); debug(` controller: ${this.testControllerDir}`); debug(` adapter: ${this.testAdapterDir}`); debug(` data: ${this.testDataDir}`); debug(` appName: ${this.appName}`); debug(` adapterName: ${this.adapterName}`); } async prepareTestDir(controllerVersion = 'dev') { debug(`Preparing the test directory. JS-Controller version: "${controllerVersion}"...`); // Make sure the test dir exists await (0, fs_extra_1.ensureDir)(this.testDir); // Write the package.json const packageJson = { name: path.basename(this.testDir), version: '1.0.0', main: 'index.js', scripts: { test: 'echo "Error: no test specified" && exit 1', }, keywords: [], author: '', license: 'ISC', dependencies: { [`${this.appName}.js-controller`]: controllerVersion, }, description: '', }; await (0, fs_extra_1.writeJSON)(path.join(this.testDir, 'package.json'), packageJson, { spaces: 2, }); // Delete a possible package-lock.json as it can mess with future installations const pckLockPath = path.join(this.testDir, 'package-lock.json'); if (await (0, fs_extra_1.pathExists)(pckLockPath)) { await (0, fs_extra_1.unlink)(pckLockPath); } // Set the engineStrict flag on new Node.js versions to be in line with newer ioBroker installations const nodeMajorVersion = parseInt(process.versions.node.split('.')[0], 10); if (nodeMajorVersion >= 10) { await (0, fs_extra_1.writeFile)(path.join(this.testDir, '.npmrc'), 'engine-strict=true', 'utf8'); } // Remember if JS-Controller is installed already. If so, we need to call `setup first` afterwards const wasJsControllerInstalled = await this.isJsControllerInstalled(); // Defer to npm to install the controller (if it wasn't already) debug('(Re-)installing JS Controller...'); await (0, executeCommand_1.executeCommand)('npm', ['i', '--omit=dev'], { cwd: this.testDir, }); // Prepare/clean the databases and config if (wasJsControllerInstalled) { await this.setupJsController(); } debug(' => done!'); } /** * Tests if JS-Controller is already installed */ async isJsControllerInstalled() { debug('Testing if JS-Controller is installed...'); // We expect js-controller to be installed if the dir in <testDir>/node_modules and the data directory exist const isInstalled = (await (0, fs_extra_1.pathExists)(this.testControllerDir)) && (await (0, fs_extra_1.pathExists)(this.testDataDir)); debug(` => ${isInstalled}`); return isInstalled; } /** * Tests if an instance of JS-Controller is already running by attempting to connect to the Objects DB */ isJsControllerRunning() { debug('Testing if JS-Controller is running...'); return new Promise(resolve => { const client = new net_1.Socket(); const timeout = setTimeout(() => { // Assume the connection failed after 1 s client.destroy(); debug(` => false`); resolve(false); }, 1000); // Try to connect to an existing ObjectsDB client .connect({ port: 9000, host: '127.0.0.1', }) .on('connect', () => { // The connection succeeded client.destroy(); debug(` => true`); clearTimeout(timeout); resolve(true); }) .on('error', () => { client.destroy(); debug(` => false`); clearTimeout(timeout); resolve(false); }); }); } // /** // * Installs a new instance of JS-Controller into the test directory // * @param appName The branded name of "iobroker" // * @param testDir The directory the integration tests are executed in // */ // public async installJsController(): Promise<void> { // debug("Installing newest JS-Controller from github..."); // // First npm install the JS-Controller into the correct directory // const installUrl = `${this.appName}/${this.appName}.js-controller`; // const installResult = await executeCommand( // "npm", // ["i", installUrl, "--save"], // { // cwd: this.testDir, // }, // ); // if (installResult.exitCode !== 0) // throw new Error("JS-Controller could not be installed!"); // debug(" => done!"); // } /** * Sets up an existing JS-Controller instance for testing by executing "iobroker setup first" */ async setupJsController() { debug('Initializing JS-Controller installation...'); // Stop the controller before calling setup first await (0, executeCommand_1.executeCommand)('node', [`${this.appName}.js`, 'stop'], { cwd: this.testControllerDir, stdout: 'ignore', }); const setupResult = await (0, executeCommand_1.executeCommand)('node', [`${this.appName}.js`, 'setup', 'first', '--console'], { cwd: this.testControllerDir, stdout: 'ignore', }); if (setupResult.exitCode !== 0) { throw new Error(`${this.appName} setup first failed!`); } debug(' => done!'); } /** * Changes the objects and states db to use alternative ports */ setupSystemConfig(dbConnection) { debug(`Moving databases to different ports...`); const systemConfig = dbConnection.getSystemConfig(); systemConfig.objects.port = 19001; systemConfig.states.port = 19000; dbConnection.setSystemConfig(systemConfig); debug(' => done!'); } /** * Clears the log dir for integration tests (and creates it if it doesn't exist) */ clearLogDir() { debug('Cleaning log directory...'); return (0, fs_extra_1.emptyDir)((0, tools_1.getTestLogDir)(this.appName, this.testDir)); } /** * Clears the sqlite DB dir for integration tests (and creates it if it doesn't exist) */ clearDBDir() { debug('Cleaning SQLite directory...'); return (0, fs_extra_1.emptyDir)((0, tools_1.getTestDBDir)(this.appName, this.testDir)); } /** * Disables all admin instances in the objects DB */ async disableAdminInstances(dbConnection) { debug('Disabling admin instances...'); const instanceObjects = await dbConnection.getObjectViewAsync('system', 'instance', { startkey: 'system.adapter.admin.', endkey: 'system.adapter.admin.\u9999', }); for (const { id, value: obj } of instanceObjects.rows) { if (obj && obj.common) { obj.common.enabled = false; await dbConnection.setObject(id, obj); } } debug(' => done!'); } } exports.ControllerSetup = ControllerSetup;