UNPKG

node-os-utils

Version:

Advanced cross-platform operating system monitoring utilities with TypeScript support

307 lines 15.5 kB
"use strict"; /** * 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