Files
StarterNG/StarterNG.Tests/BlackBox/BlackBoxListingTests.cs
maj00r e530b95352 Play back the black box of the simulator: map, cab, timeline, timetable and a summary
The simulator writes a black box of each run to physicslog/*.blackbox
(blackbox_doc.md in the maszyna repository). Three new projects read and
show it:

- Eu07.BlackBox: the reader of the records, the recording as a whole
  (the user's vehicle and consist at a time, the timetable shown, the
  progress along it with arrival and departure delays, whether the
  train stood at the platform), the light patterns Pc 1, Pc 2, Pc 5 and
  Tb 1 with the ones the run asks for, and a summary of the driving.
- Eu07.BlackBox.Views: the player window, with the scenery map (tracks,
  signals, W4 stop points with their heading and W32, the train, the
  cameras), the cab, the timeline of speed against the AI's reference,
  the events, the timetable and the summary.
- Eu07.BlackBox.Viewer: the window on its own, with options for the
  time, following the train and screenshots.

The tapes window of the starter lists the black boxes of each session
beside the Hasler tapes and opens them in the player.
2026-11-11 00:39:35 +01:00

97 lines
4.2 KiB
C#

using StarterNG.Domain.Tapes;
using StarterNG.Tests.Fakes;
namespace StarterNG.Tests.BlackBox;
public class BlackBoxListingTests
{
private static readonly DateTime Launched = new(2025, 12, 31, 23, 0, 0, DateTimeKind.Utc);
private static string Log(string name) => TestInstallation.At("physicslog", name);
[Fact]
public void Each_run_keeps_its_own_black_box_next_to_its_tapes()
{
var files = new InMemoryFileSystem()
.WithFile(Log("ra.dat"), "t")
.WithFile(Log("td_2025-12-31_23-00-05.blackbox"), "b")
.WithFile(Log("td_2026-01-01_00-00-05.blackbox"), "b");
var installation = new TestInstallation(files);
var tapes = installation.Tapes;
installation.Clock.Now = Launched;
tapes.RecordLaunch("td.scn", TimeSpan.Zero, Array.Empty<TapeVehicle>(), "ra", new[] { "ra" }, "A");
installation.Clock.Now = Launched.AddHours(1);
tapes.RecordLaunch("td.scn", TimeSpan.Zero, Array.Empty<TapeVehicle>(), "ra", new[] { "ra" }, "B");
files.WrittenAt(Log("td_2025-12-31_23-00-05.blackbox"), Launched.AddMinutes(30))
.WrittenAt(Log("td_2026-01-01_00-00-05.blackbox"), Launched.AddMinutes(90))
.WrittenAt(Log("ra.dat"), Launched.AddMinutes(90));
var sessions = tapes.Sessions();
Assert.Equal(new[] { "B", "A" }, sessions.Select(session => session.Launch!.SceneryName));
Assert.EndsWith("00-00-05.blackbox", Assert.Single(sessions[0].BlackBoxes).Path);
Assert.Single(sessions[0].Tapes);
// The tape of the first run was written over by the second; its black box was not.
Assert.EndsWith("23-00-05.blackbox", Assert.Single(sessions[1].BlackBoxes).Path);
Assert.Empty(sessions[1].Tapes);
Assert.Equal(Launched.AddMinutes(30), sessions[1].LastWrittenUtc);
}
[Fact]
public void A_black_box_is_not_taken_for_a_tape()
{
var installation = new TestInstallation(new InMemoryFileSystem()
.WithFile(Log("ra.dat"), "t")
.WithFile(Log("td_2026-03-01_12-00-00.blackbox"), "b"));
var session = Assert.Single(installation.Tapes.Sessions());
Assert.Equal("ra", Assert.Single(session.Tapes).Vehicle);
Assert.Single(session.BlackBoxes);
Assert.Equal("ra", Assert.Single(installation.Tapes.List()).Vehicle);
}
[Fact]
public void Black_boxes_with_no_launch_noted_go_with_the_tapes_written_about_the_same_time()
{
var early = new DateTime(2026, 3, 1, 12, 0, 0, DateTimeKind.Utc);
var installation = new TestInstallation(new InMemoryFileSystem()
.WithFile(Log("a.dat"), "t")
.WithFile(Log("td_2026-03-01_11-00-00.blackbox"), "b")
.WithFile(Log("td_2026-03-01_12-30-00.blackbox"), "b")
.WrittenAt(Log("a.dat"), early)
.WrittenAt(Log("td_2026-03-01_11-00-00.blackbox"), early.AddSeconds(2))
.WrittenAt(Log("td_2026-03-01_12-30-00.blackbox"), early.AddHours(1)));
var sessions = installation.Tapes.Sessions();
Assert.Equal(2, sessions.Count);
Assert.All(sessions, session => Assert.Null(session.Launch));
// Newest first: the black box on its own, then the run with the tape.
Assert.Empty(sessions[0].Tapes);
Assert.EndsWith("12-30-00.blackbox", Assert.Single(sessions[0].BlackBoxes).Path);
Assert.Single(sessions[1].Tapes);
Assert.EndsWith("11-00-00.blackbox", Assert.Single(sessions[1].BlackBoxes).Path);
Assert.Equal(early, sessions[1].StartedUtc);
}
[Fact]
public void The_black_box_of_a_running_session_is_listed_while_it_is_written()
{
var files = new InMemoryFileSystem();
var installation = new TestInstallation(files);
installation.Clock.Now = Launched;
var tapes = installation.Tapes;
tapes.RecordLaunch("td.scn", TimeSpan.Zero, Array.Empty<TapeVehicle>(), "ra");
files.WithFile(Log("td_2025-12-31_23-00-20.blackbox"), "b")
.WrittenAt(Log("td_2025-12-31_23-00-20.blackbox"), Launched.AddMinutes(5));
installation.SimulatorRunning = true;
var running = Assert.Single(tapes.Sessions());
Assert.True(running.Running);
Assert.Empty(running.Tapes);
Assert.Single(running.BlackBoxes);
}
}