b330faff03
Make the service build, run, and install on Linux as a first-class target while keeping the Windows Service + Event Log behaviour intact. - Build: drop the hardcoded win-x64 RID — single-file publish now works for any RID. publish.ps1 gains -Rid; new publish.sh for Linux hosts. - Diagnostics: DiagnosticSinkSelector picks the Error+ sink per host — Windows Event Log under the SCM, local syslog under systemd (Serilog.Sinks.SyslogMessages), none for interactive runs. The EventLog truncation helper is extracted so it is testable cross-OS. - Host: Program.cs registers AddSystemd() alongside AddWindowsService(). - Config: a RID-conditioned appsettings template ships Windows or Unix paths; both templates are schema-validated by a test. - Install: systemd unit (Type=exec) plus install.sh / uninstall.sh. Also fixes two cross-platform bugs found while testing: install.ps1 and uninstall.ps1 used New-EventLog / Remove-EventLog (absent in PowerShell 7), and the E2E sim launcher hardcoded Windows venv paths. - Docs updated across README, CLAUDE.md, and docs/ for dual-platform. 413 tests pass on Windows; 374 (all non-simulator) on Linux. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
41 lines
1.9 KiB
C#
41 lines
1.9 KiB
C#
using Mbproxy.Diagnostics;
|
|
using Shouldly;
|
|
using Xunit;
|
|
|
|
namespace Mbproxy.Tests.Diagnostics;
|
|
|
|
/// <summary>
|
|
/// Unit tests for <see cref="DiagnosticSinkSelector"/> — the pure platform-selection
|
|
/// logic for the Error+ diagnostic sink. Covers every OS / host combination so the
|
|
/// selection contract is pinned without needing a real Windows Service or systemd host.
|
|
/// </summary>
|
|
[Trait("Category", "Unit")]
|
|
public sealed class DiagnosticSinkSelectorTests
|
|
{
|
|
// 'expected' is the underlying int of DiagnosticSink: the enum is internal and
|
|
// cannot appear in a public (xunit-discoverable) method signature.
|
|
[Theory]
|
|
[InlineData(true, true, false, (int)DiagnosticSink.EventLog)] // Windows, hosted as a Windows Service
|
|
[InlineData(true, false, false, (int)DiagnosticSink.None)] // Windows, interactive / dev run
|
|
[InlineData(false, false, true, (int)DiagnosticSink.Syslog)] // Linux, hosted as a systemd service
|
|
[InlineData(false, false, false, (int)DiagnosticSink.None)] // Linux / macOS, interactive / dev run
|
|
public void Select_PicksExpectedSink(
|
|
bool isWindows, bool isWindowsService, bool isSystemd, int expected)
|
|
=> ((int)DiagnosticSinkSelector.Select(isWindows, isWindowsService, isSystemd)).ShouldBe(expected);
|
|
|
|
[Fact]
|
|
public void Select_Windows_TakesPrecedence_OverASpuriousSystemdFlag()
|
|
=> DiagnosticSinkSelector.Select(isWindows: true, isWindowsService: true, isSystemd: true)
|
|
.ShouldBe(DiagnosticSink.EventLog);
|
|
|
|
[Fact]
|
|
public void Select_WindowsConsoleRun_GetsNoSink_EvenIfSystemdFlagSet()
|
|
=> DiagnosticSinkSelector.Select(isWindows: true, isWindowsService: false, isSystemd: true)
|
|
.ShouldBe(DiagnosticSink.None);
|
|
|
|
[Fact]
|
|
public void Select_NonWindowsWithoutSystemd_GetsNoSink()
|
|
=> DiagnosticSinkSelector.Select(isWindows: false, isWindowsService: false, isSystemd: false)
|
|
.ShouldBe(DiagnosticSink.None);
|
|
}
|