@iobroker/testing 2.5.0 → 2.5.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -18,21 +18,11 @@ var __importStar = (this && this.__importStar) || function (mod) {
18
18
  __setModuleDefault(result, mod);
19
19
  return result;
20
20
  };
21
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
22
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
23
- return new (P || (P = Promise))(function (resolve, reject) {
24
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
25
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
26
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
27
- step((generator = generator.apply(thisArg, _arguments || [])).next());
28
- });
29
- };
30
21
  var __importDefault = (this && this.__importDefault) || function (mod) {
31
22
  return (mod && mod.__esModule) ? mod : { "default": mod };
32
23
  };
33
24
  Object.defineProperty(exports, "__esModule", { value: true });
34
25
  exports.ControllerSetup = void 0;
35
- /* eslint-disable @typescript-eslint/no-var-requires */
36
26
  // Add debug logging for tests
37
27
  const debug_1 = __importDefault(require("debug"));
38
28
  const fs_extra_1 = require("fs-extra");
@@ -41,18 +31,17 @@ const path = __importStar(require("path"));
41
31
  const adapterTools_1 = require("../../../lib/adapterTools");
42
32
  const executeCommand_1 = require("../../../lib/executeCommand");
43
33
  const tools_1 = require("./tools");
44
- const debug = debug_1.default("testing:integration:ControllerSetup");
34
+ const debug = (0, debug_1.default)("testing:integration:ControllerSetup");
45
35
  class ControllerSetup {
46
- constructor(adapterDir, testDir, dbConnection) {
36
+ constructor(adapterDir, testDir) {
47
37
  this.adapterDir = adapterDir;
48
38
  this.testDir = testDir;
49
- this.dbConnection = dbConnection;
50
39
  debug("Creating ControllerSetup...");
51
- this.adapterName = adapterTools_1.getAdapterName(this.adapterDir);
52
- this.appName = adapterTools_1.getAppName(this.adapterDir);
53
- this.testAdapterDir = tools_1.getTestAdapterDir(this.adapterDir, this.testDir);
54
- this.testControllerDir = tools_1.getTestControllerDir(this.appName, this.testDir);
55
- this.testDataDir = tools_1.getTestDataDir(this.appName, this.testDir);
40
+ this.adapterName = (0, adapterTools_1.getAdapterName)(this.adapterDir);
41
+ this.appName = (0, adapterTools_1.getAppName)(this.adapterDir);
42
+ this.testAdapterDir = (0, tools_1.getTestAdapterDir)(this.adapterDir, this.testDir);
43
+ this.testControllerDir = (0, tools_1.getTestControllerDir)(this.appName, this.testDir);
44
+ this.testDataDir = (0, tools_1.getTestDataDir)(this.appName, this.testDir);
56
45
  debug(` directories:`);
57
46
  debug(` controller: ${this.testControllerDir}`);
58
47
  debug(` adapter: ${this.testAdapterDir}`);
@@ -60,56 +49,62 @@ class ControllerSetup {
60
49
  debug(` appName: ${this.appName}`);
61
50
  debug(` adapterName: ${this.adapterName}`);
62
51
  }
63
- prepareTestDir() {
64
- return __awaiter(this, void 0, void 0, function* () {
65
- debug("Preparing the test directory...");
66
- // Make sure the test dir exists
67
- yield fs_extra_1.ensureDir(this.testDir);
68
- // Write the package.json
69
- const packageJson = {
70
- name: path.basename(this.testDir),
71
- version: "1.0.0",
72
- main: "index.js",
73
- scripts: {
74
- test: 'echo "Error: no test specified" && exit 1',
75
- },
76
- keywords: [],
77
- author: "",
78
- license: "ISC",
79
- dependencies: {
80
- [`${this.appName}.js-controller`]: "dev",
81
- },
82
- description: "",
83
- };
84
- yield fs_extra_1.writeJSON(path.join(this.testDir, "package.json"), packageJson, {
85
- spaces: 2,
86
- });
87
- // Delete a possible package-lock.json as it can mess with future installations
88
- const pckLockPath = path.join(this.testDir, "package-lock.json");
89
- if (yield fs_extra_1.pathExists(pckLockPath))
90
- yield fs_extra_1.unlink(pckLockPath);
91
- // Set the engineStrict flag on new Node.js versions to be in line with newer ioBroker installations
92
- const nodeMajorVersion = parseInt(process.versions.node.split(".")[0], 10);
93
- if (nodeMajorVersion >= 10) {
94
- yield fs_extra_1.writeFile(path.join(this.testDir, ".npmrc"), "engine-strict=true", "utf8");
95
- }
96
- debug(" => done!");
52
+ async prepareTestDir() {
53
+ debug("Preparing the test directory...");
54
+ // Make sure the test dir exists
55
+ await (0, fs_extra_1.ensureDir)(this.testDir);
56
+ // Write the package.json
57
+ const packageJson = {
58
+ name: path.basename(this.testDir),
59
+ version: "1.0.0",
60
+ main: "index.js",
61
+ scripts: {
62
+ test: 'echo "Error: no test specified" && exit 1',
63
+ },
64
+ keywords: [],
65
+ author: "",
66
+ license: "ISC",
67
+ dependencies: {
68
+ [`${this.appName}.js-controller`]: "dev",
69
+ },
70
+ description: "",
71
+ };
72
+ await (0, fs_extra_1.writeJSON)(path.join(this.testDir, "package.json"), packageJson, {
73
+ spaces: 2,
74
+ });
75
+ // Delete a possible package-lock.json as it can mess with future installations
76
+ const pckLockPath = path.join(this.testDir, "package-lock.json");
77
+ if (await (0, fs_extra_1.pathExists)(pckLockPath))
78
+ await (0, fs_extra_1.unlink)(pckLockPath);
79
+ // Set the engineStrict flag on new Node.js versions to be in line with newer ioBroker installations
80
+ const nodeMajorVersion = parseInt(process.versions.node.split(".")[0], 10);
81
+ if (nodeMajorVersion >= 10) {
82
+ await (0, fs_extra_1.writeFile)(path.join(this.testDir, ".npmrc"), "engine-strict=true", "utf8");
83
+ }
84
+ // Remember if JS-Controller is installed already. If so, we need to call `setup first` afterwards
85
+ const wasJsControllerInstalled = await this.isJsControllerInstalled();
86
+ // Defer to npm to install the controller (if it wasn't already)
87
+ debug("(Re-)installing JS Controller...");
88
+ await (0, executeCommand_1.executeCommand)("npm", ["i", "--production"], {
89
+ cwd: this.testDir,
97
90
  });
91
+ // Prepare/clean the databases and config
92
+ if (wasJsControllerInstalled)
93
+ await this.setupJsController();
94
+ debug(" => done!");
98
95
  }
99
96
  /**
100
97
  * Tests if JS-Controller is already installed
101
98
  * @param appName The branded name of "iobroker"
102
99
  * @param testDir The directory the integration tests are executed in
103
100
  */
104
- isJsControllerInstalled() {
105
- return __awaiter(this, void 0, void 0, function* () {
106
- debug("Testing if JS-Controller is installed...");
107
- // We expect js-controller to be installed if the dir in <testDir>/node_modules and the data directory exist
108
- const isInstalled = (yield fs_extra_1.pathExists(this.testControllerDir)) &&
109
- (yield fs_extra_1.pathExists(this.testDataDir));
110
- debug(` => ${isInstalled}`);
111
- return isInstalled;
112
- });
101
+ async isJsControllerInstalled() {
102
+ debug("Testing if JS-Controller is installed...");
103
+ // We expect js-controller to be installed if the dir in <testDir>/node_modules and the data directory exist
104
+ const isInstalled = (await (0, fs_extra_1.pathExists)(this.testControllerDir)) &&
105
+ (await (0, fs_extra_1.pathExists)(this.testDataDir));
106
+ debug(` => ${isInstalled}`);
107
+ return isInstalled;
113
108
  }
114
109
  /**
115
110
  * Tests if an instance of JS-Controller is already running by attempting to connect to the Objects DB
@@ -165,41 +160,34 @@ class ControllerSetup {
165
160
  // }
166
161
  /**
167
162
  * Sets up an existing JS-Controller instance for testing by executing "iobroker setup first"
168
- * @param appName The branded name of "iobroker"
169
- * @param testDir The directory the integration tests are executed in
170
163
  */
171
- setupJsController() {
172
- return __awaiter(this, void 0, void 0, function* () {
173
- debug("Initializing JS-Controller installation...");
174
- // Stop the controller before calling setup first
175
- yield executeCommand_1.executeCommand("node", [`${this.appName}.js`, "stop"], {
176
- cwd: this.testControllerDir,
177
- stdout: "ignore",
178
- });
179
- const setupResult = yield executeCommand_1.executeCommand("node", [`${this.appName}.js`, "setup", "first", "--console"], {
180
- cwd: this.testControllerDir,
181
- stdout: "ignore",
182
- });
183
- if (setupResult.exitCode !== 0)
184
- throw new Error(`${this.appName} setup first failed!`);
185
- debug(" => done!");
164
+ async setupJsController() {
165
+ debug("Initializing JS-Controller installation...");
166
+ // Stop the controller before calling setup first
167
+ await (0, executeCommand_1.executeCommand)("node", [`${this.appName}.js`, "stop"], {
168
+ cwd: this.testControllerDir,
169
+ stdout: "ignore",
170
+ });
171
+ const setupResult = await (0, executeCommand_1.executeCommand)("node", [`${this.appName}.js`, "setup", "first", "--console"], {
172
+ cwd: this.testControllerDir,
173
+ stdout: "ignore",
186
174
  });
175
+ if (setupResult.exitCode !== 0)
176
+ throw new Error(`${this.appName} setup first failed!`);
177
+ debug(" => done!");
187
178
  }
188
179
  /**
189
180
  * Changes the objects and states db to use alternative ports
190
181
  * @param appName The branded name of "iobroker"
191
182
  * @param testDir The directory the integration tests are executed in
192
183
  */
193
- setupSystemConfig() {
194
- return __awaiter(this, void 0, void 0, function* () {
195
- debug("Moving databases to different ports...");
196
- const systemFilename = path.join(this.testDataDir, `${this.appName}.json`);
197
- const systemConfig = require(systemFilename);
198
- systemConfig.objects.port = 19001;
199
- systemConfig.states.port = 19000;
200
- yield fs_extra_1.writeFile(systemFilename, JSON.stringify(systemConfig, null, 2));
201
- debug(" => done!");
202
- });
184
+ setupSystemConfig(dbConnection) {
185
+ debug(`Moving databases to different ports...`);
186
+ const systemConfig = dbConnection.getSystemConfig();
187
+ systemConfig.objects.port = 19001;
188
+ systemConfig.states.port = 19000;
189
+ dbConnection.setSystemConfig(systemConfig);
190
+ debug(" => done!");
203
191
  }
204
192
  /**
205
193
  * Clears the log dir for integration tests (and creates it if it doesn't exist)
@@ -208,7 +196,7 @@ class ControllerSetup {
208
196
  */
209
197
  clearLogDir() {
210
198
  debug("Cleaning log directory...");
211
- return fs_extra_1.emptyDir(tools_1.getTestLogDir(this.appName, this.testDir));
199
+ return (0, fs_extra_1.emptyDir)((0, tools_1.getTestLogDir)(this.appName, this.testDir));
212
200
  }
213
201
  /**
214
202
  * Clears the sqlite DB dir for integration tests (and creates it if it doesn't exist)
@@ -217,28 +205,25 @@ class ControllerSetup {
217
205
  */
218
206
  clearDBDir() {
219
207
  debug("Cleaning SQLite directory...");
220
- return fs_extra_1.emptyDir(tools_1.getTestDBDir(this.appName, this.testDir));
208
+ return (0, fs_extra_1.emptyDir)((0, tools_1.getTestDBDir)(this.appName, this.testDir));
221
209
  }
222
210
  /**
223
211
  * Disables all admin instances in the objects DB
224
212
  * @param objects The contents of objects.json
225
213
  */
226
- disableAdminInstances() {
227
- return __awaiter(this, void 0, void 0, function* () {
228
- debug("Disabling admin instances...");
229
- const objects = yield this.dbConnection.readObjectsDB();
230
- if (objects) {
231
- for (const id of Object.keys(objects)) {
232
- if (/^system\.adapter\.admin\.\d.+$/.test(id)) {
233
- const obj = objects[id];
234
- if (obj && obj.common)
235
- obj.common.enabled = false;
236
- }
237
- }
238
- yield this.dbConnection.writeObjectsDB(objects);
239
- }
240
- debug(" => done!");
214
+ async disableAdminInstances(dbConnection) {
215
+ debug("Disabling admin instances...");
216
+ const instanceObjects = await dbConnection.getObjectViewAsync("system", "instance", {
217
+ startkey: "system.adapter.admin.",
218
+ endkey: "system.adapter.admin.\u9999",
241
219
  });
220
+ for (const { id, value: obj } of instanceObjects.rows) {
221
+ if (obj && obj.common) {
222
+ obj.common.enabled = false;
223
+ await dbConnection.setObject(id, obj);
224
+ }
225
+ }
226
+ debug(" => done!");
242
227
  }
243
228
  }
244
229
  exports.ControllerSetup = ControllerSetup;
@@ -1,8 +1,14 @@
1
1
  /// <reference types="iobroker" />
2
+ /// <reference types="node" />
3
+ import EventEmitter from "events";
2
4
  export declare type ObjectsDB = Record<string, ioBroker.Object>;
3
5
  export declare type StatesDB = Record<string, ioBroker.State>;
4
- /** The DB connection capsules access to the objects.json and states.json on disk */
5
- export declare class DBConnection {
6
+ export interface DBConnection {
7
+ on(event: "objectChange", handler: ioBroker.ObjectChangeHandler): this;
8
+ on(event: "stateChange", handler: ioBroker.StateChangeHandler): this;
9
+ }
10
+ /** The DB connection capsules access to the states and objects DB */
11
+ export declare class DBConnection extends EventEmitter {
6
12
  private appName;
7
13
  private testDir;
8
14
  /**
@@ -11,25 +17,43 @@ export declare class DBConnection {
11
17
  */
12
18
  constructor(appName: string, testDir: string);
13
19
  private testDataDir;
14
- private objectsPath;
15
- private statesPath;
16
- readObjectsDB(): Promise<Record<string, ioBroker.Object> | undefined>;
17
- writeObjectsDB(objects: ObjectsDB | undefined): Promise<void>;
18
- writeStatesDB(states: StatesDB | undefined): Promise<void>;
19
- readStatesDB(): Promise<any>;
20
- /**
21
- * Creates a backup of the objects and states DB, so it can be restored after each test
22
- * @param appName The branded name of "iobroker"
23
- * @param testDir The directory the integration tests are executed in
24
- */
25
- readDB(): Promise<{
26
- objects: Record<string, ioBroker.Object> | undefined;
27
- states: any;
20
+ private testControllerDir;
21
+ private _objectsServer;
22
+ private _statesServer;
23
+ private _objectsClient;
24
+ /** The underlying objects client instance that can be used to access the objects DB */
25
+ get objectsClient(): any;
26
+ private _statesClient;
27
+ /** The underlying states client instance that can be used to access the states DB */
28
+ get statesClient(): any;
29
+ get objectsType(): "file" | "jsonl";
30
+ get objectsPath(): string;
31
+ get statesType(): "file" | "jsonl";
32
+ get statesPath(): string;
33
+ getSystemConfig(): any;
34
+ backup(): Promise<{
35
+ objects: Buffer;
36
+ states: Buffer;
28
37
  }>;
29
- /**
30
- * Restores a previous backup of the objects and states DB
31
- * @param appName The branded name of "iobroker"
32
- * @param testDir The directory the integration tests are executed in
33
- */
34
- writeDB(objects: any, states: any): Promise<void>;
38
+ restore(objects: Buffer, states: Buffer): Promise<void>;
39
+ setSystemConfig(systemConfig: any): void;
40
+ private _isRunning;
41
+ get isRunning(): boolean;
42
+ start(): Promise<void>;
43
+ stop(): Promise<void>;
44
+ /** Creates the objects DB and sets up listeners for it */
45
+ private createObjectsDB;
46
+ /** Creates the states DB and sets up listeners for it */
47
+ private createStatesDB;
48
+ readonly getObject: ioBroker.Adapter["getForeignObjectAsync"];
49
+ readonly setObject: ioBroker.Adapter["setForeignObjectAsync"];
50
+ readonly delObject: ioBroker.Adapter["delForeignObjectAsync"];
51
+ readonly getState: ioBroker.Adapter["getForeignStateAsync"];
52
+ readonly setState: ioBroker.Adapter["setForeignStateAsync"];
53
+ readonly delState: ioBroker.Adapter["delForeignStateAsync"];
54
+ subscribeMessage(id: string): void;
55
+ pushMessage(instanceId: string, msg: any, callback: (err: Error | null, id: any) => void): void;
56
+ readonly getObjectViewAsync: ioBroker.Adapter["getObjectViewAsync"];
57
+ getStateIDs(pattern?: string): Promise<string[]>;
58
+ getObjectIDs(pattern?: string): Promise<string[]>;
35
59
  }