1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
|
namespace SomhairlesDream.Shared.Tests
open System
open Xunit
open SomhairlesDream.Shared
module RunStateTests =
let private at hour = DateTimeOffset(2026, 9, 20, hour, 0, 0, 0, TimeSpan.Zero)
[<Fact>]
let ``a new run is idle with no design work scheduled`` () =
let snapshot = RunState.initial "heritage-001" "run-001" (at 8)
Assert.Equal("heritage-001", snapshot.ProjectId)
Assert.Equal("run-001", snapshot.RunId)
Assert.Equal(RunStatus.Idle, snapshot.Status)
Assert.Equal(0, snapshot.CurrentVersion)
Assert.Equal(0, snapshot.TargetVersion)
Assert.False(snapshot.NextDesignRunScheduled)
Assert.Equal("等待设计运行", snapshot.Message)
[<Fact>]
let ``starting a run increments the target version and heartbeat keeps it running`` () =
let started =
RunState.initial "heritage-001" "run-001" (at 8)
|> RunState.start (at 9)
let alive = RunState.heartbeat (at 9) started
Assert.Equal(RunStatus.Running, alive.Status)
Assert.Equal(1, alive.TargetVersion)
Assert.Equal(Some(at 9), alive.HeartbeatAt)
[<Fact>]
let ``a running run becomes stale after the heartbeat window`` () =
let started =
RunState.initial "heritage-001" "run-001" (at 8)
|> RunState.start (at 9)
let stale = RunState.statusAt (TimeSpan.FromMinutes 2.) (at 10) started
Assert.Equal(RunStatus.Stale, stale.Status)
Assert.Equal("心跳超时,等待重连", stale.Message)
[<Fact>]
let ``publishing a mesh records the current version and makes the run successful`` () =
let started =
RunState.initial "heritage-001" "run-001" (at 8)
|> RunState.start (at 9)
let mesh =
{ Version = 1
Label = "基础结构"
Vertices = [| { X = 0.; Y = 0.; Z = 0. } |]
Faces = [||] }
let published = RunState.publish (at 9) mesh started
Assert.Equal(RunStatus.Succeeded, published.Status)
Assert.Equal(1, published.CurrentVersion)
Assert.Equal(Some mesh, published.Mesh)
Assert.Equal("已发布基础结构", published.Message)
|