Skip to content

Commit 5daaa64

Browse files
author
Pavel Petroshenko
authored
Merge pull request #49 from electricimp/develop
v2.4.1
2 parents 691e171 + c282b78 commit 5daaa64

File tree

122 files changed

+3942
-383
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

122 files changed

+3942
-383
lines changed

Diff for: lib/util/ImpCentralApiHelper.js

+4-7
Original file line numberDiff line numberDiff line change
@@ -320,25 +320,23 @@ class ImpCentralApiHelper {
320320
}
321321

322322
createEntity(entityType, ...args) {
323-
const isLoginKey = entityType === Identifier.ENTITY_TYPE.TYPE_LOGIN_KEY;
324323
const entityApi = this._getEntityApi(entityType);
325324
return this._checkAccessToken().
326325
then(() => this._entityStorage.clearList(entityType)).
327326
then(() => this._processImpCentralApiRequest(
328-
!isLoginKey, null, null, entityApi.create.bind(entityApi), ...args)).
327+
true, null, null, entityApi.create.bind(entityApi), ...args)).
329328
then(result => result.data);
330329
}
331330

332331
updateEntity(entityType, id, ...args) {
333-
const isLoginKey = entityType === Identifier.ENTITY_TYPE.TYPE_LOGIN_KEY;
334332
const entityApi = this._getEntityApi(entityType);
335333
return this._checkAccessToken().
336334
then(() => {
337335
this._entityStorage.clearList(entityType);
338336
this._entityStorage.clearEntity(id);
339337
}).
340338
then(() => this._processImpCentralApiRequest(
341-
!isLoginKey, entityType, id, entityApi.update.bind(entityApi), id, ...args)).
339+
true, entityType, id, entityApi.update.bind(entityApi), id, ...args)).
342340
then(result => result.data);
343341
}
344342

@@ -362,15 +360,14 @@ class ImpCentralApiHelper {
362360
}
363361

364362
deleteEntity(entityType, id, ...args) {
365-
const isLoginKey = entityType === Identifier.ENTITY_TYPE.TYPE_LOGIN_KEY;
366363
const entityApi = this._getEntityApi(entityType);
367364
return this._checkAccessToken().
368365
then(() => {
369366
this._entityStorage.clearList(entityType);
370367
this._entityStorage.clearEntity(id);
371368
}).
372369
then(() => this._processImpCentralApiRequest(
373-
!isLoginKey, entityType, id, entityApi.delete.bind(entityApi), id, ...args));
370+
true, entityType, id, entityApi.delete.bind(entityApi), id, ...args));
374371
}
375372

376373
restartDevices(devGroupId, conditional = false) {
@@ -506,7 +503,7 @@ class ImpCentralApiHelper {
506503
// try to refresh access token in case of authentication error and then restart the original request
507504
return this._refreshAccessToken().
508505
then(() => this._processImpCentralApiRequest(
509-
refreshAccessTokenOnAuthError, entityType, id, impCentralApiMethod, ...args));
506+
false, entityType, id, impCentralApiMethod, ...args));
510507
}
511508
}
512509
else if (this._isRateLimitError(error)) {

Diff for: package-lock.json

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "imp-central-impt",
3-
"version": "2.4.0",
3+
"version": "2.4.1",
44
"description": "impt - command line tool for the Electric Imp impCentral API",
55
"main": "bin/impt",
66
"engines": {

Diff for: spec/ImptTestHelper.js

+39-32
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ const Utils = require('../lib/util/Utils');
3333
const UserInteractor = require('../lib/util/UserInteractor');
3434
const child_process = require('child_process');
3535

36-
const TIMEOUT_MS = 300000;
36+
const TIMEOUT_MS = 10000000;
3737
const TESTS_EXECUTION_FOLDER = `${__dirname}/../__test${process.env.IMPT_FOLDER_SUFFIX ? process.env.IMPT_FOLDER_SUFFIX : ''}`;
3838
const KEY_ANSWER = {
3939
CTRL_C: '\x03',
@@ -103,7 +103,7 @@ class ImptTestHelper {
103103
if (login) {
104104
const endpoint = config.apiEndpoint ? `--endpoint ${config.apiEndpoint}` : '';
105105
return ImptTestHelper.runCommand(
106-
`impt auth login --local --user ${config.username} --pwd ${config.password} ${endpoint}`,
106+
`impt auth login --local --user ${config.username} --pwd "${config.password}" ${endpoint}`,
107107
ImptTestHelper.checkSuccessStatus);
108108
}
109109
return Promise.resolve();
@@ -155,26 +155,6 @@ class ImptTestHelper {
155155
}).then(outputChecker);
156156
}
157157

158-
static runCommandWithTerminate(command, outputChecker) {
159-
var child;
160-
return Promise.all([
161-
new Promise((resolve, reject) => {
162-
if (config.debug) {
163-
console.log('Running command: ' + command);
164-
}
165-
child = Shell.exec(`node ${__dirname}/../bin/${command}`,
166-
{ silent: !config.debug },
167-
(code, stdout, stderr) => {
168-
resolve({ code: code, output: stdout.replace(/((\u001b\[2K.*\u001b\[1G)|(\u001b\[[0-9]{2}m))/g, '') });
169-
});
170-
171-
}).then(outputChecker),
172-
this.delayMs(20000).
173-
then(() => child.kill('SIGINT')).
174-
then(() => child.kill())
175-
]);
176-
}
177-
178158
static delayMs(ms) {
179159
return new Promise((resolve) => {
180160
setTimeout(resolve, ms);
@@ -183,15 +163,15 @@ class ImptTestHelper {
183163

184164
static getDeviceAttrs(product, dg, output) {
185165
let jsonInfo = null;
186-
return ImptTestHelper.runCommand(`impt product create -n ${product}`, ImptTestHelper.emptyCheckEx).
166+
return ImptTestHelper.runCommand(`impt product create -n ${product}`, ImptTestHelper.emptyCheck).
187167
then(() => ImptTestHelper.runCommand(`impt dg create -n ${dg} -p ${product}`, ImptTestHelper.emptyCheck)).
188-
then(() => ImptTestHelper.runCommand(`impt device assign -d ${config.devices[config.deviceidx]} -g ${dg} -q`, ImptTestHelper.emptyCheckEx)).
189-
then(() => ImptTestHelper.runCommand(`impt build deploy -g ${dg}`, ImptTestHelper.emptyCheckEx)).
168+
then(() => ImptTestHelper.runCommand(`impt device assign -d ${config.devices[config.deviceidx]} -g ${dg} -q`, ImptTestHelper.emptyCheck)).
169+
then(() => ImptTestHelper.runCommand(`impt build deploy -g ${dg}`, ImptTestHelper.emptyCheck)).
190170
then(() => ImptTestHelper.runCommand(`impt device info -d ${config.devices[config.deviceidx]} -z json`, (commandOut) => {
191171
jsonInfo = commandOut.output;
192172
ImptTestHelper.emptyCheck(commandOut);
193173
})).
194-
then(() => ImptTestHelper.runCommand(`impt product delete -p ${product} -f -b -q`, ImptTestHelper.emptyCheckEx)).
174+
then(() => ImptTestHelper.runCommand(`impt product delete -p ${product} -f -b -q`, ImptTestHelper.emptyCheck)).
195175
then(() => {
196176
return new Promise((resolve) => {
197177
let json = JSON.parse(jsonInfo);
@@ -247,28 +227,35 @@ class ImptTestHelper {
247227
expect(file).toEqual(file2);
248228
}
249229

230+
static checkFileContainsString(fileName, string) {
231+
expect(Shell.test('-e', `${TESTS_EXECUTION_FOLDER}/${fileName}`)).toBe(true);
232+
let file = Shell.cat(`${TESTS_EXECUTION_FOLDER}/${fileName}`);
233+
expect(file).toMatch(string);
234+
}
235+
250236
static projectCreate(dg, dfile = 'device.nut', afile = 'agent.nut') {
251-
return ImptTestHelper.runCommand(`impt project link -g ${dg} -x ${dfile} -y ${afile} -q`, ImptTestHelper.emptyCheckEx);
237+
return ImptTestHelper.runCommand(`impt project link -g ${dg} -x ${dfile} -y ${afile} -q`, ImptTestHelper.emptyCheck);
252238
}
253239

254240
static projectDelete() {
255-
return ImptTestHelper.runCommand(`impt project delete -f -q`, ImptTestHelper.emptyCheckEx);
241+
return ImptTestHelper.runCommand(`impt project delete -f -q`, ImptTestHelper.emptyCheck);
256242
}
257243

258244
static deviceAssign(dg) {
259-
return ImptTestHelper.runCommand(`impt device assign -d ${config.devices[config.deviceidx]} -g ${dg} -q`, ImptTestHelper.emptyCheckEx);
245+
return ImptTestHelper.runCommand(`impt device assign -d ${config.devices[config.deviceidx]} -g ${dg} -q`, ImptTestHelper.emptyCheck);
260246
}
261247

262248
static deviceRestart() {
263-
return ImptTestHelper.runCommand(`impt device restart -d ${config.devices[config.deviceidx]}`, ImptTestHelper.emptyCheckEx);
249+
return ImptTestHelper.runCommand(`impt device restart -d ${config.devices[config.deviceidx]}`, ImptTestHelper.emptyCheck);
264250
}
265251

266252
static deviceUnassign(dg) {
267-
return ImptTestHelper.runCommand(`impt dg unassign -g ${dg}`, ImptTestHelper.emptyCheckEx);
253+
return ImptTestHelper.runCommand(`impt dg unassign -g ${dg}`, ImptTestHelper.emptyCheck);
268254
}
269255

270256
// Checks success return code of the command
271257
static checkSuccessStatus(commandOut) {
258+
expect(commandOut.output).not.toMatch(UserInteractor.ERRORS.ACCESS_FAILED);
272259
expect(commandOut.code).toEqual(0);
273260
}
274261

@@ -285,7 +272,7 @@ class ImptTestHelper {
285272

286273
// Checks if the command output contains the specified attribute name and value
287274
static checkAttribute(commandOut, attrName, attrValue) {
288-
expect(commandOut.output).toMatch(new RegExp(`${attrName}"?:\\s+"?${attrValue.replace(new RegExp(/"/g), '\\\\?"')}"?`));
275+
expect(commandOut.output).toMatch(new RegExp(`${attrName}"?:\\s+"?${attrValue.replace(new RegExp(/([\^\[\.\$\{\*\(\\\+\)\|\?\<\>])/g),'\\$&').replace(new RegExp(/"/g), '\\\\?"')}"?`));
289276
}
290277

291278
// Checks if the command output contains the specified message for default or debug output mode
@@ -312,6 +299,26 @@ class ImptTestHelper {
312299
}
313300
else return null;
314301
}
302+
303+
// parse loginkey id from command output and return id value if success, otherwise return null
304+
static parseLoginkey(commandOut) {
305+
if (commandOut.output.match('Account Limit Reached')) {
306+
console.log('Error: No free loginkey slot');
307+
return null;
308+
}
309+
const idMatcher = commandOut.output.match(new RegExp(`[0-9a-z]{16}`));
310+
if (idMatcher && idMatcher.length > 0) {
311+
return idMatcher[0];
312+
}
313+
else return null;
314+
}
315+
316+
static checkDeviceStatus(device) {
317+
return ImptTestHelper.runCommand(`impt device info --device ${device} `, (commandOut) => {
318+
if (commandOut.output.match('not found')) console.log(`Error: Device id:${device} not found`);
319+
if (commandOut.output.match(/device_online:\\s+false/)) console.log(`Error: Device id:${device} is offline`);
320+
});
321+
}
315322
}
316323

317324
module.exports = ImptTestHelper;

Diff for: spec/MessageHelper.js

+10
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,12 @@ class MessageHelper {
111111
);
112112
}
113113

114+
static checkTestDeviceGroupNotExistMessage(commandOut, deviceGroup) {
115+
ImptTestHelper.checkAttribute(commandOut, UserInterractor.ERRORS.ERROR,
116+
Util.format(`${UserInterractor.ERRORS.CONFIG_OUTDATED}`, `Device Group "${deviceGroup}"`, 'Test Configuration')
117+
);
118+
}
119+
114120
static checkProjectNotFoundMessage(commandOut) {
115121
ImptTestHelper.checkAttribute(commandOut, UserInterractor.ERRORS.ERROR,
116122
`Project File is not found in the current directory.`
@@ -158,6 +164,10 @@ class MessageHelper {
158164
Util.format(`${UserInterractor.ERRORS.CMD_REQUIRED_OPTION}`, `${option}`)
159165
);
160166
}
167+
static checkNoTestFileFoundMessage(commandOut) {
168+
ImptTestHelper.checkAttribute(commandOut, UserInterractor.ERRORS.ERROR,
169+
UserInterractor.ERRORS.TEST_NO_FILES_FOUND);
170+
}
161171
}
162172

163173
module.exports = MessageHelper;

Diff for: spec/README.md

+12-6
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@ In order to decrease a time of the tests execution, the tests for different comm
2727

2828
To avoid collisions, every thread should use it's own folder. So, you must specify **IMPT_FOLDER_SUFFIX** variable for each thread.
2929

30-
The following groups of tests do not require a device and can be always executed in parallel: `auth`, `loginkey`, `product`, `project`, `webhook`, `help`.
30+
The following groups of tests do not require a device and can be always executed in parallel: `auth`, `account`, `loginkey`, `product`, `project`, `webhook`, `help`.
3131

32-
The following groups of tests require a device and cannot be executed in parallel on the same device: `build`, `log`, `device`, `dg`. They should be executed either sequentially, or in parallel using different devices (use **IMPT_DEVICE_IDX** variable to specify a concrete device for every thread).
32+
The following groups of tests require a device and cannot be executed in parallel on the same device: `build`, `log`, `device`, `dg`,`test`. They should be executed either sequentially, or in parallel using different devices (use **IMPT_DEVICE_IDX** variable to specify a concrete device for every thread).
3333

3434
### Example ###
3535

@@ -40,8 +40,9 @@ Scripts for the fastest tests execution:
4040
##### On Windows #####
4141

4242
```
43-
start cmd /k "npm test --filter **/build/*.spec.js **/log/*.spec.js **/dg/*.spec.js **/device/*.spec.js IMPT_FOLDER_SUFFIX=build"
43+
start cmd /k "npm test --filter **/build/*.spec.js **/log/*.spec.js **/dg/*.spec.js **/device/*.spec.js **/test/*.spec.js IMPT_FOLDER_SUFFIX=build"
4444
start cmd /k "npm test --filter **/auth/*.spec.js IMPT_FOLDER_SUFFIX=auth"
45+
start cmd /k "npm test --filter **/account/*.spec.js IMPT_FOLDER_SUFFIX=account"
4546
start cmd /k "npm test --filter **/loginkey/*.spec.js IMPT_FOLDER_SUFFIX=loginkey"
4647
start cmd /k "npm test --filter **/product/*.spec.js IMPT_FOLDER_SUFFIX=product"
4748
start cmd /k "npm test --filter **/webhook/*.spec.js IMPT_FOLDER_SUFFIX=webhook"
@@ -53,16 +54,17 @@ Scripts for the fastest tests execution:
5354

5455
```
5556
#/bin/sh
56-
npm test --filter **/build/*.spec.js **/log/*.spec.js **/dg/*.spec.js **/device/*.spec.js IMPT_FOLDER_SUFFIX=build &
57+
npm test --filter **/build/*.spec.js **/log/*.spec.js **/dg/*.spec.js **/device/*.spec.js **/test/*.spec.js IMPT_FOLDER_SUFFIX=build &
5758
npm test --filter **/auth/*.spec.js IMPT_FOLDER_SUFFIX=auth &
59+
npm test --filter **/account/*.spec.js IMPT_FOLDER_SUFFIX=account &
5860
npm test --filter **/loginkey/*.spec.js IMPT_FOLDER_SUFFIX=loginkey &
5961
npm test --filter **/product/*.spec.js IMPT_FOLDER_SUFFIX=product &
6062
npm test --filter **/webhook/*.spec.js IMPT_FOLDER_SUFFIX=webhook &
6163
npm test --filter **/project/*.spec.js IMPT_FOLDER_SUFFIX=project &
6264
npm test --filter **/help/*.spec.js IMPT_FOLDER_SUFFIX=help
6365
```
6466

65-
#### Using 4 devices ####
67+
#### Using 5 devices ####
6668

6769
##### On Windows #####
6870

@@ -71,7 +73,9 @@ Scripts for the fastest tests execution:
7173
start cmd /k "npm test --filter **/log/*.spec.js IMPT_FOLDER_SUFFIX=log IMPT_DEVICE_IDX=1"
7274
start cmd /k "npm test --filter **/dg/*.spec.js IMPT_FOLDER_SUFFIX=dg IMPT_DEVICE_IDX=2"
7375
start cmd /k "npm test --filter **/device/*.spec.js IMPT_FOLDER_SUFFIX=device IMPT_DEVICE_IDX=3"
76+
start cmd /k "npm test --filter **/test/*.spec.js IMPT_FOLDER_SUFFIX=test IMPT_DEVICE_IDX=4"
7477
start cmd /k "npm test --filter **/auth/*.spec.js IMPT_FOLDER_SUFFIX=auth"
78+
start cmd /k "npm test --filter **/account/*.spec.js IMPT_FOLDER_SUFFIX=account"
7579
start cmd /k "npm test --filter **/loginkey/*.spec.js IMPT_FOLDER_SUFFIX=loginkey"
7680
start cmd /k "npm test --filter **/product/*.spec.js IMPT_FOLDER_SUFFIX=product"
7781
start cmd /k "npm test --filter **/webhook/*.spec.js IMPT_FOLDER_SUFFIX=webhook"
@@ -87,7 +91,9 @@ Scripts for the fastest tests execution:
8791
npm test --filter **/log/*.spec.js IMPT_FOLDER_SUFFIX=log IMPT_DEVICE_IDX=1 &
8892
npm test --filter **/dg/*.spec.js IMPT_FOLDER_SUFFIX=dg IMPT_DEVICE_IDX=2 &
8993
npm test --filter **/device/*.spec.js IMPT_FOLDER_SUFFIX=device IMPT_DEVICE_IDX=3 &
94+
npm test --filter **/test/*.spec.js IMPT_FOLDER_SUFFIX=test IMPT_DEVICE_IDX=4 &
9095
npm test --filter **/auth/*.spec.js IMPT_FOLDER_SUFFIX=auth &
96+
npm test --filter **/account/*.spec.js IMPT_FOLDER_SUFFIX=account &
9197
npm test --filter **/loginkey/*.spec.js IMPT_FOLDER_SUFFIX=loginkey &
9298
npm test --filter **/product/*.spec.js IMPT_FOLDER_SUFFIX=product &
9399
npm test --filter **/webhook/*.spec.js IMPT_FOLDER_SUFFIX=webhook &
@@ -149,4 +155,4 @@ The files may be extended by adding more reusable methods during new tests devel
149155

150156
## Test Matrix ##
151157

152-
The list and details of the existing tests as described in the [Test Matrix document](./TestMatrix.md).
158+
The list and details of the existing tests are described in the [Test Matrix document](./TestMatrix.md).

0 commit comments

Comments
 (0)