Skip to content

Commit c12d0ba

Browse files
author
rhamlett_microsoft
committed
Removed safety limits from configuration files.
1 parent b4f33ef commit c12d0ba

File tree

12 files changed

+49
-235
lines changed

12 files changed

+49
-235
lines changed

src/PerfProblemSimulator/Models/ProblemSimulatorOptions.cs

Lines changed: 0 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -4,65 +4,13 @@ namespace PerfProblemSimulator.Models;
44
/// Configuration options for the Performance Problem Simulator.
55
/// Loaded from the "ProblemSimulator" section of appsettings.json.
66
/// </summary>
7-
/// <remarks>
8-
/// <para>
9-
/// <strong>Educational Note:</strong> These limits are crucial for preventing the simulator
10-
/// from accidentally causing permanent damage to the host system. In production applications,
11-
/// similar limits should be applied to any resource-intensive operations.
12-
/// </para>
13-
/// <para>
14-
/// The options pattern (<c>IOptions&lt;ProblemSimulatorOptions&gt;</c>) allows these values
15-
/// to be easily overridden per environment (development vs production) and supports
16-
/// hot reloading via <c>IOptionsMonitor&lt;T&gt;</c>.
17-
/// </para>
18-
/// </remarks>
197
public class ProblemSimulatorOptions
208
{
219
/// <summary>
2210
/// Configuration section name in appsettings.json.
2311
/// </summary>
2412
public const string SectionName = "ProblemSimulator";
2513

26-
/// <summary>
27-
/// Maximum duration in seconds for CPU stress simulation.
28-
/// Prevents runaway CPU consumption.
29-
/// </summary>
30-
/// <remarks>
31-
/// Default: 300 seconds (5 minutes). This provides enough time to observe metrics
32-
/// and practice diagnosis without risking long-term system instability.
33-
/// </remarks>
34-
public int MaxCpuDurationSeconds { get; set; } = 300;
35-
36-
/// <summary>
37-
/// Maximum memory that can be allocated in megabytes.
38-
/// Prevents the application from consuming all available system memory.
39-
/// </summary>
40-
/// <remarks>
41-
/// Default: 1024 MB (1 GB). This is enough to cause visible memory pressure
42-
/// on most systems without triggering out-of-memory conditions.
43-
/// </remarks>
44-
public int MaxMemoryAllocationMb { get; set; } = 1024;
45-
46-
/// <summary>
47-
/// Maximum delay in milliseconds for thread blocking simulation.
48-
/// Limits how long individual threads can be blocked.
49-
/// </summary>
50-
/// <remarks>
51-
/// Default: 30000 ms (30 seconds). Long enough to demonstrate thread pool
52-
/// starvation effects without permanently blocking threads.
53-
/// </remarks>
54-
public int MaxThreadBlockDelayMs { get; set; } = 30000;
55-
56-
/// <summary>
57-
/// Maximum number of concurrent blocking requests.
58-
/// Limits thread pool exhaustion severity.
59-
/// </summary>
60-
/// <remarks>
61-
/// Default: 200. This is typically enough to exhaust the default thread pool
62-
/// on most systems while remaining manageable.
63-
/// </remarks>
64-
public int MaxConcurrentBlockingRequests { get; set; } = 200;
65-
6614
/// <summary>
6715
/// How often the metrics collector should sample system metrics in milliseconds.
6816
/// </summary>
@@ -71,13 +19,4 @@ public class ProblemSimulatorOptions
7119
/// dashboard updates but consumes more resources.
7220
/// </remarks>
7321
public int MetricsCollectionIntervalMs { get; set; } = 1000;
74-
75-
/// <summary>
76-
/// Whether to log detailed information about simulation requests.
77-
/// </summary>
78-
/// <remarks>
79-
/// Default: true. Useful for understanding what's happening during simulations.
80-
/// May be disabled in production-like testing scenarios for performance.
81-
/// </remarks>
82-
public bool EnableRequestLogging { get; set; } = true;
8322
}

src/PerfProblemSimulator/Services/CpuStressService.cs

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
using Microsoft.Extensions.Options;
21
using PerfProblemSimulator.Models;
32
using System.Diagnostics;
43

@@ -65,7 +64,6 @@ public class CpuStressService : ICpuStressService
6564
{
6665
private readonly ISimulationTracker _simulationTracker;
6766
private readonly ILogger<CpuStressService> _logger;
68-
private readonly ProblemSimulatorOptions _options;
6967

7068
/// <summary>
7169
/// Default duration in seconds when not specified or invalid.
@@ -77,30 +75,23 @@ public class CpuStressService : ICpuStressService
7775
/// </summary>
7876
/// <param name="simulationTracker">Service for tracking active simulations.</param>
7977
/// <param name="logger">Logger for diagnostic information.</param>
80-
/// <param name="options">Configuration options containing limits.</param>
8178
public CpuStressService(
8279
ISimulationTracker simulationTracker,
83-
ILogger<CpuStressService> logger,
84-
IOptions<ProblemSimulatorOptions> options)
80+
ILogger<CpuStressService> logger)
8581
{
8682
_simulationTracker = simulationTracker ?? throw new ArgumentNullException(nameof(simulationTracker));
8783
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
88-
_options = options?.Value ?? throw new ArgumentNullException(nameof(options));
8984
}
9085

9186
/// <inheritdoc />
9287
public Task<SimulationResult> TriggerCpuStressAsync(int durationSeconds, CancellationToken cancellationToken)
9388
{
9489
// ==========================================================================
95-
// STEP 1: Validate and cap the duration
90+
// STEP 1: Validate the duration (no upper limits - app is meant to break)
9691
// ==========================================================================
97-
// We apply defensive programming here - never trust input, always validate.
98-
// This prevents users from accidentally (or intentionally) causing harm by
99-
// requesting extremely long durations.
100-
10192
var actualDuration = durationSeconds <= 0
10293
? DefaultDurationSeconds
103-
: Math.Min(durationSeconds, _options.MaxCpuDurationSeconds);
94+
: durationSeconds;
10495

10596
var simulationId = Guid.NewGuid();
10697
var startedAt = DateTimeOffset.UtcNow;

src/PerfProblemSimulator/Services/MemoryPressureService.cs

Lines changed: 6 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
using Microsoft.Extensions.Options;
21
using PerfProblemSimulator.Models;
32
using System.Runtime.InteropServices;
43

@@ -63,7 +62,6 @@ public class MemoryPressureService : IMemoryPressureService
6362
{
6463
private readonly ISimulationTracker _simulationTracker;
6564
private readonly ILogger<MemoryPressureService> _logger;
66-
private readonly ProblemSimulatorOptions _options;
6765

6866
/// <summary>
6967
/// Thread-safe list holding all allocated memory blocks.
@@ -96,67 +94,34 @@ public class MemoryPressureService : IMemoryPressureService
9694
/// </summary>
9795
/// <param name="simulationTracker">Service for tracking active simulations.</param>
9896
/// <param name="logger">Logger for diagnostic information.</param>
99-
/// <param name="options">Configuration options containing limits.</param>
10097
public MemoryPressureService(
10198
ISimulationTracker simulationTracker,
102-
ILogger<MemoryPressureService> logger,
103-
IOptions<ProblemSimulatorOptions> options)
99+
ILogger<MemoryPressureService> logger)
104100
{
105101
_simulationTracker = simulationTracker ?? throw new ArgumentNullException(nameof(simulationTracker));
106102
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
107-
_options = options?.Value ?? throw new ArgumentNullException(nameof(options));
108103
}
109104

110105
/// <inheritdoc />
111106
public SimulationResult AllocateMemory(int sizeMegabytes)
112107
{
113108
// ==========================================================================
114-
// STEP 1: Validate and constrain the allocation size
109+
// STEP 1: Validate the allocation size (no upper limits - app is meant to break)
115110
// ==========================================================================
116111
var actualSize = sizeMegabytes <= 0
117112
? DefaultSizeMegabytes
118113
: Math.Max(MinimumSizeMegabytes, sizeMegabytes);
119114

120-
// Check against remaining capacity
121115
long currentAllocatedBytes;
122116
lock (_lock)
123117
{
124118
currentAllocatedBytes = _allocatedBlocks.Sum(b => b.SizeBytes);
125119
}
126120

127-
var maxBytes = (long)_options.MaxMemoryAllocationMb * 1024 * 1024;
128-
var remainingCapacity = maxBytes - currentAllocatedBytes;
129-
var requestedBytes = (long)actualSize * 1024 * 1024;
130-
131-
if (requestedBytes > remainingCapacity)
132-
{
133-
// Cap to remaining capacity (minimum 10MB if any space left)
134-
actualSize = (int)(remainingCapacity / (1024 * 1024));
135-
if (actualSize < MinimumSizeMegabytes)
136-
{
137-
actualSize = 0; // Not enough space for minimum allocation
138-
}
139-
}
140-
141-
if (actualSize <= 0)
142-
{
143-
return new SimulationResult
144-
{
145-
SimulationId = Guid.Empty,
146-
Type = SimulationType.Memory,
147-
Status = "Failed",
148-
Message = $"Cannot allocate memory: Maximum allocation limit ({_options.MaxMemoryAllocationMb} MB) reached. " +
149-
"Release existing allocations first with POST /api/memory/release-memory.",
150-
ActualParameters = new Dictionary<string, object>
151-
{
152-
["RequestedSizeMegabytes"] = sizeMegabytes,
153-
["CurrentAllocatedMegabytes"] = currentAllocatedBytes / (1024.0 * 1024.0),
154-
["MaxAllowedMegabytes"] = _options.MaxMemoryAllocationMb
155-
},
156-
StartedAt = DateTimeOffset.UtcNow,
157-
EstimatedEndAt = null
158-
};
159-
}
121+
_logger.LogInformation(
122+
"Allocating {Size} MB. Current total: {Current} MB",
123+
actualSize,
124+
currentAllocatedBytes / (1024.0 * 1024.0));
160125

161126
var simulationId = Guid.NewGuid();
162127
var startedAt = DateTimeOffset.UtcNow;

src/PerfProblemSimulator/Services/ThreadBlockService.cs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
using Microsoft.Extensions.Options;
21
using PerfProblemSimulator.Models;
32

43
namespace PerfProblemSimulator.Services;
@@ -88,7 +87,6 @@ public class ThreadBlockService : IThreadBlockService
8887
{
8988
private readonly ISimulationTracker _simulationTracker;
9089
private readonly ILogger<ThreadBlockService> _logger;
91-
private readonly ProblemSimulatorOptions _options;
9290

9391
/// <summary>
9492
/// Default delay in milliseconds when not specified or invalid.
@@ -110,12 +108,10 @@ public class ThreadBlockService : IThreadBlockService
110108
/// </summary>
111109
public ThreadBlockService(
112110
ISimulationTracker simulationTracker,
113-
ILogger<ThreadBlockService> logger,
114-
IOptions<ProblemSimulatorOptions> options)
111+
ILogger<ThreadBlockService> logger)
115112
{
116113
_simulationTracker = simulationTracker ?? throw new ArgumentNullException(nameof(simulationTracker));
117114
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
118-
_options = options?.Value ?? throw new ArgumentNullException(nameof(options));
119115
}
120116

121117
/// <inheritdoc />
@@ -125,15 +121,15 @@ public Task<SimulationResult> TriggerSyncOverAsyncAsync(
125121
CancellationToken cancellationToken)
126122
{
127123
// ==========================================================================
128-
// STEP 1: Validate and constrain parameters
124+
// STEP 1: Validate parameters (no upper limits - app is meant to break)
129125
// ==========================================================================
130126
var actualDelay = delayMilliseconds <= 0
131127
? DefaultDelayMs
132-
: Math.Max(MinimumDelayMs, Math.Min(delayMilliseconds, _options.MaxThreadBlockDelayMs));
128+
: Math.Max(MinimumDelayMs, delayMilliseconds);
133129

134130
var actualConcurrent = concurrentRequests <= 0
135131
? DefaultConcurrentRequests
136-
: Math.Min(concurrentRequests, _options.MaxConcurrentBlockingRequests);
132+
: concurrentRequests;
137133

138134
var simulationId = Guid.NewGuid();
139135
var startedAt = DateTimeOffset.UtcNow;

src/PerfProblemSimulator/appsettings.Development.json

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,6 @@
88
}
99
},
1010
"ProblemSimulator": {
11-
"MaxCpuDurationSeconds": 60,
12-
"MaxMemoryAllocationMb": 512,
13-
"MaxThreadBlockDelayMs": 10000,
14-
"MaxConcurrentBlockingRequests": 50,
15-
"MetricsCollectionIntervalMs": 500,
16-
"EnableRequestLogging": true
11+
"MetricsCollectionIntervalMs": 500
1712
}
1813
}

src/PerfProblemSimulator/appsettings.json

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,6 @@
88
},
99
"AllowedHosts": "*",
1010
"ProblemSimulator": {
11-
"MaxCpuDurationSeconds": 300,
12-
"MaxMemoryAllocationMb": 512,
13-
"MaxThreadBlockDelayMs": 30000,
14-
"MaxConcurrentBlockingRequests": 1000,
15-
"MetricsCollectionIntervalMs": 1000,
16-
"EnableRequestLogging": true
11+
"MetricsCollectionIntervalMs": 1000
1712
}
1813
}

tests/PerfProblemSimulator.Tests/Integration/CpuEndpointTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ public async Task TriggerHighCpu_WithDefaultValues_UsesDefaults()
6868
}
6969

7070
[Fact]
71-
public async Task TriggerHighCpu_WithExcessiveDuration_CapsToMaximum()
71+
public async Task TriggerHighCpu_WithLargeDuration_UsesRequestedDuration()
7272
{
7373
// Arrange
7474
var request = new { DurationSeconds = 9999 };
@@ -86,7 +86,7 @@ public async Task TriggerHighCpu_WithExcessiveDuration_CapsToMaximum()
8686
var result = await response.Content.ReadFromJsonAsync<JsonElement>(_jsonOptions);
8787
var actualParams = result.GetProperty("actualParameters");
8888
var actualDuration = actualParams.GetProperty("durationSeconds").GetInt32();
89-
Assert.True(actualDuration <= 300, $"Duration should be capped to max (300), was {actualDuration}");
89+
Assert.Equal(9999, actualDuration); // No limits, uses requested value
9090
}
9191

9292
[Fact]

tests/PerfProblemSimulator.Tests/Integration/MemoryEndpointTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ public async Task ReleaseMemory_WhenNothingAllocated_ReturnsZeroCount()
166166
}
167167

168168
[Fact]
169-
public async Task AllocateMemory_WithExcessiveSize_CapsToMaximum()
169+
public async Task AllocateMemory_WithLargeSize_UsesRequestedSize()
170170
{
171171
// Arrange
172172
var request = new { SizeMegabytes = 9999 };
@@ -184,6 +184,6 @@ public async Task AllocateMemory_WithExcessiveSize_CapsToMaximum()
184184
var result = await response.Content.ReadFromJsonAsync<JsonElement>(_jsonOptions);
185185
var actualParams = result.GetProperty("actualParameters");
186186
var actualSize = actualParams.GetProperty("sizeMegabytes").GetInt32();
187-
Assert.True(actualSize <= 1024, $"Size should be capped to max (1024), was {actualSize}");
187+
Assert.Equal(9999, actualSize); // No limits, uses requested value
188188
}
189189
}

tests/PerfProblemSimulator.Tests/Integration/ThreadBlockEndpointTests.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ public async Task TriggerSyncOverAsync_IncludesEstimatedEndTime()
117117
}
118118

119119
[Fact]
120-
public async Task TriggerSyncOverAsync_WithExcessiveDelay_CapsToMaximum()
120+
public async Task TriggerSyncOverAsync_WithLargeDelay_UsesRequestedDelay()
121121
{
122122
// Arrange
123123
var request = new { DelayMilliseconds = 999999 };
@@ -135,11 +135,11 @@ public async Task TriggerSyncOverAsync_WithExcessiveDelay_CapsToMaximum()
135135
var result = await response.Content.ReadFromJsonAsync<JsonElement>(_jsonOptions);
136136
var actualParams = result.GetProperty("actualParameters");
137137
var actualDelay = actualParams.GetProperty("delayMilliseconds").GetInt32();
138-
Assert.True(actualDelay <= 30000, $"Delay should be capped to max (30000), was {actualDelay}");
138+
Assert.Equal(999999, actualDelay); // No limits, uses requested value
139139
}
140140

141141
[Fact]
142-
public async Task TriggerSyncOverAsync_WithExcessiveConcurrency_CapsToMaximum()
142+
public async Task TriggerSyncOverAsync_WithLargeConcurrency_UsesRequestedConcurrency()
143143
{
144144
// Arrange
145145
var request = new { ConcurrentRequests = 9999 };
@@ -157,6 +157,6 @@ public async Task TriggerSyncOverAsync_WithExcessiveConcurrency_CapsToMaximum()
157157
var result = await response.Content.ReadFromJsonAsync<JsonElement>(_jsonOptions);
158158
var actualParams = result.GetProperty("actualParameters");
159159
var actualConcurrent = actualParams.GetProperty("concurrentRequests").GetInt32();
160-
Assert.True(actualConcurrent <= 200, $"Concurrency should be capped to max (200), was {actualConcurrent}");
160+
Assert.Equal(9999, actualConcurrent); // No limits, uses requested value
161161
}
162162
}

0 commit comments

Comments
 (0)