Files
soconnor 0da94715be
Build and test / macos (push) Canceled after 0s
Signed release / release (push) Canceled after 0s
Add advanced monitoring and release infrastructure
2026-08-15 18:23:35 -04:00

304 lines
14 KiB
Swift

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)
XCTAssertEqual(system.publisher, "Apple")
XCTAssertEqual(system.domain.launchctlPrefix, "system")
XCTAssertFalse(system.isControllable)
XCTAssertTrue(user.isControllable)
XCTAssertNotEqual(system.id, user.id)
}
func testThirdPartyApplicationServicePublisher() {
let service = ServiceRecord(
label: "application.com.adobe.AdobeResourceSynchronizer.210006977.210006983",
pid: 938,
lastExitStatus: 0,
domain: .user
)
XCTAssertEqual(service.publisher, "Adobe")
XCTAssertEqual(service.displayName, "AdobeResourceSynchronizer")
}
func testProcessDisplayNameFallback() {
let process = ProcessRecord(
pid: 42,
parentPID: 1,
name: " ",
executablePath: "/usr/bin/example",
user: "tester",
cpu: 0,
memoryPercent: 0,
residentBytes: 0,
state: "S",
elapsed: "00:01",
cpuTime: 0,
threadCount: 1,
openFileCount: 0,
architecture: "ARM64",
priority: 31,
nice: 0
)
XCTAssertEqual(process.displayName, "Process 42")
}
func testAllNavigationSectionsHaveIcons() {
XCTAssertEqual(Set(TaskSection.allCases.map(\.rawValue)).count, TaskSection.allCases.count)
XCTAssertTrue(TaskSection.allCases.allSatisfy { !$0.icon.isEmpty })
}
func testBatteryHealthUsesFullChargeAndDesignCapacity() {
let battery = BatterySnapshot(fullChargeCapacityMAh: 5_761, designCapacityMAh: 6_249)
XCTAssertEqual(battery.healthPercent, 92.19, accuracy: 0.01)
}
func testBatteryPowerRejectsCorruptTelemetry() {
let normal = BatterySnapshot(voltageVolts: 12.1, currentAmps: -2.5)
let corrupt = BatterySnapshot(voltageVolts: 12.1, currentAmps: Double(UInt64.max))
XCTAssertEqual(normal.batteryPowerWatts, 30.25, accuracy: 0.001)
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(
ratedWatts: 86,
negotiatedVoltage: profile.voltageVolts,
negotiatedCurrent: profile.currentAmps,
profiles: [profile]
)
XCTAssertEqual(profile.watts, 85.8, accuracy: 0.001)
XCTAssertEqual(adapter.negotiatedWatts, 85.8, accuracy: 0.001)
}
func testMemoryBandwidthCatalogUsesSpecificChipBeforeFamilyFallback() {
XCTAssertEqual(
MemoryBandwidthCatalog.description(for: "Apple M4 Pro", cpuCoreCount: 14),
"273 GB/s bandwidth (Apple specification)"
)
XCTAssertEqual(
MemoryBandwidthCatalog.description(for: "Apple M4 Max", cpuCoreCount: 14),
"410 GB/s bandwidth (Apple specification)"
)
XCTAssertEqual(
MemoryBandwidthCatalog.description(for: "Apple M4 Max", cpuCoreCount: 16),
"546 GB/s bandwidth (Apple specification)"
)
XCTAssertEqual(
MemoryBandwidthCatalog.description(for: "Apple M5 Pro", cpuCoreCount: 18),
"Up to 307 GB/s bandwidth (Apple specification)"
)
XCTAssertEqual(MemoryBandwidthCatalog.description(for: "Intel Core i9", cpuCoreCount: 8), "Clock not published by macOS")
XCTAssertEqual(MemoryBandwidthCatalog.specifications.count, 20)
}
}