From 5e179b6a13bc1d7d420b62f716a82f522c283b99 Mon Sep 17 00:00:00 2001 From: Eugene Molodkin Date: Mon, 25 Nov 2024 18:01:32 +0100 Subject: [PATCH] wip: test-runs controller --- .../evaluation/test-definitions.types.ee.ts | 26 ++++++- .../evaluation/test-runs.controlller.ee.ts | 77 +++++++++++++++++++ packages/cli/src/server.ts | 1 + .../integration/shared/utils/test-server.ts | 1 + 4 files changed, 104 insertions(+), 1 deletion(-) create mode 100644 packages/cli/src/evaluation/test-runs.controlller.ee.ts diff --git a/packages/cli/src/evaluation/test-definitions.types.ee.ts b/packages/cli/src/evaluation/test-definitions.types.ee.ts index 939a37b949..1beb415276 100644 --- a/packages/cli/src/evaluation/test-definitions.types.ee.ts +++ b/packages/cli/src/evaluation/test-definitions.types.ee.ts @@ -13,7 +13,7 @@ export declare namespace TestDefinitionsRequest { type GetOne = AuthenticatedRequest; - type GetMany = AuthenticatedRequest<{}, {}, {}, ListQuery.Params & { includeScopes?: string }> & { + type GetMany = AuthenticatedRequest<{}, {}, {}, ListQuery.Params> & { listQueryOptions: ListQuery.Options; }; @@ -63,3 +63,27 @@ export declare namespace TestMetricsRequest { type Delete = AuthenticatedRequest; } + +// ---------------------------------- +// /test-definitions/:testDefinitionId/runs +// ---------------------------------- + +export declare namespace TestRunsRequest { + namespace RouteParams { + type TestId = { + testDefinitionId: string; + }; + + type TestRunId = { + id: string; + }; + } + + type GetMany = AuthenticatedRequest & { + listQueryOptions: ListQuery.Options; + }; + + type GetOne = AuthenticatedRequest; + + type Delete = AuthenticatedRequest; +} diff --git a/packages/cli/src/evaluation/test-runs.controlller.ee.ts b/packages/cli/src/evaluation/test-runs.controlller.ee.ts new file mode 100644 index 0000000000..09905d0b13 --- /dev/null +++ b/packages/cli/src/evaluation/test-runs.controlller.ee.ts @@ -0,0 +1,77 @@ +import { TestRunRepository } from '@/databases/repositories/test-run.repository.ee'; +import { Delete, Get, RestController } from '@/decorators'; +import { NotFoundError } from '@/errors/response-errors/not-found.error'; +import { TestRunsRequest } from '@/evaluation/test-definitions.types.ee'; +import { getSharedWorkflowIds } from '@/public-api/v1/handlers/workflows/workflows.service'; + +import { TestDefinitionService } from './test-definition.service.ee'; + +@RestController('/evaluation/test-definitions') +export class TestRunsController { + constructor( + private readonly testDefinitionService: TestDefinitionService, + private readonly testRunRepository: TestRunRepository, + ) {} + + // This method is used in multiple places in the controller to get the test definition + // (or just check that it exists and the user has access to it). + private async getTestDefinition( + req: TestRunsRequest.GetOne | TestRunsRequest.GetMany | TestRunsRequest.Delete, + ) { + const { testDefinitionId } = req.params; + + const userAccessibleWorkflowIds = await getSharedWorkflowIds(req.user, ['workflow:read']); + + const testDefinition = await this.testDefinitionService.findOne( + testDefinitionId, + userAccessibleWorkflowIds, + ); + + if (!testDefinition) throw new NotFoundError('Test definition not found'); + + return testDefinition; + } + + @Get('/:testDefinitionId/runs') + async getMany(req: TestRunsRequest.GetMany) { + const { testDefinitionId } = req.params; + + await this.getTestDefinition(req); + + return await this.testRunRepository.find({ + where: { testDefinition: { id: testDefinitionId } }, + }); + } + + @Get('/:testDefinitionId/runs/:id') + async getOne(req: TestRunsRequest.GetOne) { + const { id: testRunId, testDefinitionId } = req.params; + + await this.getTestDefinition(req); + + const testRun = await this.testRunRepository.findOne({ + where: { id: testRunId, testDefinition: { id: testDefinitionId } }, + }); + + if (!testRun) throw new NotFoundError('Test run not found'); + + return testRun; + } + + @Delete('/:testDefinitionId/runs/:id') + async delete(req: TestRunsRequest.GetOne) { + const { id: testRunId, testDefinitionId } = req.params; + + await this.getTestDefinition(req); + + const testRun = await this.testRunRepository.findOne({ + where: { id: testRunId, testDefinition: { id: testDefinitionId } }, + }); + + if (!testRun) throw new NotFoundError('Test run not found'); + + await this.testRunRepository.delete({ id: testRunId }); + + return { success: true }; + } +} diff --git a/packages/cli/src/server.ts b/packages/cli/src/server.ts index a21ad98ac2..03c824a38b 100644 --- a/packages/cli/src/server.ts +++ b/packages/cli/src/server.ts @@ -65,6 +65,7 @@ import '@/external-secrets/external-secrets.controller.ee'; import '@/license/license.controller'; import '@/evaluation/test-definitions.controller.ee'; import '@/evaluation/metrics.controller'; +import '@/evaluation/test-runs.controlller.ee'; import '@/workflows/workflow-history/workflow-history.controller.ee'; import '@/workflows/workflows.controller'; diff --git a/packages/cli/test/integration/shared/utils/test-server.ts b/packages/cli/test/integration/shared/utils/test-server.ts index 208e05e0f1..f1d2917e63 100644 --- a/packages/cli/test/integration/shared/utils/test-server.ts +++ b/packages/cli/test/integration/shared/utils/test-server.ts @@ -281,6 +281,7 @@ export const setupTestServer = ({ case 'evaluation': await import('@/evaluation/metrics.controller'); await import('@/evaluation/test-definitions.controller.ee'); + await import('@/evaluation/test-runs.controlller.ee'); break; } }