node-os-utils
Version:
Advanced cross-platform operating system monitoring utilities with TypeScript support
307 lines • 15.5 kB
JavaScript
;
/**
* Linux特定的单元测试
* 测试在Linux系统上特有的功能和行为
*/
Object.defineProperty(exports, "__esModule", { value: true });
const chai_1 = require("chai");
const test_base_1 = require("../utils/test-base");
const platform_specific_1 = require("../utils/platform-specific");
const src_1 = require("../../src");
// 只在Linux系统上运行这些测试
describe('Linux System Tests', function () {
before(function () {
if (!test_base_1.PlatformUtils.isLinux()) {
this.skip();
}
});
let osu;
before(function () {
// 使用新版本2.0 API
osu = new src_1.OSUtils();
});
after(function () {
// 清理资源,防止测试卡死
if (osu) {
osu.destroy();
}
});
describe('Linux CPU Module', function () {
describe('#info()', function () {
it('应该能够从/proc/cpuinfo读取CPU信息', (0, test_base_1.asyncTest)(async function () {
const result = await osu.cpu.info();
(0, chai_1.expect)(result.success).to.be.true;
if (result.success) {
(0, chai_1.expect)(result.data).to.exist;
(0, chai_1.expect)(result.data.model).to.be.a('string');
(0, chai_1.expect)(result.data.cores).to.be.a('number').and.greaterThan(0);
(0, chai_1.expect)(result.data.threads).to.be.a('number').and.greaterThan(0);
}
}));
});
describe('#loadAverage()', function () {
it('应该能够正确读取Linux的负载平均值', (0, test_base_1.asyncTest)(async function () {
const result = await osu.cpu.loadAverage();
(0, chai_1.expect)(result.success).to.be.true;
if (result.success) {
(0, chai_1.expect)(result.data).to.exist;
(0, chai_1.expect)(result.data.load1).to.be.a('number').and.at.least(0);
(0, chai_1.expect)(result.data.load5).to.be.a('number').and.at.least(0);
(0, chai_1.expect)(result.data.load15).to.be.a('number').and.at.least(0);
}
}));
it('应该与/proc/loadavg文件内容一致', (0, test_base_1.asyncTest)(async function () {
if (!platform_specific_1.LinuxTestUtils.canAccessProc()) {
this.skip();
}
const result = await osu.cpu.loadAverage();
if (!result.success) {
this.skip();
}
// 读取 /proc/loadavg 进行对比
const fs = require('fs');
try {
const procLoadavg = fs.readFileSync('/proc/loadavg', 'utf8').trim().split(' ');
const procLoads = [
parseFloat(procLoadavg[0]),
parseFloat(procLoadavg[1]),
parseFloat(procLoadavg[2])
];
if (result.success) {
(0, chai_1.expect)(Math.abs(result.data.load1 - procLoads[0])).to.be.below(0.01);
(0, chai_1.expect)(Math.abs(result.data.load5 - procLoads[1])).to.be.below(0.01);
(0, chai_1.expect)(Math.abs(result.data.load15 - procLoads[2])).to.be.below(0.01);
}
}
catch (error) {
this.skip();
}
}));
});
describe('#usage()', function () {
it('应该能够从/proc/stat获取CPU使用率', (0, test_base_1.asyncTest)(async function () {
const result = await osu.cpu.usage();
if (!result.success) {
this.skip();
}
if (result.success) {
(0, chai_1.expect)(result.data).to.be.a('number');
(0, chai_1.expect)(result.data).to.be.at.least(0);
(0, chai_1.expect)(result.data).to.be.at.most(100);
}
}));
});
});
describe('Linux Memory Module', function () {
describe('#info()', function () {
it('应该能够从/proc/meminfo读取内存信息', (0, test_base_1.asyncTest)(async function () {
const result = await osu.memory.info();
(0, chai_1.expect)(result.success).to.be.true;
if (result.success) {
(0, chai_1.expect)(result.data).to.exist;
(0, chai_1.expect)(result.data.total).to.exist;
(0, chai_1.expect)(result.data.total.bytes).to.be.a('number').and.greaterThan(0);
(0, chai_1.expect)(result.data.available).to.exist;
(0, chai_1.expect)(result.data.used).to.exist;
}
}));
it('内存信息应该与/proc/meminfo一致', (0, test_base_1.asyncTest)(async function () {
if (!platform_specific_1.LinuxTestUtils.canAccessProc()) {
this.skip();
}
const result = await osu.memory.info();
if (!result.success) {
this.skip();
}
// 读取 /proc/meminfo 进行对比
const fs = require('fs');
try {
const procMeminfo = fs.readFileSync('/proc/meminfo', 'utf8');
const memTotalMatch = procMeminfo.match(/MemTotal:\s+(\d+)\s+kB/);
if (memTotalMatch) {
const procTotal = parseInt(memTotalMatch[1]) * 1024; // 转换为字节
const tolerance = 0.01; // 1%的误差
if (result.success) {
const ratio = Math.abs(result.data.total.bytes - procTotal) / procTotal;
(0, chai_1.expect)(ratio).to.be.below(tolerance);
}
}
}
catch (error) {
this.skip();
}
}));
});
describe('#usage()', function () {
it('Linux系统的空闲和已用内存信息应该准确', (0, test_base_1.asyncTest)(async function () {
const result = await osu.memory.usage();
if (!result.success) {
this.skip();
}
if (result.success) {
(0, chai_1.expect)(result.data).to.be.a('number');
(0, chai_1.expect)(result.data).to.be.at.least(0);
(0, chai_1.expect)(result.data).to.be.at.most(100);
}
}));
});
});
describe('Linux Disk Module', function () {
describe('#info()', function () {
it('应该能够使用df命令获取磁盘信息', (0, test_base_1.asyncTest)(async function () {
const result = await osu.disk.info();
(0, chai_1.expect)(result.success).to.be.true;
if (result.success) {
(0, chai_1.expect)(result.data).to.be.an('array');
if (result.data.length > 0) {
const disk = result.data[0];
(0, chai_1.expect)(disk.filesystem).to.be.a('string');
(0, chai_1.expect)(disk.total).to.exist;
(0, chai_1.expect)(disk.used).to.exist;
(0, chai_1.expect)(disk.available).to.exist;
(0, chai_1.expect)(disk.usagePercentage).to.be.a('number');
}
}
}));
it('应该支持指定挂载点', (0, test_base_1.asyncTest)(async function () {
const result = await osu.disk.info(); // Remove parameter since method doesn't accept it
if (!result.success) {
this.skip();
}
if (result.success) {
(0, chai_1.expect)(result.data).to.be.an('array');
(0, chai_1.expect)(result.data.length).to.be.at.least(1);
const rootDisk = result.data.find(d => d.mountpoint === '/');
(0, chai_1.expect)(rootDisk).to.exist;
}
}));
it('应该能够处理多个文件系统', (0, test_base_1.asyncTest)(async function () {
const result = await osu.disk.info();
(0, chai_1.expect)(result.success).to.be.true;
if (result.success) {
(0, chai_1.expect)(result.data).to.be.an('array');
// Linux 系统通常有多个挂载点
const mountPoints = result.data.map(d => d.mountpoint);
(0, chai_1.expect)(mountPoints).to.include('/');
}
}));
});
});
describe('Linux Network Module', function () {
describe('#interfaces()', function () {
it('应该能够从/proc/net/dev读取网络统计', (0, test_base_1.asyncTest)(async function () {
const result = await osu.network.interfaces();
(0, chai_1.expect)(result.success).to.be.true;
if (result.success) {
(0, chai_1.expect)(result.data).to.be.an('array');
if (result.data.length > 0) {
const iface = result.data[0];
(0, chai_1.expect)(iface.name).to.be.a('string');
(0, chai_1.expect)(iface.addresses).to.exist;
(0, chai_1.expect)(iface.mac).to.be.a('string');
}
}
}));
it('网络统计应该包含常见的Linux网络接口', (0, test_base_1.asyncTest)(async function () {
const result = await osu.network.interfaces();
if (!result.success || result.data.length === 0) {
this.skip();
}
if (result.success) {
const interfaceNames = result.data.map(i => i.name);
const commonLinuxInterfaces = ['lo', 'eth0', 'wlan0', 'enp0s3', 'docker0'];
// 应该至少包含本地回环接口
(0, chai_1.expect)(interfaceNames.some(name => name === 'lo')).to.be.true;
}
}));
});
describe('#overview()', function () {
it('应该能够计算网络流量差值', (0, test_base_1.asyncTest)(async function () {
const result = await osu.network.overview();
if (!result.success) {
this.skip();
}
if (result.success) {
(0, chai_1.expect)(result.data).to.exist;
(0, chai_1.expect)(result.data.totalRxBytes).to.exist;
(0, chai_1.expect)(result.data.totalTxBytes).to.exist;
(0, chai_1.expect)(result.data.totalRxBytes.bytes).to.be.a('number').and.at.least(0);
(0, chai_1.expect)(result.data.totalTxBytes.bytes).to.be.a('number').and.at.least(0);
}
}));
});
});
describe('Linux System Commands', function () {
it('应该能够访问Linux特有的系统命令', (0, test_base_1.asyncTest)(async function () {
const result = await osu.system.info();
(0, chai_1.expect)(result.success).to.be.true;
if (result.success) {
(0, chai_1.expect)(result.data).to.exist;
(0, chai_1.expect)(result.data.platform).to.equal('linux');
}
}));
it('应该能够访问/proc文件系统', (0, test_base_1.asyncTest)(async function () {
if (!platform_specific_1.LinuxTestUtils.canAccessProc()) {
this.skip();
}
const result = await osu.system.info();
(0, chai_1.expect)(result.success).to.be.true;
if (result.success) {
(0, chai_1.expect)(result.data.hostname).to.be.a('string');
}
}));
});
describe('Linux Performance Tests', function () {
it('Linux系统调用应该在合理时间内完成', (0, test_base_1.longTest)(async function () {
const monitor = new test_base_1.PerformanceMonitor();
await monitor.time('cpu-info', () => osu.cpu.info());
await monitor.time('memory-info', () => osu.memory.info());
await monitor.time('disk-info', () => osu.disk.info());
const report = monitor.getReport();
// Linux 系统调用应该在合理时间内完成
(0, chai_1.expect)(report['cpu-info']).to.be.below(1000, 'CPU info should complete within 1s');
(0, chai_1.expect)(report['memory-info']).to.be.below(1000, 'Memory info should complete within 1s');
(0, chai_1.expect)(report['disk-info']).to.be.below(2000, 'Disk info should complete within 2s');
}));
it('重复调用不应该影响系统性能', (0, test_base_1.longTest)(async function () {
const iterations = 10;
const monitor = new test_base_1.PerformanceMonitor();
for (let i = 0; i < iterations; i++) {
await monitor.time(`cpu-usage-${i}`, () => osu.cpu.usage());
}
const times = Array.from({ length: iterations }, (_, i) => monitor.getReport()[`cpu-usage-${i}`]);
const avgTime = times.reduce((sum, time) => sum + time, 0) / times.length;
const maxTime = Math.max(...times);
// 如果平均时间为0或非常小,检查所有时间都应该在合理范围内(<100ms)
if (avgTime < 1) {
(0, chai_1.expect)(maxTime).to.be.below(100, 'Even with caching, operations should complete within 100ms');
}
else {
// 最大时间不应该超过平均时间的3倍
(0, chai_1.expect)(maxTime).to.be.below(avgTime * 3, `Max time (${maxTime}ms) should not exceed 3x average time (${avgTime}ms)`);
}
}));
});
describe('Linux Error Handling', function () {
it('应该正确处理权限不足的情况', (0, test_base_1.asyncTest)(async function () {
// 尝试访问需要特殊权限的功能
const result = await osu.process.list();
if (!result.success) {
(0, chai_1.expect)(result.error).to.exist;
(0, chai_1.expect)(result.error.code).to.be.oneOf(['PERMISSION_DENIED', 'NOT_SUPPORTED']);
}
}));
it('应该处理不存在的挂载点', (0, test_base_1.asyncTest)(async function () {
const result = await osu.disk.info(); // Remove parameter since method doesn't accept it
if (!result.success) {
(0, chai_1.expect)(result.error).to.exist;
(0, chai_1.expect)(result.error.code).to.be.oneOf(['NOT_FOUND', 'INVALID_PATH']);
}
else {
// 如果没有错误,应该返回空数组或者忽略不存在的路径
(0, chai_1.expect)(result.data).to.be.an('array');
}
}));
});
});
//# sourceMappingURL=linux.test.js.map