From 8fe1b57173a63a58617719c18cedd180932b1c32 Mon Sep 17 00:00:00 2001 From: Johannes Rest Date: Mon, 10 Aug 2026 17:23:23 +0200 Subject: [PATCH] Guard Checkmk service renames during updates --- deployment/INSTALLATION.md | 17 +++- ...ndpoint-Reachability-Analyse-2026-08-10.md | 8 +- ...k_Checkmk_Pulse_Architekturueberblick.docx | Bin 276983 -> 277060 bytes scripts/generate-architecture-overview.py | 15 ++-- .../InstallerEngine.cs | 62 ++++++++++++- src/BizTalkCheckmkPulse.Setup/MainForm.cs | 22 +++-- .../Properties/AssemblyInfo.cs | 4 +- .../Properties/AssemblyInfo.cs | 4 +- tests/BizTalkCheckmkPulse.Tests/Program.cs | 83 ++++++++++++++++++ 9 files changed, 192 insertions(+), 23 deletions(-) diff --git a/deployment/INSTALLATION.md b/deployment/INSTALLATION.md index 38caa69..4aedd7c 100644 --- a/deployment/INSTALLATION.md +++ b/deployment/INSTALLATION.md @@ -28,7 +28,22 @@ nach dem nächsten Agentenlauf das 2.2.1-Fehlerbild `Item not found in monitoring data`. Nur bei bewusst auf `true` gesetztem Opt-in ist anschließend eine Checkmk Service Discovery erforderlich. -Vor dem Stoppen des vorhandenen Tasks wird die neue Version separat getestet. +Ab Version 2.2.3 vergleicht der Installer bei jedem Update die exakten +Servicenamen der installierten und der vorbereiteten Version. Neue, entfernte +oder umbenannte Services führen **vor dem Stoppen des Tasks** zu einem +Sicherheitsstopp. Die Installation darf nur über die Checkbox +**Service-Rename ist beabsichtigt; Checkmk Service Discovery ist eingeplant** +fortgesetzt werden. Der Installer zeigt dabei die entfernten und neuen Namen +an. Eine bloß geänderte Ausgabereihenfolge gilt nicht als Rename. + +Beim korrigierenden Wechsel von 2.2.1 mit `BizTalk ACC ...` auf stabile +`BizTalk ...`-Namen ist die Änderung beabsichtigt: Checkbox aktivieren und den +Servicebestand danach per Discovery abgleichen. Sind in Checkmk bereits die +unpräfixierten Services vorhanden, werden damit insbesondere eventuell +vorhandene falsche `BizTalk ACC ...`-Services bereinigt. + +Vor dem Stoppen des vorhandenen Tasks wird die neue Version separat getestet +und ihr Checkmk-Servicevertrag mit der installierten Version verglichen. Bei normalen Servicekonten prüft der Installer außerdem Kennwort und Batch-Anmelderecht vor der Umschaltung. Der Task wird vor dem Dateitausch deaktiviert und sein Prozessende maximal zehn diff --git a/docs/ACC-Endpoint-Reachability-Analyse-2026-08-10.md b/docs/ACC-Endpoint-Reachability-Analyse-2026-08-10.md index 0f602f2..40875b3 100644 --- a/docs/ACC-Endpoint-Reachability-Analyse-2026-08-10.md +++ b/docs/ACC-Endpoint-Reachability-Analyse-2026-08-10.md @@ -71,6 +71,10 @@ nicht netzwerkprüfbare Kandidaten. Version 2.2.2 weist sie explizit als `BizTalk ...` und passen wieder zu den bereits entdeckten ACC-Services. - Nur ein bewusstes Opt-in mit `true` erzeugt Namen wie `BizTalk ACC ...` und verlangt anschließend eine Checkmk Service Discovery. +- Version 2.2.3 ergänzt einen versionsübergreifenden Installer-Schutz: Der + tatsächliche Servicevertrag der vorhandenen und der neuen EXE wird vor dem + Task-Stopp verglichen. Unbestätigte Renames, neue oder entfernte Services + blockieren das Update; die Differenz wird vollständig angezeigt. ### Korrekte Abdeckungssemantik @@ -131,7 +135,9 @@ Endpoint-/Namensfix bewusst nicht grüngefärbt. ## ACC-Abnahme nach Installation -1. Setup 2.2.2 als Update ausführen; Umgebung `ACC` kann bestehen bleiben. +1. Setup 2.2.3 als Update ausführen; Umgebung `ACC` kann bestehen bleiben. + Beim Wechsel von der fehlerhaften 2.2.1-Ausgabe `BizTalk ACC ...` auf die + stabilen Namen die Rename-/Discovery-Checkbox bewusst aktivieren. 2. In der installierten Config bestätigen: ```text diff --git a/docs/BizTalk_Checkmk_Pulse_Architekturueberblick.docx b/docs/BizTalk_Checkmk_Pulse_Architekturueberblick.docx index 37e7de30f679f35bcc673d4f2bd47e0bc13ea9b7..d61488eb65b9761c849780721ceb4e91d616d934 100644 GIT binary patch delta 11384 zcmZ9SWl&vBx2-p@ad&rj2u^TRzg9fF?9d+vMh{l58U zR?nV2YOGq_t7>&UkGE)pcW6jTASfUf004jkxJA|>Z9qV}MK+v4kV1gnA`$deP_&oV zApihZC;$K*005XdnkumR{mOtP3#RU@?tGf zPANo(l<^rd=ZNWMIRIamz*&n^QR=fA6P$}k;of&dqEMe>ua)@$%z3T$L{w7U(i9ek zkf?_;szuSVcthNNs@DM7FG>jn&{h&)oU)5a>j2_->_8tQ0iuXRsD$5?F16)|07-T? zG7*B92C4ztDhTSkOyoS5Vyv|@7*ADxoVb&!1F3C`1{rRN?_mB9{C9UBSJG+%*W;YX z{=#ZJW@H}XIga;6GW{r)MG@WK`JY#$3)XV{pqc_ADlhsW|b_0YvfSf!e}{1b19++YzT{qIZJxWB3R#e2>NkBE2jKZZCAi33apo z?H2s!#b?u0Q;z{1#z%ObVLk^BwLOn9@O?wEhE;dJDkm-SM=$tmC)<{fu(`!+z7C^qQF8kYx%YzKwSIgwkmV3sdX5@AI&8)ogn&GD+$a z);UFX&m3kkX6;##;KR1XrUb<cExr>!35=XPOcNq8x>MEpDsTS5Z(wswy+HN?cOB9a$dV7?IIl#Y){#=Fj z<)Biw4n!0+rI$fKRzW49mPq(!2w9MF^ zQ^$9gRDAF#9u;3+bbCxxI6A7g+#!|+fNFO7;A}E&V`9W_ch*&XAR&NFP+#b)H(N!FSVvdC0v}3?OSZZO{4(}*fkhL`vZ=Z#4+puBc z`$6iOy*s?<#4Iwo_05=cuh*g+O3RkK-y6z;8$4BdXx}!GyOeYyn~!qROCkhy8j?7I zBK?HY-!C6d8*tB$b6%uy&v%0iS@2)LAE|W(U_BE3AH;P72NEwgM|;5PJnduIDvS%_YwQPfK;rozDF;h{xQ6j6x{dMBAi_7cYSe?L`oFgFZCG?dXeu zlZjRed${(2%g;`yBTs=^Om!h-DD)5v3sG?0#$AJ1i3SSC=MsCCK9PwZ6R@(2n;j44 z?M5C>f8@-o$(0u2^B>?QWL&d~R(-$R97x(LQ!Os?EbyRqYf&vOlF%nKkX%ty;LA`> zhnDg*pQlDGH83?W)zj*lEb>^SZkH2p$9>0q#3y4}5${_by-SP?K$@MpQu|pT1Ka_V z8KGaIKn8GY^(y>m<=Ljl7~H#JM=^`nKu9ut@!ja74flr@Kv_Z~E;b&-R1S23jOJE1 zmU4<2*Jnr9lO%I9=noE#9?veodSyW>83;Nqk-ifZvZilBB^}N47|0>v9Y_khij$+ z9+meI^^60%B6nIhWwEe;h9rTO4&Zw4A_HwkvjOJHPc?%&r&W_09BmYaOm`Yij(dDy z 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 BLKXl3 delta 11268 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 nnd19jP38~IS+v1}K!Fq>5W#", "", - '0 "BizTalk PRD Suspended Instances" biztalk_suspended_total=0;;;0|... Suspended total=0.', - '0 "BizTalk PRD Endpoint Reachability" biztalk_endpoints_active=61;;;0|... Alle 61 aktiven Endpunkte sind erreichbar.', + '0 "BizTalk Suspended Instances" biztalk_suspended_total=0;;;0|... Suspended total=0.', + '0 "BizTalk Endpoint Reachability" biztalk_endpoints_active=61;;;0|... Alle 61 aktiven Endpunkte sind erreichbar.', ), ) add_body(document, "Die Base64-Felder verhindern problematische Trennzeichen im Header; sie sind keine Verschlüsselung. SHA-256 erkennt unvollständige oder veränderte Snapshots. Der Schutz vor unberechtigtem lokalem Zugriff erfolgt über Windows-Dateirechte.") @@ -543,6 +543,7 @@ def build_document(): add_bullet(document, "Getrennte Tageslogs für Provider und Consumer; Standardaufbewahrung 30 Tage.") add_bullet(document, "Erwartet inaktive Receive Locations und Send Ports können exakt allowlisted werden und bleiben als Messwert sichtbar.") add_bullet(document, "Endpoint-Prüfung standardmäßig mit maximal 100 Zielen, 16 parallelen Probes und 3 Sekunden Timeout je Ziel.") + add_bullet(document, "Der Installer vergleicht bei Updates die exakten Checkmk-Servicenamen und stoppt unbestätigte Änderungen, bevor Task oder Programmdateien angefasst werden.") add_heading(document, "Sicherheitsmodell", level=2) add_table( @@ -571,7 +572,7 @@ def build_document(): add_callout(document, "Kernaussage: ", "Ein privilegierter Read-only-Collector sammelt, ein unprivilegierter Consumer validiert und übergibt – Checkmk erhält neun stabile Services statt direkten Zugriff auf BizTalk oder SQL.", fill=LIGHT_GREEN, border=GREEN) add_rich_paragraph( document, - (("Dokumentbasis: Implementierung und Projektdokumentation von BizTalk Checkmk Pulse 2.2.2 sowie Checkmk User Guide „Local checks“, abgerufen am 10. August 2026.", {"size": 7.8, "color": MUTED}),), + (("Dokumentbasis: Implementierung und Projektdokumentation von BizTalk Checkmk Pulse 2.2.3 sowie Checkmk User Guide „Local checks“, abgerufen am 10. August 2026.", {"size": 7.8, "color": MUTED}),), before=8, after=0, ) diff --git a/src/BizTalkCheckmkPulse.Setup/InstallerEngine.cs b/src/BizTalkCheckmkPulse.Setup/InstallerEngine.cs index e9659b7..43431f9 100644 --- a/src/BizTalkCheckmkPulse.Setup/InstallerEngine.cs +++ b/src/BizTalkCheckmkPulse.Setup/InstallerEngine.cs @@ -27,7 +27,13 @@ namespace BizTalkCheckmkPulse.Setup checkmkLocalDirectory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), "checkmk", "agent", "local"); } - public void Install(string account, string password, bool isGmsa, string environmentName, Action report) + public void Install( + string account, + string password, + bool isGmsa, + string environmentName, + bool allowServiceNameChange, + Action report) { Validate(account, password, isGmsa, environmentName); report = report ?? delegate { }; @@ -72,9 +78,21 @@ namespace BizTalkCheckmkPulse.Setup stagedConfig, File.Exists(targetConfig) ? targetConfig : null, environmentName); - RunSelfTest(stagedExe); + var stagedServiceNames = RunSelfTest(stagedExe); report("Update-Staging validiert. Umgebung=" + (effectiveEnvironment.Length == 0 ? "(keine)" : effectiveEnvironment) + "."); + if (File.Exists(targetExe)) + { + var installedServiceNames = RunSelfTest(targetExe); + var serviceNameChange = EnsureServiceNameCompatibility( + installedServiceNames, + stagedServiceNames, + allowServiceNameChange); + report(serviceNameChange.Length == 0 + ? "Checkmk-Servicevertrag unveraendert: keine Service Discovery erforderlich." + : "Checkmk-Service-Rename ausdruecklich bestaetigt; Service Discovery erforderlich. " + serviceNameChange); + } + // Erst nach vollstaendiger Staging-Pruefung wird der laufende Provider angehalten. scheduler.DeleteIfExists(TaskName); taskRemoved = true; @@ -397,7 +415,7 @@ namespace BizTalkCheckmkPulse.Setup new DirectoryInfo(path).SetAccessControl(security); } - private static void RunSelfTest(string executable) + private static IReadOnlyList RunSelfTest(string executable) { var start = new ProcessStartInfo(executable, "--self-test") { @@ -419,7 +437,45 @@ namespace BizTalkCheckmkPulse.Setup var lines = output.Split(new[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries); if (process.ExitCode != 0 || lines.Length != 9 || lines.Any(x => !x.StartsWith("0 ", StringComparison.Ordinal))) throw new InvalidOperationException("Self-Test fehlgeschlagen. Exitcode=" + process.ExitCode + ", Zeilen=" + lines.Length + ". " + error); + + var serviceNames = lines.Select(ExtractServiceName).ToArray(); + if (serviceNames.Distinct(StringComparer.Ordinal).Count() != serviceNames.Length) + throw new InvalidOperationException("Self-Test fehlgeschlagen: Checkmk-Servicenamen sind nicht eindeutig."); + return serviceNames; } } + + private static string ExtractServiceName(string line) + { + var firstQuote = line.IndexOf('"'); + var secondQuote = firstQuote < 0 ? -1 : line.IndexOf('"', firstQuote + 1); + if (firstQuote < 0 || secondQuote <= firstQuote + 1) + throw new InvalidOperationException("Self-Test fehlgeschlagen: Checkmk-Servicename kann nicht gelesen werden: " + line); + return line.Substring(firstQuote + 1, secondQuote - firstQuote - 1); + } + + internal static string EnsureServiceNameCompatibility( + IEnumerable installedServiceNames, + IEnumerable stagedServiceNames, + bool allowServiceNameChange) + { + var installed = new HashSet(installedServiceNames ?? Enumerable.Empty(), StringComparer.Ordinal); + var staged = new HashSet(stagedServiceNames ?? Enumerable.Empty(), StringComparer.Ordinal); + if (installed.SetEquals(staged)) return string.Empty; + + var removed = installed.Except(staged, StringComparer.Ordinal).OrderBy(x => x, StringComparer.Ordinal).ToArray(); + var added = staged.Except(installed, StringComparer.Ordinal).OrderBy(x => x, StringComparer.Ordinal).ToArray(); + var description = "Entfernt=[" + string.Join(", ", removed) + "]; Neu=[" + string.Join(", ", added) + "]."; + if (!allowServiceNameChange) + { + throw new InvalidOperationException( + "Sicherheitsstopp: Das Update wuerde Checkmk-Servicenamen aendern. " + + description + + " Ohne Service Discovery entstehen verwaiste bzw. fehlende Services. " + + "Nur wenn die Aenderung beabsichtigt ist, im Setup 'Service Discovery ist eingeplant' bestaetigen und anschliessend die Discovery ausfuehren."); + } + + return description; + } } } diff --git a/src/BizTalkCheckmkPulse.Setup/MainForm.cs b/src/BizTalkCheckmkPulse.Setup/MainForm.cs index 4931c0b..261f941 100644 --- a/src/BizTalkCheckmkPulse.Setup/MainForm.cs +++ b/src/BizTalkCheckmkPulse.Setup/MainForm.cs @@ -12,6 +12,7 @@ namespace BizTalkCheckmkPulse.Setup private readonly TextBox password = new TextBox(); private readonly ComboBox environment = new ComboBox(); private readonly CheckBox gmsa = new CheckBox(); + private readonly CheckBox allowServiceNameChange = new CheckBox(); private readonly Button install = new Button(); private readonly Button uninstall = new Button(); private readonly TextBox status = new TextBox(); @@ -20,8 +21,8 @@ namespace BizTalkCheckmkPulse.Setup { this.engine = engine; Text = "BizTalk Checkmk Pulse Setup"; - ClientSize = new Size(650, 485); - MinimumSize = new Size(666, 524); + ClientSize = new Size(650, 535); + MinimumSize = new Size(666, 574); StartPosition = FormStartPosition.CenterScreen; Font = new Font("Segoe UI", 9F); @@ -68,18 +69,23 @@ namespace BizTalkCheckmkPulse.Setup if (gmsa.Checked) password.Clear(); }; - install.Location = new Point(190, 267); + allowServiceNameChange.Location = new Point(190, 262); + allowServiceNameChange.Size = new Size(420, 34); + allowServiceNameChange.Text = "Service-Rename ist beabsichtigt; Checkmk Service Discovery ist eingeplant"; + allowServiceNameChange.Enabled = engine.IsInstalled; + + install.Location = new Point(190, 306); install.Size = new Size(200, 34); install.Text = "Installieren / aktualisieren"; install.Click += async delegate { await InstallAsync(); }; - uninstall.Location = new Point(410, 267); + uninstall.Location = new Point(410, 306); uninstall.Size = new Size(200, 34); uninstall.Text = "Deinstallieren"; uninstall.Click += async delegate { await UninstallAsync(); }; - status.Location = new Point(22, 320); - status.Size = new Size(588, 135); + status.Location = new Point(22, 359); + status.Size = new Size(588, 146); status.Multiline = true; status.ReadOnly = true; status.ScrollBars = ScrollBars.Vertical; @@ -89,7 +95,7 @@ namespace BizTalkCheckmkPulse.Setup Controls.AddRange(new Control[] { - title, description, account, password, environment, gmsa, install, uninstall, status + title, description, account, password, environment, gmsa, allowServiceNameChange, install, uninstall, status }); AcceptButton = install; } @@ -114,6 +120,7 @@ namespace BizTalkCheckmkPulse.Setup collectorPassword, collectorIsGmsa, environmentName, + allowServiceNameChange.Checked, Report)); password.Clear(); Report("Installation abgeschlossen. Der Provider-Task wurde einmalig gestartet."); @@ -166,6 +173,7 @@ namespace BizTalkCheckmkPulse.Setup account.Enabled = !busy; environment.Enabled = !busy; gmsa.Enabled = !busy; + allowServiceNameChange.Enabled = !busy && engine.IsInstalled; password.Enabled = !busy && !gmsa.Checked; UseWaitCursor = busy; if (message != null) Report(message); diff --git a/src/BizTalkCheckmkPulse.Setup/Properties/AssemblyInfo.cs b/src/BizTalkCheckmkPulse.Setup/Properties/AssemblyInfo.cs index 5aa7b40..fe5b884 100644 --- a/src/BizTalkCheckmkPulse.Setup/Properties/AssemblyInfo.cs +++ b/src/BizTalkCheckmkPulse.Setup/Properties/AssemblyInfo.cs @@ -6,5 +6,5 @@ using System.Runtime.CompilerServices; [assembly: AssemblyDescription("PowerShell-free installer and updater for BizTalk Checkmk Pulse")] [assembly: AssemblyCompany("BEW")] [assembly: AssemblyProduct("BizTalk Checkmk Pulse")] -[assembly: AssemblyVersion("2.2.2.0")] -[assembly: AssemblyFileVersion("2.2.2.0")] +[assembly: AssemblyVersion("2.2.3.0")] +[assembly: AssemblyFileVersion("2.2.3.0")] diff --git a/src/BizTalkCheckmkPulse/Properties/AssemblyInfo.cs b/src/BizTalkCheckmkPulse/Properties/AssemblyInfo.cs index ff889fc..21e8c35 100644 --- a/src/BizTalkCheckmkPulse/Properties/AssemblyInfo.cs +++ b/src/BizTalkCheckmkPulse/Properties/AssemblyInfo.cs @@ -6,5 +6,5 @@ using System.Reflection; [assembly: AssemblyDescription("Privileged BizTalk data provider and validated Checkmk snapshot consumer")] [assembly: AssemblyCompany("BEW")] [assembly: AssemblyProduct("BizTalk Checkmk Pulse")] -[assembly: AssemblyVersion("2.2.2.0")] -[assembly: AssemblyFileVersion("2.2.2.0")] +[assembly: AssemblyVersion("2.2.3.0")] +[assembly: AssemblyFileVersion("2.2.3.0")] diff --git a/tests/BizTalkCheckmkPulse.Tests/Program.cs b/tests/BizTalkCheckmkPulse.Tests/Program.cs index cbd3538..08c7765 100644 --- a/tests/BizTalkCheckmkPulse.Tests/Program.cs +++ b/tests/BizTalkCheckmkPulse.Tests/Program.cs @@ -37,6 +37,13 @@ namespace BizTalkCheckmkPulse.Tests Run("EndpointOutputListsOnlyUnavailableTargets", EndpointOutputListsOnlyUnavailableTargets); Run("EndpointOutputExplainsOnlyRealResolutionGaps", EndpointOutputExplainsOnlyRealResolutionGaps); Run("EndpointProbeBudgetFitsMinuteInterval", EndpointProbeBudgetFitsMinuteInterval); +<<<<<<< HEAD +======= + Run("EnvironmentLabelDoesNotRenameServicesByDefault", EnvironmentLabelDoesNotRenameServicesByDefault); + Run("DefaultServiceContractIsExact", DefaultServiceContractIsExact); + Run("InstallerRejectsUnconfirmedServiceRename", InstallerRejectsUnconfirmedServiceRename); + Run("InstallerAllowsConfirmedServiceRename", InstallerAllowsConfirmedServiceRename); +>>>>>>> e694e4c (Guard Checkmk service renames during updates) Run("InstallerUpdatePreservesExistingSettings", InstallerUpdatePreservesExistingSettings); Run("SnapshotRoundTripPreservesLines", SnapshotRoundTripPreservesLines); Run("SnapshotRejectsTampering", SnapshotRejectsTampering); @@ -683,6 +690,82 @@ namespace BizTalkCheckmkPulse.Tests Assert(configuredMaximum <= 30000, "configured endpoint worst-case must leave headroom in the minute interval"); } +<<<<<<< HEAD +======= + private static void EnvironmentLabelDoesNotRenameServicesByDefault() + { + var options = new MonitoringOptions { EnvironmentName = "ACC" }; + var lines = new CheckmkLocalFormatter(options).FormatSelfTest().ToArray(); + Assert(lines.Any(x => x.Contains("\"BizTalk Platform\"")), "stable service name without environment missing"); + Assert(lines.All(x => x.IndexOf("\"BizTalk ACC ", StringComparison.Ordinal) < 0), "environment label must not rename services by default"); + + options.IncludeEnvironmentInServiceName = true; + lines = new CheckmkLocalFormatter(options).FormatSelfTest().ToArray(); + Assert(lines.Any(x => x.Contains("\"BizTalk ACC Platform\"")), "explicit environment service-name opt-in missing"); + } + + private static void DefaultServiceContractIsExact() + { + var actual = new CheckmkLocalFormatter(new MonitoringOptions()) + .FormatSelfTest() + .Select(ExtractQuotedServiceName) + .ToArray(); + var expected = new[] + { + "BizTalk Platform", + "BizTalk SQL Access", + "BizTalk Suspended Instances", + "BizTalk Host Instances", + "BizTalk Receive Locations", + "BizTalk Send Ports", + "BizTalk Endpoint Reachability", + "BizTalk Orchestrations", + "BizTalk Event Log" + }; + AssertEqual(string.Join("|", expected), string.Join("|", actual), "exact default service contract"); + } + + private static void InstallerRejectsUnconfirmedServiceRename() + { + try + { + BizTalkCheckmkPulse.Setup.InstallerEngine.EnsureServiceNameCompatibility( + new[] { "BizTalk Platform", "BizTalk Event Log" }, + new[] { "BizTalk ACC Platform", "BizTalk ACC Event Log" }, + false); + throw new InvalidOperationException("unconfirmed rename was accepted"); + } + catch (InvalidOperationException ex) + { + Assert(ex.Message.Contains("Sicherheitsstopp"), "rename rejection must explain the safety stop"); + Assert(ex.Message.Contains("Service Discovery"), "rename rejection must require discovery"); + } + } + + private static void InstallerAllowsConfirmedServiceRename() + { + var unchanged = BizTalkCheckmkPulse.Setup.InstallerEngine.EnsureServiceNameCompatibility( + new[] { "BizTalk Platform", "BizTalk Event Log" }, + new[] { "BizTalk Event Log", "BizTalk Platform" }, + false); + AssertEqual(string.Empty, unchanged, "service ordering must not be treated as rename"); + + var change = BizTalkCheckmkPulse.Setup.InstallerEngine.EnsureServiceNameCompatibility( + new[] { "BizTalk ACC Platform" }, + new[] { "BizTalk Platform" }, + true); + Assert(change.Contains("BizTalk ACC Platform"), "confirmed rename must report removed service"); + Assert(change.Contains("BizTalk Platform"), "confirmed rename must report new service"); + } + + private static string ExtractQuotedServiceName(string line) + { + var start = line.IndexOf('"') + 1; + var end = line.IndexOf('"', start); + return line.Substring(start, end - start); + } + +>>>>>>> e694e4c (Guard Checkmk service renames during updates) private static void InstallerUpdatePreservesExistingSettings() { var directory = Path.Combine(Path.GetTempPath(), "BizTalkCheckmkPulse.InstallerTests." + Guid.NewGuid().ToString("N"));