Convert 'logs' command to async/await and add tests

Change-type: patch
This commit is contained in:
Paulo Castro 2020-06-15 23:53:05 +01:00
parent 7e1d58546c
commit 19c3069b22
2 changed files with 82 additions and 19 deletions

View File

@ -83,16 +83,16 @@ export const logs: CommandDefinition<
},
],
primary: true,
async action(params, options, done) {
async action(params, options) {
normalizeUuidProp(params);
const balena = getBalenaSdk();
const { ExpectedError } = await import('../errors');
const { serviceIdToName } = await import('../utils/cloud');
const { displayDeviceLogs, displayLogObject } = await import(
'../utils/device/logs'
);
const { validateIPAddress } = await import('../utils/validation');
const { checkLoggedIn } = await import('../utils/patterns');
const { exitWithExpectedError } = await import('../errors');
const Logger = await import('../utils/logger');
const logger = Logger.getLogger();
@ -136,15 +136,12 @@ export const logs: CommandDefinition<
try {
await deviceApi.ping();
} catch (e) {
exitWithExpectedError(
new Error(
`Cannot access local mode device at address ${params.uuidOrDevice}`,
),
throw new ExpectedError(
`Cannot access local mode device at address ${params.uuidOrDevice}`,
);
}
const logStream = await deviceApi.getLogStream();
displayDeviceLogs(
await displayDeviceLogs(
logStream,
logger,
options.system || false,
@ -153,18 +150,19 @@ export const logs: CommandDefinition<
} else {
await checkLoggedIn();
if (options.tail) {
return balena.logs
.subscribe(params.uuidOrDevice, { count: 100 })
.then(function(logStream) {
logStream.on('line', displayCloudLog);
logStream.on('error', done);
})
.catch(done);
const logStream = await balena.logs.subscribe(params.uuidOrDevice, {
count: 100,
});
// Never resolve (quit with CTRL-C), but reject on a broken connection
await new Promise((_resolve, reject) => {
logStream.on('line', displayCloudLog);
logStream.on('error', reject);
});
} else {
return balena.logs
.history(params.uuidOrDevice)
.each(displayCloudLog)
.catch(done);
const logMessages = await balena.logs.history(params.uuidOrDevice);
for (const logMessage of logMessages) {
await displayCloudLog(logMessage);
}
}
}
},

View File

@ -0,0 +1,65 @@
/**
* @license
* Copyright 2020 Balena Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { expect } from 'chai';
import { BalenaAPIMock } from '../balena-api-mock';
import { cleanOutput, runCommand } from '../helpers';
import { SupervisorMock } from '../supervisor-mock';
const itS = process.env.BALENA_CLI_TEST_TYPE === 'standalone' ? it : it.skip;
describe('balena logs', function() {
let api: BalenaAPIMock;
let supervisor: SupervisorMock;
this.beforeEach(() => {
api = new BalenaAPIMock();
supervisor = new SupervisorMock();
api.expectGetWhoAmI();
api.expectGetMixpanel({ optional: true });
});
this.afterEach(() => {
// Check all expected api calls have been made and clean up.
api.done();
supervisor.done();
});
// skip non-standalone tests because nock's mock socket causes the error:
// "setKeepAliveInterval expects an instance of socket as its first argument"
// in utils/device/api.ts: NetKeepalive.setKeepAliveInterval(sock, 5000);
itS('should reach the expected endpoints on a local device', async () => {
supervisor.expectGetPing();
supervisor.expectGetLogs();
const { err, out } = await runCommand('logs 1.2.3.4');
expect(err).to.be.empty;
const removeTimestamps = (logLine: string) =>
logLine.replace(/(?<=\[Logs\]) \[.+?\]/, '');
const cleanedOut = cleanOutput(out, true).map(l => removeTimestamps(l));
expect(cleanedOut).to.deep.equal([
'[Logs] Streaming logs',
'[Logs] [bar] bar 8 (332) Linux 4e3f81149d71 4.19.75 #1 SMP PREEMPT Mon Mar 23 11:50:49 UTC 2020 aarch64 GNU/Linux',
'[Logs] [foo] foo 8 (200) Linux cc5df60d89ee 4.19.75 #1 SMP PREEMPT Mon Mar 23 11:50:49 UTC 2020 aarch64 GNU/Linux',
'[Error] Connection to device lost',
]);
});
});