feat: verify Tornado PGM KTAP connection

This commit is contained in:
2026-07-10 14:28:45 +09:00
parent b113830c14
commit 930424b752
22 changed files with 3474 additions and 67 deletions

View File

@@ -3,6 +3,7 @@ using System.Text.Json;
using MBN_STOCK_WEBVIEW.Core.Playout;
using MBN_STOCK_WEBVIEW.Playout;
using MBN_STOCK_WEBVIEW.Playout.Configuration;
using MBN_STOCK_WEBVIEW.Playout.Diagnostics;
using MBN_STOCK_WEBVIEW.Playout.Registration;
using MBN_STOCK_WEBVIEW.PlayoutSmoke;
@@ -26,6 +27,8 @@ return parsed.Invocation.Kind switch
SmokeCommandKind.TestPlan => TestPlan(parsed.Invocation),
SmokeCommandKind.TestConnect or SmokeCommandKind.TestSequence =>
await RunIsolatedTestCommandAsync(parsed.Invocation, cancellation.Token),
SmokeCommandKind.PgmConnectDiagnostic =>
await RunPgmConnectDiagnosticAsync(parsed.Invocation, cancellation.Token),
_ => Usage("unknown-command")
};
@@ -221,6 +224,104 @@ static async Task<int> RunIsolatedTestCommandAsync(
return report.OutcomeUnknown ? 5 : 4;
}
static async Task<int> RunPgmConnectDiagnosticAsync(
SmokeCommandInvocation invocation,
CancellationToken cancellationToken)
{
if (IsolatedTestCommandPreflight.HasPlayoutEnvironmentOverride(
Environment.GetEnvironmentVariables()))
{
WritePgmDiagnosticFailure("environment-override-present");
return 65;
}
var request = new PgmConnectDiagnosticRequest(
invocation.Host ?? string.Empty,
invocation.Port ?? 0,
invocation.ExpectedPgmWindowTitle ?? string.Empty);
PgmConnectDiagnosticReport report;
try
{
report = await new PgmConnectDiagnosticRunner()
.ExecuteAsync(request, cancellationToken)
.ConfigureAwait(false);
}
catch
{
WritePgmDiagnosticFailure("internal-diagnostic-failure");
return 70;
}
WriteJson(new
{
command = "pgm-connect-diagnostic",
report.RequestValidated,
report.ProcessGatePassed,
report.ListenerOwnershipConfirmed,
report.RegistrationReady,
report.ConnectRequestIssued,
report.ComActivationAttempted,
lastKtapConnectState = ToWireValue(report.LastKtapConnectState),
report.KtapConnectAttempted,
report.KtapConnectAccepted,
report.KtapHelloObserved,
report.NetworkMonitoringRecordExpected,
report.NetworkMonitoringCheckRequired,
report.NetworkMonitoringVerified,
report.DisconnectAttempted,
report.DisconnectCode,
report.Completed,
report.OutcomeUnknown,
report.RenderCommandSurfaceExposed,
report.RenderCommandAttempted,
report.AutomaticReconnectEnabled,
report.ErrorCode
});
if (report.Completed && !report.OutcomeUnknown)
{
return 0;
}
return report.OutcomeUnknown ? 5 : 4;
}
static void WritePgmDiagnosticFailure(string errorCode) =>
WriteJson(new
{
command = "pgm-connect-diagnostic",
requestValidated = false,
processGatePassed = false,
listenerOwnershipConfirmed = false,
registrationReady = false,
connectRequestIssued = false,
comActivationAttempted = false,
lastKtapConnectState = "not-attempted",
ktapConnectAttempted = false,
ktapConnectAccepted = false,
ktapHelloObserved = (bool?)null,
networkMonitoringRecordExpected = false,
networkMonitoringCheckRequired = false,
networkMonitoringVerified = (bool?)null,
disconnectAttempted = false,
disconnectCode = "not-attempted",
completed = false,
outcomeUnknown = false,
renderCommandSurfaceExposed = false,
renderCommandAttempted = false,
automaticReconnectEnabled = false,
errorCode
});
static string ToWireValue(PlayoutKtapConnectState state) => state switch
{
PlayoutKtapConnectState.NotAttempted => "not-attempted",
PlayoutKtapConnectState.Attempted => "attempted",
PlayoutKtapConnectState.AcceptedUnconfirmed => "accepted-unconfirmed",
PlayoutKtapConnectState.Failed => "failed",
_ => "not-attempted"
};
static void WritePreflightFailure(string command, string errorCode) =>
WriteJson(new
{
@@ -265,12 +366,14 @@ static int Usage(string? errorCode)
errorCode = errorCode ?? "invalid-command-line"
});
Console.Error.WriteLine(
"Usage: MBN_STOCK_WEBVIEW.PlayoutSmoke [--probe|--dry-run|--test-plan|--test-connect|--test-sequence]");
"Usage: MBN_STOCK_WEBVIEW.PlayoutSmoke [--probe|--dry-run|--test-plan|--test-connect|--test-sequence|--pgm-connect-diagnostic]");
Console.Error.WriteLine(
$"Test commands require {SmokeCommandLine.AcknowledgementFlag} and --config <absolute-path>.");
Console.Error.WriteLine(
"--test-plan and --test-sequence also require --prepare <scene-code> --next <scene-code> --observe-ms <1000..30000>.");
Console.Error.WriteLine(
"Only --test-connect and --test-sequence may request COM, after all Test safety gates pass.");
"--test-connect and --test-sequence may request render-capable COM after all Test safety gates pass.");
Console.Error.WriteLine(
$"--pgm-connect-diagnostic requires {SmokeCommandLine.PgmConnectAcknowledgementFlag}, --host, --port and --expected-pgm-window-title; it exposes no render command.");
return 64;
}