Files
ClaudeDo/tests/ClaudeDo.Worker.Tests/Usage/UsageThrottleTests.cs
T
mika kuns a201d3f43d chore(claude-do): UsageGate: Parallelitaet stufenweise drosseln statt erst bei
## Kontext: Limits sind Fenster, nicht Summen

Die Runs laufen ueber das Claude-Abo. Limits greifen pro 5h-Fenster und pro 7 Tage. Nicht die Wochensumme tut weh, sondern dass ein Agent-Burst ein Fenster leerraeumt, in dem Mika selbst interaktiv arbeiten will.

## Messgrundlage (alle Transcripts unter ~/.claude/projects)

Agent-Runs sind ueber die ganze Historie nur **18,4 %** des Account-Verbrauch

ClaudeDo-Task: 87105f5e-c4f4-4af4-ae60-89cd2e153e3c
2026-08-05 15:53:15 +02:00

112 lines
2.6 KiB
C#

using ClaudeDo.Worker.Usage;
namespace ClaudeDo.Worker.Tests.Usage;
public sealed class UsageThrottleTests
{
private const int Soft = 50;
private const int Hard = 65;
private const int GateFive = 80;
private const int GateSeven = 90;
private static int Effective(double? five, double? seven, int configured = 3) =>
UsageThrottle.EffectiveSlots(configured, five, seven, Soft, Hard, GateFive, GateSeven);
[Fact]
public void BelowSoftThreshold_ReturnsFullConfiguredSlots()
{
Assert.Equal(3, Effective(30, 40));
}
[Fact]
public void AtSoftThreshold_CapsAtTwo()
{
Assert.Equal(2, Effective(50, 10));
}
[Fact]
public void BetweenSoftAndHard_CapsAtTwo()
{
Assert.Equal(2, Effective(60, 0));
}
[Fact]
public void AtHardThreshold_CapsAtOne()
{
Assert.Equal(1, Effective(65, 0));
}
[Fact]
public void BetweenHardAndGate_CapsAtOne()
{
Assert.Equal(1, Effective(70, 0));
}
[Fact]
public void AtGateThreshold_ReturnsZero()
{
Assert.Equal(0, Effective(80, 0));
}
[Fact]
public void AboveGateThreshold_ReturnsZero()
{
Assert.Equal(0, Effective(95, 0));
}
[Fact]
public void FiveHourAloneDecisive_SevenDayLow()
{
Assert.Equal(1, Effective(70, 5));
}
[Fact]
public void SevenDayAloneDecisive_FiveHourLow()
{
Assert.Equal(1, Effective(5, 70));
}
[Fact]
public void SevenDayAloneAtGate_ReturnsZero()
{
Assert.Equal(0, Effective(10, 90));
}
[Fact]
public void FiveHourAloneAtGate_ReturnsZero()
{
Assert.Equal(0, Effective(80, 10));
}
[Fact]
public void ConfiguredSlotsSmallerThanCap_NeverIncreased()
{
// Soft tier caps at 2, but configured is only 1 — throttle never raises parallelism.
Assert.Equal(1, Effective(55, 0, configured: 1));
}
[Fact]
public void NoUtilizationAtAll_ReturnsFullConfiguredSlots()
{
Assert.Equal(3, Effective(null, null));
}
[Fact]
public void ZeroSoftAndHardThresholds_NeverThrottleBelowGate()
{
Assert.Equal(3, UsageThrottle.EffectiveSlots(3, 79, 89, softPct: 0, hardPct: 0, gateFiveHourPct: GateFive, gateSevenDayPct: GateSeven));
}
[Fact]
public void ZeroGateThresholds_NeverHardBlock()
{
Assert.Equal(1, UsageThrottle.EffectiveSlots(3, 99, 99, softPct: Soft, hardPct: Hard, gateFiveHourPct: 0, gateSevenDayPct: 0));
}
[Fact]
public void ConfiguredSlotsBelowOne_ClampedToOneBeforeThrottling()
{
Assert.Equal(1, Effective(10, 10, configured: 0));
}
}