Files
Denso/srcs/RobotNet10/Commons/RobotNet10.NavigationTune/Controllers/TestRunsController.cs
2026-07-03 16:31:37 +07:00

195 lines
6.5 KiB
C#

using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using RobotNet10.NavigationTune.Shared.Interfaces;
using RobotNet10.NavigationTune.Shared.Models;
namespace RobotNet10.NavigationTune.Controllers;
/// <summary>
/// REST API controller for test runs (test history)
/// </summary>
[ApiController]
[Route("api/[controller]")]
public class TestRunsController : ControllerBase
{
private readonly ITestRepository _testRepository;
private readonly ILogger<TestRunsController> _logger;
public TestRunsController(
ITestRepository testRepository,
ILogger<TestRunsController> logger)
{
_testRepository = testRepository;
_logger = logger;
}
/// <summary>
/// Get test runs with optional pagination (returns DTO to avoid abstract TestScenario deserialization on client).
/// Use skip/take for paging; totalCount is returned for paginator.
/// </summary>
[HttpGet]
public async Task<ActionResult<PagedResult<TestRunDto>>> GetAll(
[FromQuery] int? skip = null,
[FromQuery] int? take = null,
[FromQuery] int? limit = null)
{
try
{
int skipVal = skip ?? 0;
int takeVal;
if (limit.HasValue && limit.Value > 0 && !take.HasValue)
takeVal = limit.Value;
else
takeVal = Math.Min(take ?? 50, 500);
var totalCount = await _testRepository.GetCountAsync();
var testRuns = await _testRepository.GetPagedAsync(skipVal, takeVal);
var items = testRuns.Select(ToDto).ToList();
return Ok(new PagedResult<TestRunDto> { TotalCount = totalCount, Items = items });
}
catch (Exception ex)
{
_logger.LogError(ex, "Error getting all test runs");
return StatusCode(500, new { error = "Failed to retrieve test runs" });
}
}
/// <summary>
/// Get test run by ID
/// </summary>
[HttpGet("{id:guid}")]
public async Task<ActionResult<TestRunDto>> GetById(Guid id)
{
try
{
var testRun = await _testRepository.GetByIdAsync(id);
if (testRun == null)
return NotFound(new { error = $"Test run with ID {id} not found" });
return Ok(ToDto(testRun));
}
catch (Exception ex)
{
_logger.LogError(ex, "Error getting test run {Id}", id);
return StatusCode(500, new { error = "Failed to retrieve test run" });
}
}
/// <summary>
/// Get test runs by scenario ID
/// </summary>
[HttpGet("scenario/{scenarioId}")]
public async Task<ActionResult<List<TestRunDto>>> GetByScenario(Guid scenarioId)
{
try
{
var testRuns = await _testRepository.GetByScenarioAsync(scenarioId);
return Ok(testRuns.Select(ToDto).ToList());
}
catch (Exception ex)
{
_logger.LogError(ex, "Error getting test runs for scenario {ScenarioId}", scenarioId);
return StatusCode(500, new { error = "Failed to retrieve test runs" });
}
}
/// <summary>
/// Get test runs by parameter set ID
/// </summary>
[HttpGet("parameterset/{parameterSetId}")]
public async Task<ActionResult<List<TestRunDto>>> GetByParameterSet(Guid parameterSetId)
{
try
{
var testRuns = await _testRepository.GetByParameterSetAsync(parameterSetId);
return Ok(testRuns.Select(ToDto).ToList());
}
catch (Exception ex)
{
_logger.LogError(ex, "Error getting test runs for parameter set {ParameterSetId}", parameterSetId);
return StatusCode(500, new { error = "Failed to retrieve test runs" });
}
}
/// <summary>
/// Get test runs by date range
/// </summary>
[HttpGet("daterange")]
public async Task<ActionResult<List<TestRunDto>>> GetByDateRange(
[FromQuery] DateTime from,
[FromQuery] DateTime to)
{
try
{
var testRuns = await _testRepository.GetByDateRangeAsync(from, to);
return Ok(testRuns.Select(ToDto).ToList());
}
catch (Exception ex)
{
_logger.LogError(ex, "Error getting test runs for date range {From} to {To}", from, to);
return StatusCode(500, new { error = "Failed to retrieve test runs" });
}
}
/// <summary>
/// Delete test run
/// </summary>
[HttpDelete("{id}")]
public async Task<ActionResult> Delete(Guid id)
{
try
{
var existing = await _testRepository.GetByIdAsync(id);
if (existing == null)
return NotFound(new { error = $"Test run with ID {id} not found" });
await _testRepository.DeleteAsync(id);
return NoContent();
}
catch (Exception ex)
{
_logger.LogError(ex, "Error deleting test run {Id}", id);
return StatusCode(500, new { error = "Failed to delete test run" });
}
}
/// <summary>
/// Delete multiple test runs by IDs
/// </summary>
[HttpPost("delete-batch")]
public async Task<ActionResult> DeleteBatch([FromBody] DeleteBatchRequest request)
{
if (request?.Ids == null || request.Ids.Count == 0)
return BadRequest(new { error = "Ids is required and must not be empty" });
try
{
await _testRepository.DeleteManyAsync(request.Ids);
return NoContent();
}
catch (Exception ex)
{
_logger.LogError(ex, "Error deleting test runs batch");
return StatusCode(500, new { error = "Failed to delete test runs" });
}
}
private static TestRunDto ToDto(TestRun r)
{
return new TestRunDto
{
Id = r.Id,
ScenarioId = r.ScenarioId,
ScenarioName = r.Scenario?.Name ?? string.Empty,
ParameterSetId = r.ParameterSetId,
ParameterSetName = r.ParameterSet?.Name ?? string.Empty,
StartTime = r.StartTime,
EndTime = r.EndTime,
Status = r.Status,
Duration = r.Duration,
Notes = r.Notes,
ErrorMessage = r.ErrorMessage,
Metrics = r.Metrics,
SafetyViolations = r.SafetyViolations ?? new List<SafetyViolation>()
};
}
}