Stufe 4c (#764): Kommentare in C#, WebUI-Skripten, CSS und HTML auf Englisch

Rund 2.600 Kommentarblöcke in 310 C#-Dateien übersetzt, Begründungen vollständig
erhalten: blockweise gleiche Anzahl wie vorher, kein Block unter 60 % seiner
Länge, der Code außerhalb der Kommentare per Tokenizer byte-identisch geprüft.
Zitate deutscher Oberflächentexte und Testdaten bleiben deutsch.

WebUI: Kommentare in JS/CSS/HTML übersetzt, JSDoc-@param an die in 4b
umbenannten Parameter angeglichen.

Dabei behoben:
- 4b hatte "tag" (HTML-Tag) als deutsches "Tag" gelesen und zu "dayValue"
  gemacht (makeElement, svg, Tagesübersicht) - zurück auf tag/day.
- Aufgaben "InProgress" bekamen die Plakettenart "laufend", für die es nie eine
  CSS-Klasse gab - jetzt "success" wie laufende Instanzen.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Richard
2026-10-04 12:45:03 +02:00
co-authored by Claude Opus 5.5
parent da4ceac7d5
commit 837a634a22
311 changed files with 7238 additions and 7252 deletions
@@ -7,16 +7,15 @@ using Shouldly;
namespace ClawdDotNet.Manager.Tests;
/// <summary>
/// „Autostart durch Manager" — der Schalter, der eine Instanz am Laufen hält (#528).
/// "Autostart by manager" — the switch that keeps an instance running (#528).
///
/// <para><b>Zwei Dinge in einem Schalter, weil es dieselbe Zusage ist:</b> Der Manager
/// startet die Instanz beim Hochkommen, und er startet sie nach einem Absturz wieder. Ohne
/// den Schalter rührt er nichts an — ein Manager, der nach einem Neustart der Maschine
/// alles hochfährt, was er findet, startet auch das, was jemand mit Absicht angehalten
/// hat.</para>
/// <para><b>Two things in one switch, because it is the same promise:</b> the manager
/// starts the instance when coming up, and it starts it again after a crash. Without
/// the switch it touches nothing — a manager that boots everything it finds after a restart of the machine
/// also starts what someone stopped on purpose.</para>
///
/// <para><b>Und der Sicherungsautomat ist der eigentliche Inhalt.</b> Wieder hochzufahren
/// ist die einfache Hälfte; die schwierige ist zu erkennen, wann man es lassen muss.</para>
/// <para><b>And the circuit breaker is the actual content.</b> Booting again
/// is the easy half; the hard one is recognizing when to stop.</para>
/// </summary>
public sealed class AutostartTests : IAsyncDisposable
{
@@ -41,9 +40,9 @@ public sealed class AutostartTests : IAsyncDisposable
Directory.CreateDirectory(_root);
_verzeichnisse = new InstanceDirectoryManager(Path.Combine(_root, "Instances"));
// Der Socket antwortet nur, wenn wirklich ein Prozess laeuft - sonst hiesse eine
// vorab hinterlegte Antwort "laeuft schon", und der Manager wuerde uebernehmen
// statt zu starten.
// The socket only answers if a process is really running - otherwise an
// answer stored in advance would mean "already running", and the manager would take over
// instead of starting.
_kanal.Launcher = _launcher;
}
@@ -51,7 +50,7 @@ public sealed class AutostartTests : IAsyncDisposable
{
await Task.CompletedTask;
try { Directory.Delete(_root, recursive: true); }
catch { /* Ein liegengebliebener Testordner faerbt keinen Lauf rot. */ }
catch { /* A leftover test folder does not turn a run red. */ }
}
private ManagerCore Manager(RestartPolicy? policy = null)
@@ -64,7 +63,7 @@ public sealed class AutostartTests : IAsyncDisposable
restartPolicy: policy);
}
/// <summary>Legt eine Instanz an und setzt den Schalter in ihrer Instanzdatei.</summary>
/// <summary>Creates an instance and sets the switch in its instance file.</summary>
private string Instanz(string name, bool autostart)
{
var pfad = _verzeichnisse.CreateInstance(name);
@@ -83,7 +82,7 @@ public sealed class AutostartTests : IAsyncDisposable
InstanceEventKind.Crashed, Path.GetFullPath(pfad), name, 4711, 137,
"unerwartet beendet", DateTimeOffset.UtcNow);
// ─── Beim Hochkommen ───
// ─── When coming up ───
[Fact]
public async Task Eine_Instanz_mit_Autostart_wird_beim_Hochfahren_gestartet()
@@ -110,8 +109,8 @@ public sealed class AutostartTests : IAsyncDisposable
}
/// <summary>
/// Was schon läuft, wird nicht noch einmal gestartet: Ein zweiter Prozess auf derselben
/// <c>state.db</c> wäre das Gegenteil von hilfreich.
/// What is already running is not started again: a second process on the same
/// <c>state.db</c> would be the opposite of helpful.
/// </summary>
[Fact]
public async Task Was_schon_laeuft_wird_nicht_noch_einmal_gestartet()
@@ -143,7 +142,7 @@ public sealed class AutostartTests : IAsyncDisposable
manager.Instances.Instances.Single(i => i.Name == "Ohne").AutostartByManager.ShouldBeFalse();
}
// ─── Nach einem Absturz ───
// ─── After a crash ───
[Fact]
public async Task Nach_einem_Absturz_wird_wieder_gestartet()
@@ -155,7 +154,7 @@ public sealed class AutostartTests : IAsyncDisposable
var vorher = _launcher.Starts;
// Der Prozess ist weg; die Aufsicht hat es gemeldet.
// The process is gone; supervision has reported it.
_launcher.Last!.Exit(137);
await manager.RestartAfterCrashAsync(Absturz(pfad, "Alpha"));
@@ -178,14 +177,14 @@ public sealed class AutostartTests : IAsyncDisposable
}
/// <summary>
/// Eine verstummte Instanz wird beendet und neu gestartet — aber erst, nachdem der
/// alte Prozess nachweislich weg ist.
/// A silent instance is ended and restarted — but only after the
/// old process is provably gone.
///
/// <para><b>Der Fall wird hier wirklich hergestellt und nicht behauptet.</b> Der
/// Prozess lebt weiter, nur der Socket schweigt — genau die Lage aus #529. Ein Test,
/// der stattdessen das Ereignis von Hand baut und die Neustartmethode aufruft, prüft
/// die eine Hälfte, die ohnehin funktioniert, und lässt die gefährliche aus: dass vor
/// dem Start niemand mehr auf der Datenbank sitzt.</para>
/// <para><b>The case is really produced here and not claimed.</b> The
/// process lives on, only the socket is silent — exactly the situation from #529. A test
/// that instead builds the event by hand and calls the restart method checks
/// the half that works anyway, and leaves out the dangerous one: that before
/// the start nobody sits on the database any more.</para>
/// </summary>
[Fact]
public async Task Eine_verstummte_Instanz_wird_erst_beendet_und_dann_neu_gestartet()
@@ -198,24 +197,24 @@ public sealed class AutostartTests : IAsyncDisposable
var alt = _launcher.Last.ShouldNotBeNull();
_launcher.Starts.ShouldBe(1);
// Ab jetzt haengt sie: Der Prozess lebt, der Socket antwortet nicht mehr.
// From now on it hangs: the process lives, the socket no longer answers.
_kanal.Verstummen(pfad);
var aufsicht = manager.Instances.SupervisorFor(pfad).ShouldNotBeNull();
// Drei Durchgaenge bis zum Alarm - vorher wird nichts unternommen.
// Three passes until the alarm - nothing is done before that.
for (var i = 0; i < 3; i++) await aufsicht.CheckAsync();
aufsicht.Condition.ShouldBe(InstanceCondition.Silent);
alt.WasKilled.ShouldBeFalse("Vor Ablauf der Frist wird nicht abgeschossen.");
// Die Frist laeuft ab (SilentKillGrace: 300ms).
// The deadline expires (SilentKillGrace: 300ms).
await Task.Delay(400);
await aufsicht.CheckAsync();
alt.WasKilled.ShouldBeTrue("Nach der Frist wird der haengende Prozess beendet.");
// Der Absturzweg startet neu - und der neue Prozess ist ein anderer.
// The crash path restarts - and the new process is a different one.
await Warte(() => _launcher.Starts >= 2);
_launcher.Last.ShouldNotBeNull().Id.ShouldNotBe(alt.Id);
@@ -223,11 +222,11 @@ public sealed class AutostartTests : IAsyncDisposable
}
/// <summary>
/// Eine Instanz, die aufräumt, wird nicht abgeschossen — auch wenn es dauert.
/// An instance that is cleaning up is not killed — even if it takes a while.
///
/// <para>Sie antwortet ja; sie tut genau das, worum gebeten wurde. Der Unterschied
/// zwischen „hängt" und „räumt auf" ist der ganze Grund, warum der Puls mehr sagt als
/// „jemand hat geantwortet".</para>
/// <para>It does answer; it is doing exactly what it was asked to do. The difference
/// between "hangs" and "cleans up" is the whole reason why the pulse says more than
/// "someone answered".</para>
/// </summary>
[Fact]
public async Task Wer_aufraeumt_gilt_nicht_als_verstummt()
@@ -259,11 +258,11 @@ public sealed class AutostartTests : IAsyncDisposable
}
/// <summary>
/// Nach der Grenze setzt der Manager aus.
/// After the limit the manager pauses.
///
/// <para>Was an einer kaputten Konfiguration scheitert, scheitert beim zehnten Versuch
/// genauso — dann hat man statt einer toten Instanz eine tote Instanz, ein volles
/// Protokoll und einen Bugtracker voller Wiederholungen.</para>
/// <para>What fails because of a broken configuration fails the same way on the tenth attempt
/// — then instead of a dead instance you have a dead instance, a full
/// log and a bug tracker full of repetitions.</para>
/// </summary>
[Fact]
public async Task Nach_drei_Neustarts_im_Zeitfenster_setzt_der_Manager_aus()
@@ -285,8 +284,8 @@ public sealed class AutostartTests : IAsyncDisposable
}
/// <summary>
/// Wer von Hand startet, hat entweder etwas geändert oder weiß, was er tut. Ihm die
/// Versuche von vorhin anzurechnen hieße, ihn für den Absturz zu bestrafen.
/// Whoever starts by hand has either changed something or knows what they are doing. Charging them with
/// the earlier attempts would mean punishing them for the crash.
/// </summary>
[Fact]
public async Task Ein_Start_von_Hand_raeumt_den_Zaehler_ab()
@@ -304,7 +303,7 @@ public sealed class AutostartTests : IAsyncDisposable
var erschoepft = _launcher.Starts;
// Ein neuer Manager faengt bei null an - genau wie ein Start von Hand.
// A new manager starts at zero - just like a start by hand.
await using var frisch = Manager(new RestartPolicy(3, TimeSpan.FromMinutes(10)));
await frisch.StartAsync();
@@ -315,7 +314,7 @@ public sealed class AutostartTests : IAsyncDisposable
}
}
/// <summary>Der Sicherungsautomat für sich genommen.</summary>
/// <summary>The circuit breaker on its own.</summary>
public sealed class RestartLedgerTests
{
private sealed class Uhr(DateTimeOffset jetzt) : TimeProvider
@@ -349,8 +348,8 @@ public sealed class RestartLedgerTests
}
/// <summary>
/// Das Zeitfenster wandert: Eine Instanz, die einmal im Monat abstürzt und wieder
/// hochkommt, läuft nie in die Grenze — eine, die im Minutentakt fällt, sofort.
/// The time window moves: an instance that crashes once a month and comes back
/// up never runs into the limit — one that falls every minute does immediately.
/// </summary>
[Fact]
public void Alte_Versuche_fallen_aus_dem_Fenster()
@@ -383,12 +382,12 @@ public sealed class RestartLedgerTests
}
/// <summary>
/// Ein Start, der auf einen veralteten Merkzettel trifft.
/// A start that meets an outdated note.
///
/// <para><b>Der Defekt, den erst die Autostart-Tests gezeigt haben.</b> Zwischen zwei
/// Aufsichtsdurchgängen liegen Sekunden, und in denen kann eine Instanz wegbrechen. Wer in
/// dieser Lücke „starten" verlangte, bekam „läuft schon" — einen Erfolg, hinter dem nichts
/// stand. Der nächste Durchgang meldete dann einen Absturz, den niemand mehr erwartete.</para>
/// <para><b>The defect that only the autostart tests revealed.</b> Between two
/// supervision passes there are seconds, and in them an instance can break away. Whoever
/// asked to "start" in this gap got "already running" — a success with nothing
/// behind it. The next pass then reported a crash nobody expected any more.</para>
/// </summary>
public sealed class StaleStateTests : IAsyncDisposable
{
@@ -409,7 +408,7 @@ public sealed class StaleStateTests : IAsyncDisposable
{
await Task.CompletedTask;
try { Directory.Delete(_root, recursive: true); }
catch { /* Ein liegengebliebener Testordner faerbt keinen Lauf rot. */ }
catch { /* A leftover test folder does not turn a run red. */ }
}
[Fact]
@@ -421,7 +420,7 @@ public sealed class StaleStateTests : IAsyncDisposable
await using var aufsicht = new InstanceSupervisor(
dir, _launcher, _kanal, NullLogger.Instance,
new SupervisionOptions(
TimeSpan.FromSeconds(30), // absichtlich traege: kein Durchgang dazwischen
TimeSpan.FromSeconds(30), // deliberately sluggish: no pass in between
TimeSpan.FromMilliseconds(600),
3,
TimeSpan.FromMilliseconds(300),
@@ -431,8 +430,8 @@ public sealed class StaleStateTests : IAsyncDisposable
(await aufsicht.StartAsync()).ShouldBeTrue();
aufsicht.Condition.ShouldBe(InstanceCondition.Running);
// Die Instanz bricht weg. Die Aufsicht hat es noch nicht bemerkt - der naechste
// Durchgang kaeme erst in dreissig Sekunden.
// The instance breaks away. Supervision has not noticed yet - the next
// pass would only come in thirty seconds.
_launcher.Last!.Exit(137);
aufsicht.Condition.ShouldBe(InstanceCondition.Running, "Noch nichts bemerkt.");