summaryrefslogtreecommitdiff
path: root/tests/SomhairlesDream.Modeling.Tests/BridgeTests.fs
blob: d9c7347c375cae8af1e27e6bab7a2eeb89ea0312 (plain)
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
module SomhairlesDream.Modeling.Tests.BridgeTests

open System
open System.IO
open Xunit
open SomhairlesDream.Modeling

let private withTempDirectory action =
    let path = Path.Combine(Path.GetTempPath(), "somhairles-dream-bridge-" + Guid.NewGuid().ToString("N"))
    Directory.CreateDirectory(path) |> ignore

    try
        action path
    finally
        if Directory.Exists(path) then
            Directory.Delete(path, true)

let private fixtureScript =
    [| "import argparse"
       "import json"
       "import os"
       ""
       "parser = argparse.ArgumentParser()"
       "parser.add_argument('--step-id', required=True)"
       "parser.add_argument('--output', required=True)"
       "parser.add_argument('--render-output')"
       "parser.add_argument('--result-output')"
       "args = parser.parse_args()"
       "os.makedirs(os.path.dirname(args.output), exist_ok=True)"
       "with open(args.output, 'wb') as stream:"
       "    stream.write(b'glTF')"
       "result_path = args.result_output or args.output + '.result.json'"
       "with open(result_path, 'w', encoding='utf-8') as stream:"
       "    json.dump({"
       "        'ok': True,"
       "        'blenderVersion': 'test',"
       "        'exportedAt': '2026-09-20T12:00:05Z',"
       "        'objectIds': ['heritage.foundation', 'heritage.deck'],"
       "        'verifiedObjectIds': ['heritage.foundation', 'heritage.deck'],"
       "        'glbBytes': 4"
       "    }, stream)"
       "with open(args.output + '.log', 'w', encoding='utf-8') as stream:"
       "    stream.write('fixture log retained separately\\n')"
       "print('Blender informational output')" |]
    |> String.concat Environment.NewLine

[<Fact>]
let ``bridge reads result file instead of polluted stdout and retains process log`` () =
    withTempDirectory (fun root ->
        let blenderRoot = Path.Combine(root, "stage", "blender")
        Directory.CreateDirectory(blenderRoot) |> ignore
        File.WriteAllText(Path.Combine(blenderRoot, "fixture.py"), fixtureScript)

        let output = Path.Combine(root, "run", "step.glb")
        let request =
            { Step = Design.steps[0]
              GlbPath = output
              RenderPath = None
              ResultPath = output + ".result.json"
              LogPath = output + ".log" }

        let result =
            (BlenderProcessBridge("python3", Path.Combine(root, "stage")) :> IArtifactBridge)
                .Export(request, ignore)

        match result with
        | Error message -> failwith message
        | Ok value ->
            Assert.Equal("test", value.BlenderVersion)
            Assert.Equal(4L, value.GlbBytes)
            Assert.True(File.Exists(output + ".log"))
            Assert.Contains("Blender informational output", File.ReadAllText(output + ".log")))