Add advanced monitoring and release infrastructure
This commit is contained in:
@@ -1,7 +1,195 @@
|
||||
import XCTest
|
||||
import PuterHelperProtocol
|
||||
@testable import puter
|
||||
|
||||
final class ModelTests: XCTestCase {
|
||||
func testNativeProcessSamplerPerformanceBudget() {
|
||||
let result = ProcessSamplerBenchmark.run(iterations: 6)
|
||||
XCTAssertGreaterThan(result.processCount, 20, "Native telemetry should return a credible process inventory")
|
||||
XCTAssertLessThan(
|
||||
result.averageSeconds,
|
||||
0.5,
|
||||
"The native hot path should remain comfortably below the foreground sampling interval"
|
||||
)
|
||||
let lightweight = ProcessSamplerBenchmark.run(iterations: 12, includeProcessInventory: false)
|
||||
print(
|
||||
String(
|
||||
format: "Sampler benchmark: full %.4f s, lightweight %.4f s per iteration",
|
||||
result.averageSeconds,
|
||||
lightweight.averageSeconds
|
||||
)
|
||||
)
|
||||
XCTAssertEqual(lightweight.processCount, 0)
|
||||
XCTAssertLessThan(
|
||||
lightweight.averageSeconds,
|
||||
result.averageSeconds,
|
||||
"Lightweight system telemetry must remain cheaper than enumerating every process"
|
||||
)
|
||||
}
|
||||
|
||||
func testOnlyProcessConsumerPagesUseLiveInventory() {
|
||||
XCTAssertTrue(TaskSection.processes.usesLiveProcessInventory)
|
||||
XCTAssertTrue(TaskSection.performance.usesLiveProcessInventory)
|
||||
XCTAssertTrue(TaskSection.energy.usesLiveProcessInventory)
|
||||
XCTAssertTrue(TaskSection.diagnostics.usesLiveProcessInventory)
|
||||
XCTAssertFalse(TaskSection.hardware.usesLiveProcessInventory)
|
||||
XCTAssertFalse(TaskSection.startup.usesLiveProcessInventory)
|
||||
XCTAssertFalse(TaskSection.services.usesLiveProcessInventory)
|
||||
XCTAssertFalse(TaskSection.settings.usesLiveProcessInventory)
|
||||
}
|
||||
|
||||
func testProcessHeaderCyclesDescendingAscendingThenGrouped() {
|
||||
let descending = ProcessSortCycleState.next(
|
||||
currentField: .name, ascending: true, grouped: true, clicked: .cpu
|
||||
)
|
||||
XCTAssertEqual(descending, .init(field: .cpu, ascending: false, grouped: false))
|
||||
let ascending = ProcessSortCycleState.next(
|
||||
currentField: descending.field, ascending: descending.ascending,
|
||||
grouped: descending.grouped, clicked: .cpu
|
||||
)
|
||||
XCTAssertEqual(ascending, .init(field: .cpu, ascending: true, grouped: false))
|
||||
let grouped = ProcessSortCycleState.next(
|
||||
currentField: ascending.field, ascending: ascending.ascending,
|
||||
grouped: ascending.grouped, clicked: .cpu
|
||||
)
|
||||
XCTAssertEqual(grouped, .init(field: .cpu, ascending: true, grouped: true))
|
||||
XCTAssertEqual(descending.accessibilityValue(for: .cpu), "Sorted descending")
|
||||
XCTAssertEqual(ascending.accessibilityValue(for: .cpu), "Sorted ascending")
|
||||
XCTAssertEqual(grouped.accessibilityValue(for: .cpu), "Not sorted; grouped by category")
|
||||
XCTAssertEqual(descending.accessibilityValue(for: .memory), "Not sorted; grouped by category")
|
||||
}
|
||||
|
||||
func testPrivilegedHelperRejectsUnsafeFanTargets() {
|
||||
XCTAssertEqual(PuterFanTargetValidator.validate([0: 2_000, 1: 4_500])?.count, 2)
|
||||
XCTAssertNil(PuterFanTargetValidator.validate([16: 2_000]))
|
||||
XCTAssertNil(PuterFanTargetValidator.validate([0: 20_001]))
|
||||
XCTAssertNil(PuterFanTargetValidator.validate([:] as [NSNumber: NSNumber]))
|
||||
}
|
||||
|
||||
func testBackgroundTaskRegistryParsesAndDeduplicatesLoginApps() {
|
||||
let fixture = """
|
||||
#1:
|
||||
Name: Example App
|
||||
Developer Name: Example Corp
|
||||
Type: app (0x2)
|
||||
Disposition: [disabled, allowed, notified] (0xa)
|
||||
URL: file:///Applications/Example%20App.app/
|
||||
Bundle Identifier: com.example.app
|
||||
|
||||
#2:
|
||||
Name: Example App
|
||||
Developer Name: Example Corp
|
||||
Type: app (0x2)
|
||||
Disposition: [enabled, allowed, notified] (0xb)
|
||||
URL: file:///Applications/Example%20App.app/
|
||||
Bundle Identifier: com.example.app
|
||||
|
||||
#3:
|
||||
Name: Background Daemon
|
||||
Type: daemon (0x10)
|
||||
Disposition: [enabled, allowed, notified] (0xb)
|
||||
URL: file:///Library/LaunchDaemons/com.example.daemon.plist
|
||||
"""
|
||||
let items = BackgroundTaskRegistryParser.parse(fixture)
|
||||
XCTAssertEqual(items.count, 1)
|
||||
XCTAssertEqual(items[0].name, "Example App")
|
||||
XCTAssertEqual(items[0].developer, "Example Corp")
|
||||
XCTAssertEqual(items[0].bundleIdentifier, "com.example.app")
|
||||
XCTAssertEqual(items[0].path, "/Applications/Example App.app")
|
||||
XCTAssertTrue(items[0].enabled)
|
||||
}
|
||||
|
||||
func testOnlySleepRelatedAssertionsAreBlockers() {
|
||||
let blocker = SleepAssertionSnapshot(
|
||||
id: "1", pid: 42, processName: "Video", type: "NoIdleSleepAssertion", reason: "Playback", duration: "00:01:00"
|
||||
)
|
||||
let activity = SleepAssertionSnapshot(
|
||||
id: "2", pid: 43, processName: "WindowServer", type: "UserIsActive", reason: "Input", duration: "00:00:01"
|
||||
)
|
||||
XCTAssertTrue(blocker.preventsSleep)
|
||||
XCTAssertFalse(activity.preventsSleep)
|
||||
}
|
||||
|
||||
func testResourceAlertsRequireSustainedSamplesAndCooldown() {
|
||||
let now = Date(timeIntervalSince1970: 1_000)
|
||||
XCTAssertFalse(ResourceAlertPolicy.shouldFire(
|
||||
value: 95, threshold: 90, consecutiveSamples: 2, requiredSamples: 3,
|
||||
lastFired: nil, now: now, cooldown: 300
|
||||
))
|
||||
XCTAssertTrue(ResourceAlertPolicy.shouldFire(
|
||||
value: 95, threshold: 90, consecutiveSamples: 3, requiredSamples: 3,
|
||||
lastFired: nil, now: now, cooldown: 300
|
||||
))
|
||||
XCTAssertFalse(ResourceAlertPolicy.shouldFire(
|
||||
value: 95, threshold: 90, consecutiveSamples: 4, requiredSamples: 3,
|
||||
lastFired: now.addingTimeInterval(-299), now: now, cooldown: 300
|
||||
))
|
||||
XCTAssertTrue(ResourceAlertPolicy.shouldFire(
|
||||
value: 95, threshold: 90, consecutiveSamples: 4, requiredSamples: 3,
|
||||
lastFired: now.addingTimeInterval(-300), now: now, cooldown: 300
|
||||
))
|
||||
}
|
||||
|
||||
func testTelemetryRecordingSampleRoundTripsThroughJSON() throws {
|
||||
let sample = TelemetryRecordingSample(
|
||||
timestamp: Date(timeIntervalSince1970: 123), cpuPercent: 12.5,
|
||||
memoryUsedBytes: 1_000, memoryTotalBytes: 2_000, memoryPressure: "Normal",
|
||||
diskReadBytesPerSecond: 10, diskWriteBytesPerSecond: 20, gpuPercent: 30,
|
||||
networkReceiveBytesPerSecond: 40, networkSendBytesPerSecond: 50,
|
||||
systemPowerWatts: 6.5, thermalState: "Nominal", processCount: 100
|
||||
)
|
||||
XCTAssertEqual(try JSONDecoder().decode(TelemetryRecordingSample.self, from: JSONEncoder().encode(sample)), sample)
|
||||
}
|
||||
|
||||
func testDiagnosticCaptureRoundTripsThroughJSON() throws {
|
||||
let capture = DiagnosticCapture(
|
||||
id: UUID(), name: "Baseline", createdAt: Date(timeIntervalSince1970: 100),
|
||||
system: DiagnosticSystemMetrics(
|
||||
cpuPercent: 10, memoryUsedBytes: 100, memoryTotalBytes: 200, memoryPressure: "Normal",
|
||||
compressedBytes: 5, swapUsedBytes: 0, diskReadBytesPerSecond: 1,
|
||||
diskWriteBytesPerSecond: 2, diskActivePercent: 3, gpuPercent: 4,
|
||||
networkReceiveBytesPerSecond: 5, networkSendBytesPerSecond: 6,
|
||||
systemPowerWatts: 7, thermalState: "Nominal", processCount: 8,
|
||||
threadCount: 9, uptimeSeconds: 10
|
||||
),
|
||||
processes: [], disks: []
|
||||
)
|
||||
XCTAssertEqual(try JSONDecoder().decode(DiagnosticCapture.self, from: JSONEncoder().encode(capture)), capture)
|
||||
}
|
||||
|
||||
func testSystemExecutableHasAValidCodeSignature() {
|
||||
let security = ProcessSecurityInspector.inspect(executablePath: "/bin/ls")
|
||||
XCTAssertEqual(security.signatureStatus, "Valid")
|
||||
XCTAssertNotEqual(security.signingIdentifier, "Not reported")
|
||||
}
|
||||
|
||||
func testPhysicalDiskRemainingLifeIsDerivedFromPercentageUsed() {
|
||||
let disk = PhysicalDiskSnapshot(
|
||||
id: "disk0", name: "SSD", protocolName: "NVMe", capacity: 1_000,
|
||||
isInternal: true, isRemovable: false, isSolidState: true, smartStatus: "Verified",
|
||||
trimEnabled: true, temperatureCelsius: 39, percentageUsed: 5, availableSparePercent: 100,
|
||||
powerOnHours: 10, powerCycles: 2, unsafeShutdowns: 0, mediaErrors: 0,
|
||||
bytesRead: 100, bytesWritten: 200
|
||||
)
|
||||
XCTAssertEqual(disk.remainingLifePercent, 95)
|
||||
}
|
||||
|
||||
func testDiskActivityExcludesVirtualDiskImages() {
|
||||
XCTAssertTrue(DiskMediaClassifier.isPhysicalMediaName("APPLE SSD AP1024Z Media"))
|
||||
XCTAssertTrue(DiskMediaClassifier.isPhysicalMediaName("External USB SSD Media"))
|
||||
XCTAssertFalse(DiskMediaClassifier.isPhysicalMediaName("Apple Disk Image Media"))
|
||||
XCTAssertFalse(DiskMediaClassifier.isPhysicalMediaName("RAM Disk Media"))
|
||||
XCTAssertFalse(DiskMediaClassifier.isPhysicalMediaName(""))
|
||||
}
|
||||
|
||||
func testPhysicalDiskScannerFindsAttachedStorage() {
|
||||
let disks = PhysicalDiskScanner.capture()
|
||||
XCTAssertFalse(disks.isEmpty)
|
||||
XCTAssertTrue(disks.allSatisfy { !$0.id.isEmpty && $0.capacity > 0 })
|
||||
XCTAssertTrue(disks.compactMap(\.percentageUsed).allSatisfy { $0 == $0.rounded() && (0...100).contains($0) })
|
||||
XCTAssertTrue(disks.compactMap(\.availableSparePercent).allSatisfy { $0 == $0.rounded() && (0...100).contains($0) })
|
||||
}
|
||||
|
||||
func testAppleSystemServicePublisherAndDomainIdentity() {
|
||||
let system = ServiceRecord(label: "com.apple.accessoryd", pid: 7750, lastExitStatus: 0, domain: .system)
|
||||
let user = ServiceRecord(label: "com.apple.accessoryd", pid: 731, lastExitStatus: 0, domain: .user)
|
||||
@@ -64,6 +252,22 @@ final class ModelTests: XCTestCase {
|
||||
XCTAssertEqual(corrupt.batteryPowerWatts, 0)
|
||||
}
|
||||
|
||||
func testLiveSMCPowerSensorsOverrideCalculatedBatteryPower() {
|
||||
let parsed = SMCPowerSensorParser.parse("""
|
||||
[PDTR] 42.33818435668945
|
||||
[PPBR] 23.479623794555664
|
||||
[PSTR] 66.0309829711914
|
||||
""")
|
||||
XCTAssertEqual(parsed.systemWatts, 66.0309829711914, accuracy: 0.0001)
|
||||
XCTAssertEqual(parsed.adapterWatts, 42.33818435668945, accuracy: 0.0001)
|
||||
XCTAssertEqual(parsed.batteryWatts, 23.479623794555664, accuracy: 0.0001)
|
||||
let battery = BatterySnapshot(
|
||||
voltageVolts: 12, currentAmps: 1,
|
||||
sensorBatteryPowerWatts: parsed.batteryWatts
|
||||
)
|
||||
XCTAssertEqual(battery.batteryPowerWatts, parsed.batteryWatts, accuracy: 0.0001)
|
||||
}
|
||||
|
||||
func testUSBPDProfileAndNegotiatedPower() {
|
||||
let profile = PowerProfile(voltageVolts: 20, currentAmps: 4.29)
|
||||
let adapter = PowerAdapterSnapshot(
|
||||
|
||||
Reference in New Issue
Block a user