fix: restore existing WeChat instance and add M6 validation tools
This commit is contained in:
@@ -35,6 +35,33 @@ try
|
||||
WriteJson(report);
|
||||
return report.Errors.Count == 0 ? 0 : 2;
|
||||
}
|
||||
case "diagnose":
|
||||
{
|
||||
var directory = Path.GetFullPath(GetRequiredOption(args, "--output"));
|
||||
Directory.CreateDirectory(directory);
|
||||
var snapshot = await WechatUiInspector.CaptureAsync(Path.Combine(directory, "ui-tree.json"), cancellationToken);
|
||||
var baseline = snapshot;
|
||||
if (GetOption(args, "--baseline") is { } baselinePath)
|
||||
{
|
||||
await using var input = File.OpenRead(baselinePath);
|
||||
baseline = await JsonSerializer.DeserializeAsync<UiNodeSnapshot>(input,
|
||||
new JsonSerializerOptions { MaxDepth = 128 }, cancellationToken)
|
||||
?? throw new WxAgentException(WxAgentErrorCode.InvalidArgument, "Baseline UI snapshot is empty.");
|
||||
}
|
||||
var report = new
|
||||
{
|
||||
correlationId = Guid.NewGuid().ToString("N"),
|
||||
stage = "ui-compatibility-diagnostics",
|
||||
capturedAt = DateTimeOffset.UtcNow,
|
||||
doctor = WechatDoctor.Run(cancellationToken),
|
||||
nativeWindows = WechatChatClient.InspectNativeWindows(),
|
||||
comparison = UiSnapshotComparison.Compare(baseline, snapshot)
|
||||
};
|
||||
await File.WriteAllTextAsync(Path.Combine(directory, "diagnostics.json"),
|
||||
JsonSerializer.Serialize(report, jsonOptions), cancellationToken);
|
||||
WriteJson(report);
|
||||
return report.doctor.Errors.Count == 0 && report.comparison.MissingRequiredControls.Count == 0 ? 0 : 2;
|
||||
}
|
||||
case "inspect-ui":
|
||||
{
|
||||
var output = GetRequiredOption(args, "--output");
|
||||
@@ -62,6 +89,78 @@ try
|
||||
});
|
||||
return report.Errors.Count == 0 ? 0 : 2;
|
||||
}
|
||||
case "tray-status":
|
||||
{
|
||||
WriteJson(WechatChatClient.InspectTray(cancellationToken));
|
||||
return 0;
|
||||
}
|
||||
case "window-status":
|
||||
{
|
||||
WriteJson(WechatChatClient.InspectNativeWindows());
|
||||
return 0;
|
||||
}
|
||||
case "listener-smoke":
|
||||
{
|
||||
var result = await WechatChatClient.ListenerSmokeAsync(GetRequiredOption(args, "--output"), cancellationToken);
|
||||
WriteJson(result);
|
||||
return result.Sent && result.MatchingEvents == 1 && result.EventsAfterRestart == 0
|
||||
&& result.Snapshots >= 2 && result.CheckpointSaved ? 0 : 2;
|
||||
}
|
||||
case "recovery-smoke":
|
||||
{
|
||||
var checks = await WechatChatClient.RecoverySmokeAsync(cancellationToken);
|
||||
WriteJson(checks);
|
||||
return checks.All(check => check.TransitionObserved && check.SameInstance && check.MainViewFound
|
||||
&& check.SessionsFound && check.MessagesFound) ? 0 : 2;
|
||||
}
|
||||
case "recover-ui":
|
||||
{
|
||||
var result = await WechatChatClient.RecoverUiAsync(cancellationToken);
|
||||
WriteJson(result);
|
||||
return result.Success ? 0 : 2;
|
||||
}
|
||||
case "stability-smoke":
|
||||
{
|
||||
var seconds = GetPositiveIntOption(args, "--seconds", 15, 300);
|
||||
var sampleSeconds = GetPositiveIntOption(args, "--sample-seconds", 5, seconds);
|
||||
var output = GetOption(args, "--output") ?? Path.Combine("artifacts", "m6-stability-smoke");
|
||||
var recovery = await WechatChatClient.RecoverUiAsync(cancellationToken);
|
||||
var report = await WechatStabilityRunner.RunAsync(
|
||||
TimeSpan.FromSeconds(seconds),
|
||||
TimeSpan.FromSeconds(sampleSeconds),
|
||||
output,
|
||||
cancellationToken);
|
||||
WriteJson(new
|
||||
{
|
||||
scope = "M6",
|
||||
recovery.Success,
|
||||
report.Healthy,
|
||||
sampleCount = report.Samples.Count,
|
||||
report.MessageEvents,
|
||||
report.ReconnectEvents,
|
||||
report.WorkingSetGrowthBytes,
|
||||
report.HandleGrowth,
|
||||
report.ThreadGrowth,
|
||||
report.Findings,
|
||||
output = Path.GetFullPath(output),
|
||||
privacy = "message content omitted"
|
||||
});
|
||||
return report.Healthy ? 0 : 2;
|
||||
}
|
||||
case "endurance":
|
||||
{
|
||||
var hours = GetPositiveIntOption(args, "--hours", 24, 72);
|
||||
var sampleSeconds = GetPositiveIntOption(args, "--sample-seconds", 60, 3600);
|
||||
var output = GetOption(args, "--output") ?? Path.Combine("artifacts", $"endurance-{DateTimeOffset.UtcNow:yyyyMMddHHmmss}");
|
||||
await WechatChatClient.RecoverUiAsync(cancellationToken);
|
||||
var report = await WechatStabilityRunner.RunAsync(
|
||||
TimeSpan.FromHours(hours),
|
||||
TimeSpan.FromSeconds(sampleSeconds),
|
||||
output,
|
||||
cancellationToken);
|
||||
WriteJson(report with { Samples = [] });
|
||||
return report.Healthy ? 0 : 2;
|
||||
}
|
||||
case "m5-smoke":
|
||||
{
|
||||
var momentsWindow = await WechatChatClient.OpenMomentsAsync(cancellationToken);
|
||||
@@ -372,6 +471,18 @@ static int ValidateCommandLine(string[] values)
|
||||
return 30;
|
||||
}
|
||||
|
||||
if (values[0] == "listener-smoke")
|
||||
{
|
||||
ValidateOptions(values, 1, ["--output", "--timeout"], []);
|
||||
return 60;
|
||||
}
|
||||
|
||||
if (values[0] == "diagnose")
|
||||
{
|
||||
ValidateOptions(values, 1, ["--output", "--baseline", "--timeout"], []);
|
||||
return 60;
|
||||
}
|
||||
|
||||
if (values[0] == "inspect-ui")
|
||||
{
|
||||
ValidateOptions(values, 1, ["--output", "--timeout"], []);
|
||||
@@ -384,6 +495,24 @@ static int ValidateCommandLine(string[] values)
|
||||
return 30;
|
||||
}
|
||||
|
||||
if (values[0] is "recover-ui" or "window-status" or "tray-status" or "recovery-smoke")
|
||||
{
|
||||
ValidateOptions(values, 1, ["--timeout"], []);
|
||||
return 30;
|
||||
}
|
||||
|
||||
if (values[0] == "stability-smoke")
|
||||
{
|
||||
ValidateOptions(values, 1, ["--seconds", "--sample-seconds", "--output", "--timeout"], []);
|
||||
return GetPositiveIntOption(values, "--seconds", 15, 300) + 60;
|
||||
}
|
||||
|
||||
if (values[0] == "endurance")
|
||||
{
|
||||
ValidateOptions(values, 1, ["--hours", "--sample-seconds", "--output", "--timeout"], []);
|
||||
return checked(GetPositiveIntOption(values, "--hours", 24, 72) * 3600 + 120);
|
||||
}
|
||||
|
||||
if (values[0] == "m5-smoke")
|
||||
{
|
||||
ValidateOptions(values, 1, ["--timeout"], []);
|
||||
@@ -586,10 +715,18 @@ static int CountNodes(UiNodeSnapshot node) => 1 + node.Children.Sum(CountNodes);
|
||||
static void PrintHelp() => Console.WriteLine("""
|
||||
WxAgent.Host commands:
|
||||
doctor [--timeout 30]
|
||||
diagnose --output <dir> [--baseline <ui-tree.json>] [--timeout 60]
|
||||
inspect-ui --output <path> [--timeout 30]
|
||||
smoke [--output <path>] [--timeout 30]
|
||||
m4-smoke [--timeout 60]
|
||||
m5-smoke [--timeout 60]
|
||||
tray-status [--timeout 30]
|
||||
window-status [--timeout 30]
|
||||
listener-smoke --output <new-dir> [--timeout 60]
|
||||
recovery-smoke [--timeout 30]
|
||||
recover-ui [--timeout 30]
|
||||
stability-smoke [--seconds 15] [--sample-seconds 5] [--output <dir>]
|
||||
endurance [--hours 24] [--sample-seconds 60] [--output <dir>]
|
||||
group at-all --group <name> --message <text> --confirm CONFIRM [--timeout 30]
|
||||
group verify-at-all --group <name> --message <text> [--timeout 30]
|
||||
chat send-url-card --to <name> --url <http-url> [--message <text>] --confirm CONFIRM [--timeout 60]
|
||||
|
||||
Reference in New Issue
Block a user