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> { export async function undervoltageDetected(): Promise<boolean> {
try { try {
const { stdout: dmesgStdout } = await exec('dmesg'); const { stdout: dmesgStdout } = await exec('dmesg');
@ -138,6 +138,6 @@ export function isSignificantChange(
return Math.floor(current / bucketSize) !== Math.floor(past / bucketSize); return Math.floor(current / bucketSize) !== Math.floor(past / bucketSize);
} }
function bytesToMb(bytes: number) { export function bytesToMb(bytes: number) {
return Math.floor(bytes / 1024 / 1024); 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 { expect } from 'chai';
import { stub } from 'sinon'; import { SinonStub, stub } from 'sinon';
import * as systeminformation from 'systeminformation';
import { promises as fs } from 'fs'; 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) { describe('System information', () => {
return Math.floor(bytes / 1024 / 1024); before(() => {
} stub(systeminformation, 'fsSize');
stub(systeminformation, 'mem').resolves(mockMemory);
describe('System information', async () => { stub(systeminformation, 'currentLoad').resolves(mockCPU.load);
const fsSizeStub = stub(systeminformation, 'fsSize'); stub(systeminformation, 'cpuTemperature').resolves(mockCPU.temp);
const memStub = stub(systeminformation, 'mem'); // @ts-ignore TS thinks we can't return a buffer...
const currentLoadStub = stub(systeminformation, 'currentLoad'); stub(fs, 'readFile').resolves(mockCPU.idBuffer);
const cpuTempStub = stub(systeminformation, 'cpuTemperature'); stub(fsUtils, 'exec');
after(() => {
fsSizeStub.restore();
memStub.restore();
currentLoadStub.restore();
cpuTempStub.restore();
}); });
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', () => { it('should correctly filter cpu usage', () => {
expect(sysInfo.isSignificantChange('cpu_usage', 21, 20)).to.equal(false); 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( expect(sysInfo.isSignificantChange('cpu_usage', undefined, 22)).to.equal(
true, true,
); );
@ -60,9 +64,8 @@ describe('System information', async () => {
}); });
}); });
describe('CPU information', async () => { describe('CPU information', () => {
it('gets CPU usage', async () => { it('gets CPU usage', async () => {
currentLoadStub.resolves(mockCPU.load);
const cpuUsage = await sysInfo.getCpuUsage(); const cpuUsage = await sysInfo.getCpuUsage();
// Make sure it is a whole number // Make sure it is a whole number
expect(cpuUsage % 1).to.equal(0); expect(cpuUsage % 1).to.equal(0);
@ -71,7 +74,6 @@ describe('System information', async () => {
}); });
it('gets CPU temp', async () => { it('gets CPU temp', async () => {
cpuTempStub.resolves(mockCPU.temp);
const tempInfo = await sysInfo.getCpuTemp(); const tempInfo = await sysInfo.getCpuTemp();
// Make sure it is a whole number // Make sure it is a whole number
expect(tempInfo % 1).to.equal(0); expect(tempInfo % 1).to.equal(0);
@ -80,41 +82,17 @@ describe('System information', async () => {
}); });
it('gets CPU ID', 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(); const cpuId = await sysInfo.getCpuId();
expect(cpuId).to.equal('1000000001b93f3f'); expect(cpuId).to.equal('1000000001b93f3f');
fsStub.restore();
}); });
}); });
describe('Memory information', async () => { describe('getMemoryInformation', async () => {
it('should return the correct value for memory usage', async () => { it('should return the correct value for memory usage', async () => {
memStub.resolves(mockMemory);
const memoryInfo = await sysInfo.getMemoryInformation(); const memoryInfo = await sysInfo.getMemoryInformation();
expect(memoryInfo).to.deep.equal({ expect(memoryInfo).to.deep.equal({
total: toMb(mockMemory.total), total: sysInfo.bytesToMb(mockMemory.total),
used: toMb( used: sysInfo.bytesToMb(
mockMemory.total - mockMemory.total -
mockMemory.free - mockMemory.free -
(mockMemory.cached + mockMemory.buffers), (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 () => { it('should return info on /data mount', async () => {
fsSizeStub.resolves(mockFS); (systeminformation.fsSize as SinonStub).resolves(mockFS);
const storageInfo = await sysInfo.getStorageInfo(); const storageInfo = await sysInfo.getStorageInfo();
expect(storageInfo).to.deep.equal({ expect(storageInfo).to.deep.equal({
blockDevice: '/dev/mmcblk0p6', blockDevice: '/dev/mmcblk0p6',
@ -135,7 +113,7 @@ describe('System information', async () => {
}); });
it('should handle no /data mount', async () => { it('should handle no /data mount', async () => {
fsSizeStub.resolves([]); (systeminformation.fsSize as SinonStub).resolves([]);
const storageInfo = await sysInfo.getStorageInfo(); const storageInfo = await sysInfo.getStorageInfo();
expect(storageInfo).to.deep.equal({ expect(storageInfo).to.deep.equal({
blockDevice: '', 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 = { 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 = [ const mockFS = [
{ {