Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
184 changes: 123 additions & 61 deletions Controllers/AppController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,27 +9,32 @@ namespace WebApp_AppService.Controllers
public class AppController : ControllerBase
{
private readonly IConfiguration app;
public AppController(IConfiguration configuration)
private readonly ILogger<AppController> _logger;

public AppController(IConfiguration configuration, ILogger<AppController> logger)
{
app = configuration;
_logger = logger;
}

[HttpGet]
[Route("appinvoke")]
public ActionResult<string> appinvoke()
{
_logger.LogWarning("DANGEROUS ENDPOINT: appinvoke called - creates memory leak with 2100 event subscribers");

try
{
Subscriber.CreatePublishers();
_logger.LogError("Memory leak created: 2100 subscribers with 1MB each = ~2.1GB memory leak");
return "Created multiple subscribers to the publisher! WARNING: This creates a memory leak.";
}

catch (Exception ex)
{
_logger.LogError(ex, "Exception in appinvoke endpoint");
Debug.WriteLine(ex.ToString());
return "Error: " + ex.Message;
}

return "Created multiple subscribers to the publisher!";
}
private static Processor p = new Processor();

Expand Down Expand Up @@ -67,91 +72,124 @@ public void ProcessTransaction(Customer customer)
[Route("memleak/{kb}")]
public ActionResult<string> memleak(int kb)
{
int it = (kb * 1000) / 100;
for (int i = 0; i < it; i++)
_logger.LogWarning("DANGEROUS ENDPOINT: memleak called with {KB}KB - will cause memory leak", kb);

try
{
p.ProcessTransaction(new Customer(Guid.NewGuid().ToString()));
}
int it = (kb * 1000) / 100;
_logger.LogWarning("Adding {Iterations} customer objects to static cache (memory leak)", it);

for (int i = 0; i < it; i++)
{
p.ProcessTransaction(new Customer(Guid.NewGuid().ToString()));
}

return "success:memleak";
_logger.LogError("Memory leak created: {KB}KB worth of objects added to static cache", kb);
return $"success:memleak - Added {it} objects to cache (WARNING: Memory leak created)";
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception in memleak endpoint with {KB}KB", kb);
return "Error: " + ex.Message;
}
}

[HttpGet]
[Route("work")]
public async Task<ActionResult<string>> doWork(int? durationInSeconds)
{
var seconds = durationInSeconds ?? 10;
var start = DateTime.UtcNow;
var endTime = start.AddSeconds(seconds);
_logger.LogWarning("High CPU work started for {Seconds} seconds", seconds);

try
{
var start = DateTime.UtcNow;
var endTime = start.AddSeconds(seconds);

double result = 0;
long iterations = 0;
int threadCount = (Environment.ProcessorCount > 2) ? (int)Math.Ceiling((decimal)Environment.ProcessorCount / 2) : 1;
object lockObj = new object();
double result = 0;
long iterations = 0;
int threadCount = (Environment.ProcessorCount > 2) ? (int)Math.Ceiling((decimal)Environment.ProcessorCount / 2) : 1;
object lockObj = new object();

var tasks = new List<Task>();
_logger.LogInformation("Starting high CPU task with {ThreadCount} threads for {Seconds}s", threadCount, seconds);

for (int i = 0; i < threadCount; i++)
{
tasks.Add(Task.Run(() =>
{
double localResult = 0;
long localIterations = 0;
var tasks = new List<Task>();

while (DateTime.UtcNow < endTime)
for (int i = 0; i < threadCount; i++)
{
tasks.Add(Task.Run(() =>
{
// More expensive operations
localResult += Math.Pow(Math.Sin(localIterations), 2) + Math.Cos(localIterations);
localResult += Math.Sqrt(Math.Abs(localResult));
localResult += Math.Log(Math.Abs(localResult) + 1);

// Prime calculation (expensive)
bool isPrime = IsPrime(localIterations % 10000 + 2);
if (isPrime) localResult += 1;

localIterations++;
}
double localResult = 0;
long localIterations = 0;

while (DateTime.UtcNow < endTime)
{
// More expensive operations
localResult += Math.Pow(Math.Sin(localIterations), 2) + Math.Cos(localIterations);
localResult += Math.Sqrt(Math.Abs(localResult));
localResult += Math.Log(Math.Abs(localResult) + 1);

// Prime calculation (expensive)
bool isPrime = IsPrime(localIterations % 10000 + 2);
if (isPrime) localResult += 1;

localIterations++;
}

lock (lockObj)
{
result += localResult;
iterations += localIterations;
}
}));
}

lock (lockObj)
bool IsPrime(long number)
{
if (number < 2) return false;
for (long i = 2; i <= Math.Sqrt(number); i++)
{
result += localResult;
iterations += localIterations;
if (number % i == 0) return false;
}
}));
}
return true;
}

bool IsPrime(long number)
await Task.WhenAll(tasks);

_logger.LogWarning("High CPU work completed: {Iterations:N0} iterations, {Result:F2} result", iterations, result);
return $"High CPU task completed! Iterations: {iterations:N0}, Result: {result:F2} for Duration: {durationInSeconds}";
}
catch (Exception ex)
{
if (number < 2) return false;
for (long i = 2; i <= Math.Sqrt(number); i++)
{
if (number % i == 0) return false;
}
return true;
_logger.LogError(ex, "Exception in work endpoint with duration {Seconds}", seconds);
return "Error: " + ex.Message;
}

await Task.WhenAll(tasks);
return $"High CPU task completed! Iterations: {iterations:N0}, Result: {result:F2} for Duration: {durationInSeconds}";
}

[HttpGet]
[Route("test")]
public ActionResult<string> sayhello()
{
var connectionString = app.GetConnectionString("StorageAccount");
if (string.IsNullOrEmpty(connectionString))
{
throw new InvalidOperationException("Storage account connection string is not configured.");
}

_logger.LogInformation("Storage connection test requested");

try
{
var connectionString = app.GetConnectionString("StorageAccount");
if (string.IsNullOrEmpty(connectionString))
{
_logger.LogError("Storage account connection string is not configured");
throw new InvalidOperationException("Storage account connection string is not configured.");
}

var blobServiceClient = new BlobServiceClient(connectionString);
var accountInfo = blobServiceClient.GetAccountInfo();

_logger.LogInformation("Storage account connection successful");
return "Hello, the storage account is connected successfully! Account Name: ";
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to connect to storage account");
throw new InvalidOperationException($"Failed to connect to storage account: {ex.Message}", ex);
}
}
Expand All @@ -162,14 +200,38 @@ public ActionResult<string> sayhello()
[Route("crash")]
public ActionResult<string> crash()
{
double bytesSize = 0;
while (true || bytesSize < 1_000_000)
_logger.LogCritical("CRITICAL DANGER: Crash endpoint called - will cause OutOfMemory exception and application crash");

try
{
bytesSize += 10 * 1024 * 1024; // 10MB
memoryHog.Add(new byte[10 * 1024 * 1024]); // Allocate 1MB
}
double bytesSize = 0;
int iterations = 0;

while (true || bytesSize < 1_000_000)
{
bytesSize += 10 * 1024 * 1024; // Track 10MB
memoryHog.Add(new byte[10 * 1024 * 1024]); // Allocate 10MB
iterations++;

if (iterations % 10 == 0) // Log every 100MB
{
_logger.LogCritical("Memory allocation: {SizeMB}MB allocated, iteration {Iterations}",
bytesSize / (1024 * 1024), iterations);
}
}

return "success:oomd";
return "success:oomd";
}
catch (OutOfMemoryException ex)
{
_logger.LogCritical(ex, "OutOfMemory exception occurred as expected in crash endpoint");
return "OutOfMemory exception occurred - application may crash";
}
catch (Exception ex)
{
_logger.LogError(ex, "Unexpected exception in crash endpoint");
return "Unexpected error: " + ex.Message;
}
}
}
}
Loading