import { expect } from 'chai'; import { stub } from 'sinon'; import * as systeminformation from 'systeminformation'; import { fs } from 'mz'; 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('Delta-based filtering', () => { it('should correctly filter cpu usage', () => { expect( sysInfo.filterNonSignificantChanges({ cpu_usage: 21 }, { cpu_usage: 20, } as sysInfo.SystemInfo), ).to.deep.equal(['cpu_usage']); expect( sysInfo.filterNonSignificantChanges({ cpu_usage: 10 }, { cpu_usage: 20, } as sysInfo.SystemInfo), ).to.deep.equal([]); }); it('should correctly filter cpu temperature', () => { expect( sysInfo.filterNonSignificantChanges({ cpu_temp: 21 }, { cpu_temp: 22, } as sysInfo.SystemInfo), ).to.deep.equal(['cpu_temp']); expect( sysInfo.filterNonSignificantChanges({ cpu_temp: 10 }, { cpu_temp: 20, } as sysInfo.SystemInfo), ).to.deep.equal([]); }); it('should correctly filter memory usage', () => { expect( sysInfo.filterNonSignificantChanges({ memory_usage: 21 }, { memory_usage: 22, } as sysInfo.SystemInfo), ).to.deep.equal(['memory_usage']); expect( sysInfo.filterNonSignificantChanges({ memory_usage: 10 }, { memory_usage: 20, } as sysInfo.SystemInfo), ).to.deep.equal([]); }); it('should not filter if we didnt have a past value', () => { expect( sysInfo.filterNonSignificantChanges({}, { memory_usage: 22, cpu_usage: 10, cpu_temp: 5, } as sysInfo.SystemInfo), ).to.deep.equal([]); }); }); describe('CPU information', async () => { 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); // Make sure it's the right number given the mocked data expect(cpuUsage).to.equal(1); }); 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); // Make sure it's the right number given the mocked data expect(tempInfo).to.equal(51); }); 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('1000000001b93f3'); fsStub.restore(); }); }); describe('Memory information', 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( mockMemory.total - mockMemory.free - (mockMemory.cached + mockMemory.buffers), ), }); }); }); describe('Storage information', async () => { it('should return info on /data mount', async () => { fsSizeStub.resolves(mockFS); const storageInfo = await sysInfo.getStorageInfo(); expect(storageInfo).to.deep.equal({ blockDevice: '/dev/mmcblk0p6', storageUsed: 1118, storageTotal: 29023, }); }); it('should handle no /data mount', async () => { fsSizeStub.resolves([]); const storageInfo = await sysInfo.getStorageInfo(); expect(storageInfo).to.deep.equal({ blockDevice: '', storageUsed: undefined, storageTotal: undefined, }); }); }); }); const mockCPU = { temp: { main: 50.634, cores: [], max: 50.634, socket: [], }, load: { avgLoad: 0.6, currentLoad: 1.4602487831260142, currentLoadUser: 0.7301243915630071, currentLoadSystem: 0.7301243915630071, currentLoadNice: 0, currentLoadIdle: 98.53975121687398, currentLoadIrq: 0, rawCurrentLoad: 5400, rawCurrentLoadUser: 2700, rawCurrentLoadSystem: 2700, rawCurrentLoadNice: 0, rawCurrentLoadIdle: 364400, rawCurrentLoadIrq: 0, cpus: [ { load: 1.8660812294182216, loadUser: 0.7683863885839737, loadSystem: 1.0976948408342482, loadNice: 0, loadIdle: 98.13391877058177, loadIrq: 0, rawLoad: 1700, rawLoadUser: 700, rawLoadSystem: 1000, rawLoadNice: 0, rawLoadIdle: 89400, rawLoadIrq: 0, }, { load: 1.7204301075268817, loadUser: 0.8602150537634409, loadSystem: 0.8602150537634409, loadNice: 0, loadIdle: 98.27956989247312, loadIrq: 0, rawLoad: 1600, rawLoadUser: 800, rawLoadSystem: 800, rawLoadNice: 0, rawLoadIdle: 91400, rawLoadIrq: 0, }, { load: 1.186623516720604, loadUser: 0.9708737864077669, loadSystem: 0.2157497303128371, loadNice: 0, loadIdle: 98.8133764832794, loadIrq: 0, rawLoad: 1100, rawLoadUser: 900, rawLoadSystem: 200, rawLoadNice: 0, rawLoadIdle: 91600, rawLoadIrq: 0, }, { load: 1.0752688172043012, loadUser: 0.3225806451612903, loadSystem: 0.7526881720430108, loadNice: 0, loadIdle: 98.9247311827957, loadIrq: 0, rawLoad: 1000, rawLoadUser: 300, rawLoadSystem: 700, rawLoadNice: 0, rawLoadIdle: 92000, rawLoadIrq: 0, }, ], }, }; const mockFS = [ { fs: 'overlay', type: 'overlay', size: 30433308672, used: 1172959232, available: 27684696064, use: 4.06, mount: '/', }, { fs: '/dev/mmcblk0p6', type: 'ext4', size: 30433308672, used: 1172959232, available: 27684696064, use: 4.06, mount: '/data', }, { fs: '/dev/mmcblk0p1', type: 'vfat', size: 41281536, used: 7219200, available: 34062336, use: 17.49, mount: '/boot/config.json', }, { fs: '/dev/disk/by-state/resin-state', type: 'ext4', size: 19254272, used: 403456, available: 17383424, use: 2.27, mount: '/mnt/root/mnt/state', }, { fs: '/dev/disk/by-uuid/ba1eadef-4660-4b03-9e71-9f33257f292c', type: 'ext4', size: 313541632, used: 308860928, available: 0, use: 100, mount: '/mnt/root/mnt/sysroot/active', }, { fs: '/dev/mmcblk0p2', type: 'ext4', size: 313541632, used: 299599872, available: 0, use: 100, mount: '/mnt/root/mnt/sysroot/inactive', }, ]; const mockMemory = { total: 4032724992, free: 2182356992, used: 1850368000, active: 459481088, available: 3573243904, buffers: 186269696, cached: 1055621120, slab: 252219392, buffcache: 1494110208, swaptotal: 2016358400, swapused: 0, swapfree: 2016358400, };