claire-tray/Tests/ClaireTrayAppTests/WatchdogTests.swift

49 lines
2.4 KiB
Swift
Raw Normal View History

import XCTest
@testable import ClaireTrayApp
final class WatchdogTests: XCTestCase {
private let t0 = Date(timeIntervalSince1970: 1_000_000)
func testHealthyStaysOK() {
var w = Watchdog(failureThreshold: 3, cooldown: 120, maxAttempts: 5)
XCTAssertEqual(w.record(healthy: true, now: t0), .ok)
XCTAssertEqual(w.record(healthy: true, now: t0.addingTimeInterval(25)), .ok)
}
func testRecoversOnlyAfterThreshold() {
var w = Watchdog(failureThreshold: 3, cooldown: 120, maxAttempts: 5)
XCTAssertEqual(w.record(healthy: false, now: t0), .watching) // 1
XCTAssertEqual(w.record(healthy: false, now: t0.addingTimeInterval(25)), .watching) // 2
XCTAssertEqual(w.record(healthy: false, now: t0.addingTimeInterval(50)), .recover) // 3 kick
}
func testCooldownSuppressesRepeatKicks() {
var w = Watchdog(failureThreshold: 1, cooldown: 120, maxAttempts: 5)
XCTAssertEqual(w.record(healthy: false, now: t0), .recover) // kick at t0
// Within cooldown: no second kick.
XCTAssertEqual(w.record(healthy: false, now: t0.addingTimeInterval(60)), .watching)
// After cooldown: kick again.
XCTAssertEqual(w.record(healthy: false, now: t0.addingTimeInterval(130)), .recover)
}
func testGivesUpAfterMaxAttempts() {
var w = Watchdog(failureThreshold: 1, cooldown: 0, maxAttempts: 2)
XCTAssertEqual(w.record(healthy: false, now: t0), .recover) // attempt 1
XCTAssertEqual(w.record(healthy: false, now: t0.addingTimeInterval(1)), .recover) // attempt 2
XCTAssertEqual(w.record(healthy: false, now: t0.addingTimeInterval(2)), .gaveUp) // ceiling hit
XCTAssertTrue(w.gaveUp)
}
func testRecoveryResetsAfterDaemonHealthyAgain() {
var w = Watchdog(failureThreshold: 1, cooldown: 0, maxAttempts: 2)
_ = w.record(healthy: false, now: t0) // recover
_ = w.record(healthy: false, now: t0.addingTimeInterval(1)) // recover
_ = w.record(healthy: false, now: t0.addingTimeInterval(2)) // gaveUp
XCTAssertTrue(w.gaveUp)
XCTAssertEqual(w.record(healthy: true, now: t0.addingTimeInterval(3)), .ok) // recovered
XCTAssertFalse(w.gaveUp)
// Counters reset a fresh failure run can recover again.
XCTAssertEqual(w.record(healthy: false, now: t0.addingTimeInterval(4)), .recover)
}
}