Add workspace load testing#58
Conversation
There was a problem hiding this comment.
Pull request overview
Adds a Development-only, Admin-protected Razor Page that seeds a “load test” workspace with many checks and synthetic historical check results to exercise dashboard/query performance in SAMA.
Changes:
- Added
/Dev/LoadTestRazor Page + handler to generate a new workspace with N checks. - Seeded synthetic
CheckResulthistory across a configurable number of days for each generated check.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 7 comments.
| File | Description |
|---|---|
| SAMA.Web/Pages/Dev/LoadTest.cshtml.cs | Implements the dev-only POST handler that creates the workspace, checks, and historical check results. |
| SAMA.Web/Pages/Dev/LoadTest.cshtml | Adds a simple form UI to configure and trigger workspace load-test data creation. |
| var userId = User.FindFirstValue(ClaimTypes.NameIdentifier) ?? "system"; | ||
| var workspaceName = string.IsNullOrWhiteSpace(Input.WorkspaceNamePrefix) | ||
| ? $"LoadTest-{DateTimeOffset.UtcNow:yyyy-MM-dd}-{Guid.CreateVersion7():N}" | ||
| : $"{Input.WorkspaceNamePrefix}-{DateTimeOffset.UtcNow:yyyy-MM-dd}-{Guid.CreateVersion7():N}"; |
There was a problem hiding this comment.
Fixed in arktronic@978a027 — capped WorkspaceNamePrefix to 100 - 12 - 32 = 56 chars (reserving room for the -yyyy-MM-dd- + 32-char GUID suffix) so the combined name can never exceed the DB's 100-char limit.
| var lastStatus = "Up"; | ||
| var lastResponseTime = random.Next(20, 500); |
There was a problem hiding this comment.
Fixed in arktronic@1ac985c — replaced the hard-coded "Up"/"Warn"/"Down" strings with CheckStatuses constants throughout.
| if (random.NextDouble() < 0.05) | ||
| { | ||
| status = "Down"; | ||
| responseTime = random.Next(1000, 5000); | ||
| } | ||
| else if (random.NextDouble() < 0.1) | ||
| { | ||
| status = "Warn"; | ||
| responseTime = random.Next(500, 2000); | ||
| } | ||
| else | ||
| { | ||
| status = "Up"; | ||
| responseTime = random.Next(20, 500); | ||
| } | ||
|
|
There was a problem hiding this comment.
Fixed in arktronic@1ac985c — this line now uses CheckStatuses.Up.
| if (status == "Down" && random.NextDouble() < 0.6) | ||
| { | ||
| status = "Warn"; | ||
| responseTime = random.Next(500, 1500); | ||
| } |
There was a problem hiding this comment.
Fixed in arktronic@1ac985c — all status literals in this method now use CheckStatuses.
| Status = status, | ||
| ResponseTimeMs = responseTime, | ||
| StatusCode = status == "Up" ? 200 : (status == "Warn" ? 200 : 0), | ||
| ErrorMessage = status == "Down" ? "Connection failed" : null, |
There was a problem hiding this comment.
Fixed in arktronic@cfa6210 — replaced the nested ternaries with a switch expression over CheckStatuses for the StatusCode/ErrorMessage mapping.
| current = current.AddSeconds(intervalSeconds); | ||
| } | ||
|
|
||
| await dbContext.SaveChangesAsync(); |
There was a problem hiding this comment.
Fixed in arktronic@c8a136c — after seeding each check's historical results, we now look up the tracked Check entity and set LatestStatus/LatestCheckedAt/LatestResponseTimeMs from the loop's final values before saving.
| StatusMessage = $"Created workspace '{workspace.Name}' with {checks.Count} checks and {totalResults} historical results."; | ||
| return RedirectToPage("/Dashboard/Index", new { workspaceId = workspace.Id }); | ||
| } |
There was a problem hiding this comment.
Fixed in arktronic@e64778c — switched to TempData["SuccessMessage"], which the shared layout already renders after a redirect (same pattern as Workspaces/Create), and removed the dead StatusMessage property/alert block.
Workspace.Name is limited to 100 chars, but the load test page appended a date + GUID suffix to an unbounded 100-char prefix, which could exceed the limit and cause SaveChangesAsync to throw. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Replaces hard-coded "Up"/"Warn"/"Down" strings with the existing CheckStatuses constants to avoid typos and stay consistent with the rest of the codebase. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Replaces nested ternaries with a switch on CheckStatuses so the StatusCode/ErrorMessage mapping stays clear and easy to extend if statuses ever change. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
CheckResults were being inserted without updating the owning Check's LatestStatus/LatestCheckedAt/LatestResponseTimeMs, so the dashboard and check list (which read those fields directly) showed load-test checks as pending until the scheduler ran them for real. Also puts the previously-unused lastCheckedAt value to use. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
StatusMessage was set right before redirecting to /Dashboard/Index, so it never rendered. Switch to TempData["SuccessMessage"], which the shared layout already displays after a redirect, matching the pattern used by other create pages (e.g. Workspaces/Create). Removes the now-dead StatusMessage property and its alert block. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
No description provided.