Fix undervoltage regex, add undervoltage tests, move sysinfo suite to test/src

Signed-off-by: Christina Wang <christina@balena.io>
This commit is contained in:
Christina Wang 2021-05-05 12:34:48 +09:00
parent e1cdade9b7
commit 39601473c0
No known key found for this signature in database
GPG Key ID: 7C3ED0230F440835
4 changed files with 69 additions and 56 deletions

View File

@ -77,7 +77,7 @@ export async function getCpuId(): Promise<string | undefined> {
}
}
const undervoltageRegex = /under.*voltage/;
const undervoltageRegex = /under.*voltage/i;
export async function undervoltageDetected(): Promise<boolean> {
try {
const { stdout: dmesgStdout } = await exec('dmesg');
@ -138,6 +138,6 @@ export function isSignificantChange(
return Math.floor(current / bucketSize) !== Math.floor(past / bucketSize);
}
function bytesToMb(bytes: number) {
export function bytesToMb(bytes: number) {
return Math.floor(bytes / 1024 / 1024);
}

View File

@ -1 +0,0 @@
{"foo": "bar"}

Binary file not shown.

View File

@ -1,28 +1,32 @@
import { expect } from 'chai';
import { stub } from 'sinon';
import * as systeminformation from 'systeminformation';
import { SinonStub, stub } from 'sinon';
import { promises as fs } from 'fs';
import * as systeminformation from 'systeminformation';
import * as sysInfo from '../src/lib/system-info';
import * as fsUtils from '../../../src/lib/fs-utils';
import * as sysInfo from '../../../src/lib/system-info';
function toMb(bytes: number) {
return Math.floor(bytes / 1024 / 1024);
}
describe('System information', async () => {
const fsSizeStub = stub(systeminformation, 'fsSize');
const memStub = stub(systeminformation, 'mem');
const currentLoadStub = stub(systeminformation, 'currentLoad');
const cpuTempStub = stub(systeminformation, 'cpuTemperature');
after(() => {
fsSizeStub.restore();
memStub.restore();
currentLoadStub.restore();
cpuTempStub.restore();
describe('System information', () => {
before(() => {
stub(systeminformation, 'fsSize');
stub(systeminformation, 'mem').resolves(mockMemory);
stub(systeminformation, 'currentLoad').resolves(mockCPU.load);
stub(systeminformation, 'cpuTemperature').resolves(mockCPU.temp);
// @ts-ignore TS thinks we can't return a buffer...
stub(fs, 'readFile').resolves(mockCPU.idBuffer);
stub(fsUtils, 'exec');
});
describe('Delta-based filtering', () => {
after(() => {
(systeminformation.fsSize as SinonStub).restore();
(systeminformation.mem as SinonStub).restore();
(systeminformation.currentLoad as SinonStub).restore();
(systeminformation.cpuTemperature as SinonStub).restore();
(fs.readFile as SinonStub).restore();
(fsUtils.exec as SinonStub).restore();
});
describe('filterNonSignificantChanges', () => {
it('should correctly filter cpu usage', () => {
expect(sysInfo.isSignificantChange('cpu_usage', 21, 20)).to.equal(false);
@ -45,7 +49,7 @@ describe('System information', async () => {
);
});
it('should not filter if we didnt have a past value', () => {
it("should not filter if we didn't have a past value", () => {
expect(sysInfo.isSignificantChange('cpu_usage', undefined, 22)).to.equal(
true,
);
@ -60,9 +64,8 @@ describe('System information', async () => {
});
});
describe('CPU information', async () => {
describe('CPU information', () => {
it('gets CPU usage', async () => {
currentLoadStub.resolves(mockCPU.load);
const cpuUsage = await sysInfo.getCpuUsage();
// Make sure it is a whole number
expect(cpuUsage % 1).to.equal(0);
@ -71,7 +74,6 @@ describe('System information', async () => {
});
it('gets CPU temp', async () => {
cpuTempStub.resolves(mockCPU.temp);
const tempInfo = await sysInfo.getCpuTemp();
// Make sure it is a whole number
expect(tempInfo % 1).to.equal(0);
@ -80,41 +82,17 @@ describe('System information', async () => {
});
it('gets CPU ID', async () => {
const fsStub = stub(fs, 'readFile').resolves(
// @ts-ignore TS thinks we can't return a buffer...
Buffer.from([
0x31,
0x30,
0x30,
0x30,
0x30,
0x30,
0x30,
0x30,
0x30,
0x31,
0x62,
0x39,
0x33,
0x66,
0x33,
0x66,
0x00,
]),
);
const cpuId = await sysInfo.getCpuId();
expect(cpuId).to.equal('1000000001b93f3f');
fsStub.restore();
});
});
describe('Memory information', async () => {
describe('getMemoryInformation', async () => {
it('should return the correct value for memory usage', async () => {
memStub.resolves(mockMemory);
const memoryInfo = await sysInfo.getMemoryInformation();
expect(memoryInfo).to.deep.equal({
total: toMb(mockMemory.total),
used: toMb(
total: sysInfo.bytesToMb(mockMemory.total),
used: sysInfo.bytesToMb(
mockMemory.total -
mockMemory.free -
(mockMemory.cached + mockMemory.buffers),
@ -123,9 +101,9 @@ describe('System information', async () => {
});
});
describe('Storage information', async () => {
describe('getStorageInfo', async () => {
it('should return info on /data mount', async () => {
fsSizeStub.resolves(mockFS);
(systeminformation.fsSize as SinonStub).resolves(mockFS);
const storageInfo = await sysInfo.getStorageInfo();
expect(storageInfo).to.deep.equal({
blockDevice: '/dev/mmcblk0p6',
@ -135,7 +113,7 @@ describe('System information', async () => {
});
it('should handle no /data mount', async () => {
fsSizeStub.resolves([]);
(systeminformation.fsSize as SinonStub).resolves([]);
const storageInfo = await sysInfo.getStorageInfo();
expect(storageInfo).to.deep.equal({
blockDevice: '',
@ -144,6 +122,23 @@ describe('System information', async () => {
});
});
});
describe('undervoltageDetected', () => {
it('should detect undervoltage', async () => {
(fsUtils.exec as SinonStub).resolves({
stdout: Buffer.from(
'[58611.126996] Under-voltage detected! (0x00050005)',
),
stderr: Buffer.from(''),
});
expect(await sysInfo.undervoltageDetected()).to.be.true;
(fsUtils.exec as SinonStub).resolves({
stdout: Buffer.from('[569378.450066] eth0: renamed from veth3aa11ca'),
stderr: Buffer.from(''),
});
expect(await sysInfo.undervoltageDetected()).to.be.false;
});
});
});
const mockCPU = {
@ -226,6 +221,25 @@ const mockCPU = {
},
],
},
idBuffer: Buffer.from([
0x31,
0x30,
0x30,
0x30,
0x30,
0x30,
0x30,
0x30,
0x30,
0x31,
0x62,
0x39,
0x33,
0x66,
0x33,
0x66,
0x00,
]),
};
const mockFS = [
{