mirror of
https://github.com/aculix/knotchy.git
synced 2026-10-27 07:15:53 +00:00
Initial release
This commit is contained in:
commit
4b67728cce
108 files changed
+13310
No files matched your search
@@ -0,0 +1,121 @@
|
||||
import Foundation
|
||||
import Testing
|
||||
@testable import KnotchyCore
|
||||
|
||||
@MainActor
|
||||
@Suite(.timeLimit(.minutes(1)))
|
||||
struct SessionSetupRunTests {
|
||||
@Test func aWindowRunFixesEachIssueInTurnAndEndsIdle() async {
|
||||
let h = Harness()
|
||||
h.backend.queuePreflight(.issue(.imageMissing))
|
||||
#expect(await h.controller.runSetup(.serviceStopped, continuing: true) == .ready)
|
||||
#expect(h.state == .idle)
|
||||
#expect(h.backend.calls == [.sweep(keeping: []), .fix(.serviceStopped), .preflight, .fix(.imageMissing), .preflight])
|
||||
}
|
||||
|
||||
@Test func aWindowRunStartsFolded() async {
|
||||
let h = Harness()
|
||||
h.backend.hold(.fix)
|
||||
let run = Task { await h.controller.runSetup(.imageMissing, continuing: false) }
|
||||
await waitUntil("building") { h.backend.parkedCount(.fix) == 1 }
|
||||
#expect(h.state == .settingUp(.imageMissing))
|
||||
#expect(h.controller.setupFolded)
|
||||
h.backend.release(.fix)
|
||||
#expect(await run.value == .ready)
|
||||
}
|
||||
|
||||
@Test func aWindowRunNeverFixesTheSameIssueTwice() async {
|
||||
let h = Harness()
|
||||
h.backend.queuePreflight(.issue(.serviceStopped))
|
||||
#expect(await h.controller.runSetup(.serviceStopped, continuing: true)
|
||||
== .failed(.serviceStopped, SessionController.stillBrokenMessage))
|
||||
#expect(h.state == .idle)
|
||||
#expect(h.backend.calls.filter { $0 == .fix(.serviceStopped) }.count == 1)
|
||||
}
|
||||
|
||||
@Test func anotherImageIssueAfterABuildIsTheSameFix() async {
|
||||
let h = Harness()
|
||||
h.backend.queuePreflight(.issue(.imageOutdated(found: 2, need: 3)))
|
||||
#expect(await h.controller.runSetup(.imageMissing, continuing: true)
|
||||
== .failed(.imageOutdated(found: 2, need: 3), SessionController.stillBrokenMessage))
|
||||
#expect(h.backend.calls.filter { if case .fix = $0 { true } else { false } }.count == 1)
|
||||
}
|
||||
|
||||
@Test func aFailedWindowRunLeavesNoCardWithoutALink() async {
|
||||
let h = Harness()
|
||||
h.backend.scriptFix(output: [], error: VMBackendError.failed("container build failed"))
|
||||
#expect(await h.controller.runSetup(.imageMissing, continuing: true) == .failed(.imageMissing, "container build failed"))
|
||||
#expect(h.state == .idle)
|
||||
}
|
||||
|
||||
@Test func aLinkDuringAWindowRunWaitsForTheWholeChain() async {
|
||||
let h = Harness()
|
||||
h.backend.queuePreflight(.issue(.imageMissing))
|
||||
h.backend.hold(.fix)
|
||||
let run = Task { await h.controller.runSetup(.serviceStopped, continuing: true) }
|
||||
await waitUntil("starting the service") { h.backend.parkedCount(.fix) == 1 }
|
||||
h.controller.open(Harness.url)
|
||||
#expect(h.state == .settingUp(.serviceStopped))
|
||||
#expect(!h.controller.setupFolded) // A waiting link shows its card.
|
||||
h.backend.release(.fix)
|
||||
#expect(await run.value == .ready)
|
||||
await waitUntil("loading") { h.state == .starting(.loading, folded: false) }
|
||||
#expect(Array(h.backend.calls.prefix(5))
|
||||
== [.sweep(keeping: []), .fix(.serviceStopped), .preflight, .fix(.imageMissing), .preflight])
|
||||
}
|
||||
|
||||
@Test func aBusyControllerRefusesTheWindow() async {
|
||||
let h = Harness()
|
||||
await h.goLive()
|
||||
#expect(await h.controller.runSetup(.imageMissing, continuing: true) == nil)
|
||||
#expect(await h.controller.checkSetup() == nil)
|
||||
}
|
||||
|
||||
@Test func checkingStartsAStoppedServiceButNeverBuilds() async {
|
||||
let h = Harness()
|
||||
h.backend.queuePreflight(.issue(.serviceStopped), .issue(.imageMissing))
|
||||
#expect(await h.controller.checkSetup() == .needs(.imageMissing))
|
||||
#expect(h.state == .idle)
|
||||
#expect(h.backend.calls == [.sweep(keeping: []), .preflight, .fix(.serviceStopped), .preflight])
|
||||
}
|
||||
|
||||
@Test func checkingOpensALinkACardWasHolding() async {
|
||||
let h = Harness()
|
||||
h.backend.queuePreflight(.issue(.imageMissing))
|
||||
h.controller.open(Harness.url)
|
||||
await waitUntil("setup required") { h.state == .setupRequired(.imageMissing, error: nil) }
|
||||
#expect(await h.controller.checkSetup() == .ready)
|
||||
await waitUntil("loading") { h.state == .starting(.loading, folded: false) }
|
||||
#expect(h.controller.openedURL == Harness.url)
|
||||
}
|
||||
|
||||
@Test func checkingAReadyMacFixesNothing() async {
|
||||
let h = Harness()
|
||||
#expect(await h.controller.checkSetup() == .ready)
|
||||
#expect(!h.backend.calls.contains { if case .fix = $0 { true } else { false } })
|
||||
}
|
||||
|
||||
@Test func setupOutputKeepsTheLast200Lines() async {
|
||||
let h = Harness()
|
||||
h.backend.scriptFix(output: (1...250).map { "line \($0)" })
|
||||
_ = await h.controller.runSetup(.imageMissing, continuing: false)
|
||||
#expect(h.controller.setupOutput.count == 200)
|
||||
#expect(h.controller.setupOutput.first == "line 51")
|
||||
#expect(h.controller.setupOutput.last == "line 250")
|
||||
}
|
||||
|
||||
@Test func waitingForSetupReturnsOnlyWhenItEnds() async {
|
||||
let h = Harness()
|
||||
h.backend.hold(.fix)
|
||||
let run = Task { await h.controller.runSetup(.imageMissing, continuing: false) }
|
||||
await waitUntil("building") { h.backend.parkedCount(.fix) == 1 }
|
||||
let waiter = Task {
|
||||
await h.controller.waitWhileSettingUp()
|
||||
return h.state
|
||||
}
|
||||
await Task.yield()
|
||||
h.backend.release(.fix)
|
||||
#expect(await waiter.value == .idle)
|
||||
_ = await run.value
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user