using Xunit; namespace Admin.NET.Plugin.AiDOP.Tests.Infrastructure; /// /// 启动期并发守卫。ISqlSugarClient 是单例 SqlSugarScope,其 AsyncLocal 上下文在 Host 启动阶段 /// 会被 Configure 管道与任何火忘任务共享,共享即同一个 MySqlConnection;后执行的 ApprovalFlow /// 插件同步 InitTables 没有容错,撞上就是进程退出。 /// 2026-09-26 事故复盘:doc/plan/天缘对接/20260926问题描述.md /// public class StartupConcurrencyGuardTests { private static string PluginStartupSource() { var dir = new DirectoryInfo(AppContext.BaseDirectory); while (dir != null && !File.Exists(Path.Combine(dir.FullName, "AGENTS.md"))) dir = dir.Parent; Assert.NotNull(dir); return File.ReadAllText(Path.Combine( dir!.FullName, "server", "Plugins", "Admin.NET.Plugin.AiDOP", "Startup.cs")); } /// 去掉注释,否则「不要改成 Task.Run」这类说明文字会被误判为违规调用。 private static string StripComments(string source) { var noBlock = System.Text.RegularExpressions.Regex.Replace(source, @"/\*.*?\*/", "", System.Text.RegularExpressions.RegexOptions.Singleline); return System.Text.RegularExpressions.Regex.Replace(noBlock, @"//.*?$", "", System.Text.RegularExpressions.RegexOptions.Multiline); } [Fact] public void AiDopStartup_DoesNotFireAndForgetDatabaseWork() { var code = StripComments(PluginStartupSource()); Assert.DoesNotContain("Task.Run", code); Assert.DoesNotContain("Task.Factory.StartNew", code); } }