mirror of
https://github.com/balena-os/balena-supervisor.git
synced 2025-02-01 00:45:23 +00:00
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:
parent
e1cdade9b7
commit
39601473c0
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -1 +0,0 @@
|
|||||||
{"foo": "bar"}
|
|
Binary file not shown.
@ -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 = [
|
||||||
{
|
{
|
Loading…
x
Reference in New Issue
Block a user