74 lines
3.3 KiB
Swift
74 lines
3.3 KiB
Swift
import Foundation
|
|
import Testing
|
|
@testable import Metrics
|
|
|
|
@Suite struct PowerSamplerTests {
|
|
private func table(_ values: [UInt32]) -> Data {
|
|
var data = Data()
|
|
for value in values {
|
|
withUnsafeBytes(of: value.littleEndian) { data.append(contentsOf: $0) }
|
|
withUnsafeBytes(of: UInt32(800).littleEndian) { data.append(contentsOf: $0) }
|
|
}
|
|
return data
|
|
}
|
|
|
|
@Test func parsesTablesInHertzAndMegahertz() {
|
|
#expect(PowerSampler.parseFrequencyTable(table([600_000_000, 1_200_000_000, 3_200_000_000])) == [600, 1200, 3200])
|
|
#expect(PowerSampler.parseFrequencyTable(table([1308, 2292, 4608])) == [1308, 2292, 4608])
|
|
// 第一项为 0 的是 GPU 等模块的表
|
|
#expect(PowerSampler.parseFrequencyTable(table([0, 338_000, 1_620_000])) == nil)
|
|
#expect(PowerSampler.parseFrequencyTable(Data([1, 2, 3])) == nil)
|
|
}
|
|
|
|
@Test func recognizesComplexChannels() {
|
|
#expect(PowerSampler.complexLetter("ECPU") == "E")
|
|
#expect(PowerSampler.complexLetter("PCPU") == "P")
|
|
#expect(PowerSampler.complexLetter("MCPU1") == "M")
|
|
#expect(PowerSampler.complexLetter("PCPM") == nil)
|
|
#expect(PowerSampler.complexLetter("MCPM0_IDLE") == nil)
|
|
}
|
|
|
|
@Test func weightsFrequencyByResidencyAndOrdersClusters() {
|
|
let tables: [[Double]] = [[600, 1000, 2000], [1000, 2000, 3000, 4000]]
|
|
let efficiency = PowerSampler.ComplexResidency(letter: "E", states: [("IDLE", 900), ("V0P2", 50), ("V1P1", 0), ("V2P0", 50)])
|
|
let performance = PowerSampler.ComplexResidency(letter: "P", states: [("DOWN", 10), ("IDLE", 10), ("V0P3", 0), ("V1P2", 0), ("V2P1", 0), ("V3P0", 100)])
|
|
let result = PowerSampler.clusterFrequencies([efficiency, performance], tables: tables, perfLevels: 2)
|
|
#expect(result[0] == 4000)
|
|
#expect(result[1] == 1300)
|
|
// 核心组数与 perflevel 数对不上时不猜
|
|
#expect(PowerSampler.clusterFrequencies([efficiency], tables: tables, perfLevels: 2).isEmpty)
|
|
}
|
|
|
|
@Test func convertsEnergyUnits() {
|
|
#expect(PowerSampler.joulesPerUnit("nJ") == 1e-9)
|
|
#expect(PowerSampler.joulesPerUnit("mJ") == 1e-3)
|
|
}
|
|
}
|
|
|
|
@Suite struct DiskSamplerTests {
|
|
@Test func parsesNVMeHealthLog() throws {
|
|
var log = [UInt8](repeating: 0, count: 512)
|
|
log[0] = 0
|
|
log[1] = 0x3B; log[2] = 0x01 // 315 K ≈ 41.85 °C
|
|
log[3] = 100; log[4] = 10; log[5] = 3
|
|
log[48] = 0x10; log[49] = 0x27 // 写入 10000 个数据单位
|
|
log[128] = 0xE8; log[129] = 0x03 // 通电 1000 小时
|
|
log[144] = 5
|
|
let health = try #require(DiskHealthReader.parse(log, model: "SSD"))
|
|
#expect(health.percentageUsed == 3)
|
|
#expect(health.remainingLife == 97)
|
|
#expect(health.bytesWritten == 10_000 * 512 * 1000)
|
|
#expect(health.powerOnHours == 1000)
|
|
#expect(health.unsafeShutdowns == 5)
|
|
#expect(abs((health.temperature ?? 0) - 41.85) < 0.01)
|
|
#expect(DiskHealthReader.parse([1, 2, 3], model: "SSD") == nil)
|
|
}
|
|
|
|
@Test func activityNeedsTwoSamples() {
|
|
var sampler = DiskActivitySampler()
|
|
#expect(sampler.sample(now: Date()) == nil)
|
|
let second = sampler.sample(now: Date().addingTimeInterval(1))
|
|
#expect(second.map { $0.readRate >= 0 && $0.writeRate >= 0 } ?? true)
|
|
}
|
|
}
|