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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
|
module SomhairlesDream.Server.Tests.CoordinatorTests
open System
open System.IO
open System.Threading
open Xunit
open SomhairlesDream.Modeling
open SomhairlesDream.Server
open SomhairlesDream.Shared
let private ids : RunIds =
{ ProjectId = "heritage-001"
RunId = "run-20260920-001"
BaseId = "heritage"
TargetId = "heritage-001" }
let private withTempDirectory action =
let path = Path.Combine(Path.GetTempPath(), "somhairles-dream-server-" + Guid.NewGuid().ToString("N"))
Directory.CreateDirectory(path) |> ignore
try
action path
finally
if Directory.Exists(path) then
Directory.Delete(path, true)
type private TestBridge() =
interface IArtifactBridge with
member _.Export(request, _) =
File.WriteAllBytes(request.GlbPath, [| 0x67uy; 0x6Cuy; 0x54uy; byte request.Step.Index |])
Directory.CreateDirectory(Path.GetDirectoryName(request.LogPath)) |> ignore
File.WriteAllText(request.LogPath, $"bridge log for {request.Step.StepId}")
Ok
{ BlenderVersion = "5.0.1"
ExportedAt = DateTimeOffset.Parse("2026-09-20T12:00:05Z")
ObjectIds = request.Step.ObjectIds
VerifiedObjectIds = request.Step.ObjectIds
GlbBytes = 4L
RenderPath = None
RenderedAt = None }
let private waitFor predicate =
let deadline = DateTime.UtcNow.AddSeconds(5.)
let mutable matched = predicate ()
while not matched && DateTime.UtcNow < deadline do
Thread.Sleep(10)
matched <- predicate ()
matched
[<Fact>]
let ``coordinator starts one shared pipeline and publishes its manifest`` () =
withTempDirectory (fun root ->
let clock () = DateTimeOffset.Parse("2026-09-20T12:00:00Z")
let coordinator =
ArtifactRunCoordinator(
root,
(fun () -> TestBridge() :> IArtifactBridge),
clock,
TimeSpan.FromSeconds 15.
)
match coordinator.Start(ids, false) with
| Error message -> failwith message
| Ok(Accepted snapshot) ->
Assert.Equal(ids.ProjectId, snapshot.ProjectId)
Assert.Equal(ids.RunId, snapshot.RunId)
| Ok(Conflict _) -> failwith "expected the first start to be accepted"
let completed =
waitFor (fun () ->
coordinator.TryFind(ids.ProjectId, ids.RunId)
|> Option.exists (fun store -> store.Snapshot().Status = "complete"))
Assert.True(completed)
match coordinator.Manifest(ids.ProjectId, ids.RunId) with
| Error failure -> failwith $"manifest lookup failed: {failure}"
| Ok manifest ->
Assert.Equal("complete", manifest.Status)
Assert.Equal(3, manifest.Steps.Length))
|