diff --git a/lib/database/adapters/HostAdapter.js b/lib/database/adapters/HostAdapter.js index 487aa2cb6d..6ef6f07ce8 100644 --- a/lib/database/adapters/HostAdapter.js +++ b/lib/database/adapters/HostAdapter.js @@ -34,12 +34,10 @@ class HostAdapter { * @param {SequelizeHost} databaseObject Object to convert. * @returns {Host} Converted entity object. */ - toEntity({ id, hostname, processesExecutions, createdAt, updatedAt }) { + toEntity({ id, hostname, processesExecutions }) { return { id, hostname, - createdAt: createdAt ? new Date(createdAt).getTime() : createdAt, - updatedAt: updatedAt ? new Date(updatedAt).getTime() : updatedAt, processesExecutions: (processesExecutions ?? []).map(this.dplProcessExecutionAdapter.toEntity), }; } diff --git a/lib/database/adapters/dpl/DplDetectorAdapter.js b/lib/database/adapters/dpl/DplDetectorAdapter.js index 354aeeeea0..5090dbf6ed 100644 --- a/lib/database/adapters/dpl/DplDetectorAdapter.js +++ b/lib/database/adapters/dpl/DplDetectorAdapter.js @@ -35,12 +35,10 @@ class DplDetectorAdapter { * @returns {DplDetector} Converted entity object. */ toEntity(databaseObject) { - const { id, name, createdAt, updatedAt, processesExecutions } = databaseObject; + const { id, name, processesExecutions } = databaseObject; return { id, name, - createdAt: createdAt ? new Date(createdAt).getTime() : createdAt, - updatedAt: updatedAt ? new Date(updatedAt).getTime() : updatedAt, processesExecutions: (processesExecutions ?? []).map(this.dplProcessExecutionAdapter.toEntity), }; } diff --git a/lib/database/adapters/dpl/DplProcessAdapter.js b/lib/database/adapters/dpl/DplProcessAdapter.js index b170c6d09d..7c7a868b79 100644 --- a/lib/database/adapters/dpl/DplProcessAdapter.js +++ b/lib/database/adapters/dpl/DplProcessAdapter.js @@ -39,13 +39,11 @@ class DplProcessAdapter { * @param {SequelizeDplProcess} databaseObject Object to convert. * @returns {DplProcess} Converted entity object. */ - toEntity({ id, name, typeId, createdAt, updatedAt, type, processesExecutions }) { + toEntity({ id, name, typeId, type, processesExecutions }) { return { id, name, typeId, - createdAt: createdAt ? new Date(createdAt).getTime() : createdAt, - updatedAt: updatedAt ? new Date(updatedAt).getTime() : updatedAt, type: type ? this.dplProcessTypeAdapter.toEntity(type) : null, processesExecutions: (processesExecutions ?? []).map(this.dplProcessExecutionAdapter.toEntity), }; diff --git a/lib/database/adapters/dpl/DplProcessExecutionAdapter.js b/lib/database/adapters/dpl/DplProcessExecutionAdapter.js index 6ffe4b5ea3..c46019653b 100644 --- a/lib/database/adapters/dpl/DplProcessExecutionAdapter.js +++ b/lib/database/adapters/dpl/DplProcessExecutionAdapter.js @@ -50,7 +50,7 @@ class DplProcessExecutionAdapter { * @returns {DplProcessExecution} Converted entity object. */ toEntity(databaseObject) { - const { id, hostId, processId, detectorId, runNumber, args, createdAt, updatedAt, detector, host, process, run } = databaseObject; + const { id, hostId, processId, detectorId, runNumber, args, detector, host, process, run } = databaseObject; return { id, @@ -59,8 +59,6 @@ class DplProcessExecutionAdapter { detectorId, runNumber, args, - createdAt: createdAt ? new Date(createdAt).getTime() : createdAt, - updatedAt: updatedAt ? new Date(updatedAt).getTime() : updatedAt, detector: detector ? this.dplDetectorAdapter.toEntity(detector) : null, host: host ? this.hostAdapter.toEntity(host) : null, process: process ? this.dplProcessAdapter.toEntity(process) : null, diff --git a/lib/database/adapters/dpl/DplProcessTypeAdapter.js b/lib/database/adapters/dpl/DplProcessTypeAdapter.js index abc30be578..4ecd6ff209 100644 --- a/lib/database/adapters/dpl/DplProcessTypeAdapter.js +++ b/lib/database/adapters/dpl/DplProcessTypeAdapter.js @@ -29,12 +29,10 @@ class DplProcessTypeAdapter { * @param {SequelizeDplProcessType} databaseObject Object to convert. * @returns {DplProcessType} Converted entity object. */ - toEntity({ id, label, createdAt, updatedAt }) { + toEntity({ id, label }) { return { id, label, - createdAt: createdAt ? new Date(createdAt).getTime() : createdAt, - updatedAt: updatedAt ? new Date(updatedAt).getTime() : updatedAt, }; } diff --git a/lib/domain/entities/Host.js b/lib/domain/entities/Host.js index 2eca6bda74..786276ba66 100644 --- a/lib/domain/entities/Host.js +++ b/lib/domain/entities/Host.js @@ -15,8 +15,6 @@ * @typedef Host * @property {number} id * @property {string} hostname - * @property {number} createdAt - * @property {number} updatedAt * @property {DplProcessExecution[]} processesExecutions */ diff --git a/lib/domain/entities/dpl/DplDetector.js b/lib/domain/entities/dpl/DplDetector.js index dbf5a6ee39..546cb6d9b7 100644 --- a/lib/domain/entities/dpl/DplDetector.js +++ b/lib/domain/entities/dpl/DplDetector.js @@ -15,8 +15,6 @@ * @typedef DplDetector * @property {number} id * @property {string} name - * @property {number} createdAt - * @property {number} updatedAt * @property {DplProcessExecution[]} processesExecutions */ diff --git a/lib/domain/entities/dpl/DplProcess.js b/lib/domain/entities/dpl/DplProcess.js index 4ce2c18241..6f9d095f3c 100644 --- a/lib/domain/entities/dpl/DplProcess.js +++ b/lib/domain/entities/dpl/DplProcess.js @@ -16,8 +16,6 @@ * @property {number} id * @property {string} name * @property {number} typeId - * @property {number} createdAt - * @property {number} updatedAt * @property {DplProcessType|null} type * @property {DplProcessExecution[]} processesExecutions */ diff --git a/lib/domain/entities/dpl/DplProcessExecution.js b/lib/domain/entities/dpl/DplProcessExecution.js index 04e356820a..59380fb5c2 100644 --- a/lib/domain/entities/dpl/DplProcessExecution.js +++ b/lib/domain/entities/dpl/DplProcessExecution.js @@ -16,11 +16,9 @@ * @property {number} id * @property {number} runNumber * @property {number} detectorId - * @property {string} processId - * @property {string} hostId - * @property {string} args - * @property {number} createdAt - * @property {number} updatedAt + * @property {number} processId + * @property {number} hostId + * @property {string|null} args * @property {Run|null} run * @property {DplDetector|null} detector * @property {DplProcess|null} process diff --git a/lib/domain/entities/dpl/DplProcessType.js b/lib/domain/entities/dpl/DplProcessType.js index 0d38838267..d43cd4bee2 100644 --- a/lib/domain/entities/dpl/DplProcessType.js +++ b/lib/domain/entities/dpl/DplProcessType.js @@ -15,8 +15,6 @@ * @typedef DplProcessType * @property {number} id * @property {string} label - * @property {number} createdAt - * @property {number} updatedAt */ /** diff --git a/lib/server/api-docs/API.md b/lib/server/api-docs/API.md index 83227440ca..39a512754a 100644 --- a/lib/server/api-docs/API.md +++ b/lib/server/api-docs/API.md @@ -646,3 +646,95 @@ Responses: ```bash curl -g -OJ "$BOOKKEEPING_URL/api/attachments/1?token=$TOKEN" ``` + +## DPL processes + +Processes of the data processing layer (DPL) executed during the runs, by detector, process and host. + +### `GET /dpl-process/detectors` - List the detectors having an executed process in a run + +Operation id: `listDplDetectorsWithExecutedProcesses` + +Returns the detectors that have at least one executed DPL process in the run, sorted by name. Not paginated. This is the first level of the +run details tree of DPL processes: detector, then process (`/dpl-process/processes`), then host (`/dpl-process/hosts`), then executions +(`/dpl-process/executions`). + +| Parameter | In | Type | Required | Notes | +| --- | --- | --- | --- | --- | +| `runNumber` | query | integer | yes | Run number. | + +Responses: + +- `200`: The detectors. +- `400`: The request failed validation. HTTP status is 400 although each error's `status` field is `"422"`. `source.pointer` has the form `/data/attributes//`. +- `404`: The run, the detector, the process or the host does not exist. + +```bash +curl -g "$BOOKKEEPING_URL/api/dpl-process/detectors?runNumber=106&token=$TOKEN" +``` + +### `GET /dpl-process/processes` - List the processes executed for a detector in a run + +Operation id: `listDplProcessesExecutedForDetector` + +Returns the DPL processes that have been executed at least once in the run for the detector, sorted by name, with their type. Not paginated. + +| Parameter | In | Type | Required | Notes | +| --- | --- | --- | --- | --- | +| `runNumber` | query | integer | yes | Run number. | +| `detectorId` | query | integer | yes | Identifier of the detector (the detectors of `GET /detectors`). | + +Responses: + +- `200`: The processes. +- `400`: The request failed validation. HTTP status is 400 although each error's `status` field is `"422"`. `source.pointer` has the form `/data/attributes//`. +- `404`: The run, the detector, the process or the host does not exist. + +```bash +curl -g "$BOOKKEEPING_URL/api/dpl-process/processes?runNumber=106&detectorId=1&token=$TOKEN" +``` + +### `GET /dpl-process/hosts` - List the hosts on which a process was executed for a detector in a run + +Operation id: `listHostsExecutingDplProcess` + +Returns the hosts on which the DPL process has been executed at least once in the run for the detector, sorted by host name. Not paginated. + +| Parameter | In | Type | Required | Notes | +| --- | --- | --- | --- | --- | +| `runNumber` | query | integer | yes | Run number. | +| `detectorId` | query | integer | yes | Identifier of the detector (the detectors of `GET /detectors`). | +| `processId` | query | integer | yes | Identifier of the DPL process. | + +Responses: + +- `200`: The hosts. +- `400`: The request failed validation. HTTP status is 400 although each error's `status` field is `"422"`. `source.pointer` has the form `/data/attributes//`. +- `404`: The run, the detector, the process or the host does not exist. + +```bash +curl -g "$BOOKKEEPING_URL/api/dpl-process/hosts?runNumber=106&detectorId=1&processId=1&token=$TOKEN" +``` + +### `GET /dpl-process/executions` - List the executions of a process on a host for a detector in a run + +Operation id: `listDplProcessExecutions` + +Returns the executions of the DPL process on the host in the run for the detector. Not paginated. + +| Parameter | In | Type | Required | Notes | +| --- | --- | --- | --- | --- | +| `runNumber` | query | integer | yes | Run number. | +| `detectorId` | query | integer | yes | Identifier of the detector (the detectors of `GET /detectors`). | +| `processId` | query | integer | yes | Identifier of the DPL process. | +| `hostId` | query | integer | yes | Host identifier. | + +Responses: + +- `200`: The executions. +- `400`: The request failed validation. HTTP status is 400 although each error's `status` field is `"422"`. `source.pointer` has the form `/data/attributes//`. +- `404`: The run, the detector, the process or the host does not exist. + +```bash +curl -g "$BOOKKEEPING_URL/api/dpl-process/executions?runNumber=106&detectorId=1&processId=1&hostId=1&token=$TOKEN" +``` diff --git a/lib/server/api-docs/index.html b/lib/server/api-docs/index.html index 79ac65edd1..421ae26956 100644 --- a/lib/server/api-docs/index.html +++ b/lib/server/api-docs/index.html @@ -1160,6 +1160,180 @@

Attachments

curl -g -OJ "$BOOKKEEPING_URL/api/attachments/1?token=$TOKEN"
 
+

DPL processes

+

Processes of the data processing layer (DPL) executed during the runs, by detector, process and host.

+
+

GET /dpl-process/detectors - List the detectors having an executed process in a run

+ +

Operation id: listDplDetectorsWithExecutedProcesses

+

Returns the detectors that have at least one executed DPL process in the run, sorted by name. Not paginated. This is the first level of the +run details tree of DPL processes: detector, then process (/dpl-process/processes), then host (/dpl-process/hosts), then executions +(/dpl-process/executions).

+ + + + + + + + + + + + + + + + + +
ParameterInTypeRequiredNotes
runNumberqueryintegeryesRun number.
+

Responses:

+
    +
  • 200: The detectors.
  • +
  • 400: The request failed validation. HTTP status is 400 although each error's status field is "422". source.pointer has the form /data/attributes/<query|params|body>/<field>.
  • +
  • 404: The run, the detector, the process or the host does not exist.
  • +
+
curl -g "$BOOKKEEPING_URL/api/dpl-process/detectors?runNumber=106&token=$TOKEN"
+
+
+
+

GET /dpl-process/processes - List the processes executed for a detector in a run

+ +

Operation id: listDplProcessesExecutedForDetector

+

Returns the DPL processes that have been executed at least once in the run for the detector, sorted by name, with their type. Not paginated.

+ + + + + + + + + + + + + + + + + + + + + + + + +
ParameterInTypeRequiredNotes
runNumberqueryintegeryesRun number.
detectorIdqueryintegeryesIdentifier of the detector (the detectors of GET /detectors).
+

Responses:

+
    +
  • 200: The processes.
  • +
  • 400: The request failed validation. HTTP status is 400 although each error's status field is "422". source.pointer has the form /data/attributes/<query|params|body>/<field>.
  • +
  • 404: The run, the detector, the process or the host does not exist.
  • +
+
curl -g "$BOOKKEEPING_URL/api/dpl-process/processes?runNumber=106&detectorId=1&token=$TOKEN"
+
+
+
+

GET /dpl-process/hosts - List the hosts on which a process was executed for a detector in a run

+ +

Operation id: listHostsExecutingDplProcess

+

Returns the hosts on which the DPL process has been executed at least once in the run for the detector, sorted by host name. Not paginated.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParameterInTypeRequiredNotes
runNumberqueryintegeryesRun number.
detectorIdqueryintegeryesIdentifier of the detector (the detectors of GET /detectors).
processIdqueryintegeryesIdentifier of the DPL process.
+

Responses:

+
    +
  • 200: The hosts.
  • +
  • 400: The request failed validation. HTTP status is 400 although each error's status field is "422". source.pointer has the form /data/attributes/<query|params|body>/<field>.
  • +
  • 404: The run, the detector, the process or the host does not exist.
  • +
+
curl -g "$BOOKKEEPING_URL/api/dpl-process/hosts?runNumber=106&detectorId=1&processId=1&token=$TOKEN"
+
+
+
+

GET /dpl-process/executions - List the executions of a process on a host for a detector in a run

+ +

Operation id: listDplProcessExecutions

+

Returns the executions of the DPL process on the host in the run for the detector. Not paginated.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParameterInTypeRequiredNotes
runNumberqueryintegeryesRun number.
detectorIdqueryintegeryesIdentifier of the detector (the detectors of GET /detectors).
processIdqueryintegeryesIdentifier of the DPL process.
hostIdqueryintegeryesHost identifier.
+

Responses:

+
    +
  • 200: The executions.
  • +
  • 400: The request failed validation. HTTP status is 400 although each error's status field is "422". source.pointer has the form /data/attributes/<query|params|body>/<field>.
  • +
  • 404: The run, the detector, the process or the host does not exist.
  • +
+
curl -g "$BOOKKEEPING_URL/api/dpl-process/executions?runNumber=106&detectorId=1&processId=1&hostId=1&token=$TOKEN"
+
+
Generated from openapi.yaml by npm run docs:api · ALICE Bookkeeping · internal use only
diff --git a/lib/server/api-docs/openapi.yaml b/lib/server/api-docs/openapi.yaml index 4bae027099..ac5613c322 100644 --- a/lib/server/api-docs/openapi.yaml +++ b/lib/server/api-docs/openapi.yaml @@ -59,6 +59,8 @@ tags: description: End-of-shift (EoS) reports written by the shifters. - name: Attachments description: Files attached to log entries. + - name: DPL processes + description: Processes of the data processing layer (DPL) executed during the runs, by detector, process and host. paths: /tags: @@ -792,6 +794,100 @@ paths: example: errors: [{ status: 404, title: Not found, detail: Attachment with this id (999999999) could not be found }] + /dpl-process/detectors: + get: + tags: [DPL processes] + operationId: listDplDetectorsWithExecutedProcesses + summary: List the detectors having an executed process in a run + description: | + Returns the detectors that have at least one executed DPL process in the run, sorted by name. Not paginated. This is the first level of the + run details tree of DPL processes: detector, then process (`/dpl-process/processes`), then host (`/dpl-process/hosts`), then executions + (`/dpl-process/executions`). + parameters: + - $ref: '#/components/parameters/DplRunNumber' + responses: + '200': + description: The detectors. + content: + application/json: + schema: { $ref: '#/components/schemas/DplDetectorListResponse' } + example: + data: + - { id: 1, name: CPV, processesExecutions: [] } + - { id: 2, name: EMC, processesExecutions: [] } + '400': { $ref: '#/components/responses/ValidationError' } + '404': { $ref: '#/components/responses/DplNotFound' } + + /dpl-process/processes: + get: + tags: [DPL processes] + operationId: listDplProcessesExecutedForDetector + summary: List the processes executed for a detector in a run + description: Returns the DPL processes that have been executed at least once in the run for the detector, sorted by name, with their type. Not paginated. + parameters: + - $ref: '#/components/parameters/DplRunNumber' + - $ref: '#/components/parameters/DplDetectorId' + responses: + '200': + description: The processes. + content: + application/json: + schema: { $ref: '#/components/schemas/DplProcessListResponse' } + example: + data: + - { id: 1, name: PROCESS-1, typeId: 1, type: { id: 1, label: QcTask }, processesExecutions: [] } + '400': { $ref: '#/components/responses/ValidationError' } + '404': { $ref: '#/components/responses/DplNotFound' } + + /dpl-process/hosts: + get: + tags: [DPL processes] + operationId: listHostsExecutingDplProcess + summary: List the hosts on which a process was executed for a detector in a run + description: Returns the hosts on which the DPL process has been executed at least once in the run for the detector, sorted by host name. Not paginated. + parameters: + - $ref: '#/components/parameters/DplRunNumber' + - $ref: '#/components/parameters/DplDetectorId' + - $ref: '#/components/parameters/DplProcessId' + responses: + '200': + description: The hosts. + content: + application/json: + schema: { $ref: '#/components/schemas/HostListResponse' } + example: + data: + - { id: 1, hostname: flp001, processesExecutions: [] } + '400': { $ref: '#/components/responses/ValidationError' } + '404': { $ref: '#/components/responses/DplNotFound' } + + /dpl-process/executions: + get: + tags: [DPL processes] + operationId: listDplProcessExecutions + summary: List the executions of a process on a host for a detector in a run + description: Returns the executions of the DPL process on the host in the run for the detector. Not paginated. + parameters: + - $ref: '#/components/parameters/DplRunNumber' + - $ref: '#/components/parameters/DplDetectorId' + - $ref: '#/components/parameters/DplProcessId' + - name: hostId + in: query + required: true + description: Host identifier. + schema: { type: integer, minimum: 1, examples: [1] } + responses: + '200': + description: The executions. + content: + application/json: + schema: { $ref: '#/components/schemas/DplProcessExecutionListResponse' } + example: + data: + - { id: 1, hostId: 1, processId: 1, detectorId: 1, runNumber: 106, args: --id QcTask, detector: null, host: null, process: null, run: null } + '400': { $ref: '#/components/responses/ValidationError' } + '404': { $ref: '#/components/responses/DplNotFound' } + components: securitySchemes: jwtQuery: @@ -820,6 +916,25 @@ components: description: Number of items to skip. schema: { type: integer, minimum: 0, default: 0 } + DplRunNumber: + name: runNumber + in: query + required: true + description: Run number. + schema: { type: integer, minimum: 1, examples: [106] } + DplDetectorId: + name: detectorId + in: query + required: true + description: Identifier of the detector (the detectors of `GET /detectors`). + schema: { type: integer, minimum: 1, examples: [1] } + DplProcessId: + name: processId + in: query + required: true + description: Identifier of the DPL process. + schema: { type: integer, minimum: 1, examples: [1] } + responses: ValidationError: description: | @@ -849,6 +964,15 @@ components: example: errors: [{ status: '404', title: 'Tag with this id (999999999) could not be found' }] + DplNotFound: + description: The run, the detector, the process or the host does not exist. + content: + application/json: + schema: { $ref: '#/components/schemas/ErrorResponse' } + example: + errors: + - { status: 404, title: Not found, detail: Run with this run number (999) could not be found } + schemas: Tag: type: object @@ -1231,3 +1355,74 @@ components: required: [data] properties: data: { $ref: '#/components/schemas/StoredAttachment' } + DplDetector: + type: object + required: [id, name] + properties: + id: { type: integer } + name: { type: string, description: 'Detector code, e.g. `ITS`.' } + processesExecutions: { type: array, description: Always empty here., items: { type: object, additionalProperties: true } } + DplDetectorListResponse: + type: object + required: [data] + properties: + data: + type: array + items: { $ref: '#/components/schemas/DplDetector' } + DplProcessType: + type: object + required: [id, label] + properties: + id: { type: integer } + label: { type: string, examples: [QcTask] } + DplProcess: + type: object + required: [id, name] + properties: + id: { type: integer } + name: { type: string } + typeId: { type: integer } + type: { $ref: '#/components/schemas/DplProcessType' } + processesExecutions: { type: array, description: Always empty here., items: { type: object, additionalProperties: true } } + DplProcessListResponse: + type: object + required: [data] + properties: + data: + type: array + items: { $ref: '#/components/schemas/DplProcess' } + Host: + type: object + required: [id, hostname] + properties: + id: { type: integer } + hostname: { type: string, examples: [flp001] } + processesExecutions: { type: array, description: Always empty here., items: { type: object, additionalProperties: true } } + HostListResponse: + type: object + required: [data] + properties: + data: + type: array + items: { $ref: '#/components/schemas/Host' } + DplProcessExecution: + type: object + required: [id, hostId, processId, detectorId, runNumber] + properties: + id: { type: integer } + hostId: { type: integer } + processId: { type: integer } + detectorId: { type: integer } + runNumber: { type: integer } + args: { type: [string, 'null'], description: Arguments of the process. } + detector: { type: 'null', description: Always null here. } + host: { type: 'null', description: Always null here. } + process: { type: 'null', description: Always null here. } + run: { type: 'null', description: Always null here. } + DplProcessExecutionListResponse: + type: object + required: [data] + properties: + data: + type: array + items: { $ref: '#/components/schemas/DplProcessExecution' } diff --git a/lib/server/controllers/dplProcess.controller.js b/lib/server/controllers/dplProcess.controller.js index 0fa95e645a..bc9c039e4b 100644 --- a/lib/server/controllers/dplProcess.controller.js +++ b/lib/server/controllers/dplProcess.controller.js @@ -11,20 +11,24 @@ * or submit itself to any jurisdiction. */ -/* eslint-disable jsdoc/require-param */ - const { dtoValidator } = require('../utilities/index.js'); const { updateExpressResponseFromNativeError } = require('../express/updateExpressResponseFromNativeError.js'); const { DtoFactory } = require('../../domain/dtos/DtoFactory.js'); -const Joi = require('joi'); +const EntityIdDto = require('../../domain/dtos/EntityIdDto.js'); const { dplProcessService } = require('../services/dpl/DplProcessService.js'); /** * Route to fetch all the DPL detectors that have at least one executed process for a given run + * + * @param {Object} request The *request* object represents the HTTP request and has properties for the request query + * string, parameters, body, HTTP headers, and so on. + * @param {Object} response The *response* object represents the HTTP response that an Express app sends when it gets an + * HTTP request. + * @returns {Promise} resolves once the response has been sent */ const getAllDplDetectorsWithExecutedProcessesByRunHandler = async (request, response) => { const requestDto = await dtoValidator( - DtoFactory.queryOnly({ runNumber: Joi.number().required() }), + DtoFactory.queryOnly({ runNumber: EntityIdDto.required() }), request, response, ); @@ -40,12 +44,18 @@ const getAllDplDetectorsWithExecutedProcessesByRunHandler = async (request, resp /** * Route to fetch all the processes that have been executed at least once for a given run and detector + * + * @param {Object} request The *request* object represents the HTTP request and has properties for the request query + * string, parameters, body, HTTP headers, and so on. + * @param {Object} response The *response* object represents the HTTP response that an Express app sends when it gets an + * HTTP request. + * @returns {Promise} resolves once the response has been sent */ const getAllExecutedProcessesByRunAndDplDetectorHandler = async (request, response) => { const requestDto = await dtoValidator( DtoFactory.queryOnly({ - runNumber: Joi.number().required(), - detectorId: Joi.number().required(), + runNumber: EntityIdDto.required(), + detectorId: EntityIdDto.required(), }), request, response, @@ -64,14 +74,20 @@ const getAllExecutedProcessesByRunAndDplDetectorHandler = async (request, respon }; /** - * Route to fetch all the hosts that on which a given process has been executed for a given run and detector + * Route to fetch all the hosts on which a given process has been executed for a given run and detector + * + * @param {Object} request The *request* object represents the HTTP request and has properties for the request query + * string, parameters, body, HTTP headers, and so on. + * @param {Object} response The *response* object represents the HTTP response that an Express app sends when it gets an + * HTTP request. + * @returns {Promise} resolves once the response has been sent */ const getAllHostsWithExecutedProcessByRunAndDplDetectorHandler = async (request, response) => { const requestDto = await dtoValidator( DtoFactory.queryOnly({ - runNumber: Joi.number().required(), - detectorId: Joi.number().required(), - processId: Joi.number().required(), + runNumber: EntityIdDto.required(), + detectorId: EntityIdDto.required(), + processId: EntityIdDto.required(), }), request, response, @@ -92,14 +108,20 @@ const getAllHostsWithExecutedProcessByRunAndDplDetectorHandler = async (request, /** * Route to fetch all executions of a given process on a given host for a given run and detector + * + * @param {Object} request The *request* object represents the HTTP request and has properties for the request query + * string, parameters, body, HTTP headers, and so on. + * @param {Object} response The *response* object represents the HTTP response that an Express app sends when it gets an + * HTTP request. + * @returns {Promise} resolves once the response has been sent */ const getAllProcessExecutionByRunAndDplDetectorAndHostHandler = async (request, response) => { const requestDto = await dtoValidator( DtoFactory.queryOnly({ - runNumber: Joi.number().required(), - detectorId: Joi.number().required(), - processId: Joi.number().required(), - hostId: Joi.number().required(), + runNumber: EntityIdDto.required(), + detectorId: EntityIdDto.required(), + processId: EntityIdDto.required(), + hostId: EntityIdDto.required(), }), request, response, diff --git a/lib/server/services/dpl/DplProcessService.js b/lib/server/services/dpl/DplProcessService.js index 589fba217a..024165812e 100644 --- a/lib/server/services/dpl/DplProcessService.js +++ b/lib/server/services/dpl/DplProcessService.js @@ -17,12 +17,6 @@ const { dplProcessExecutionAdapter, hostAdapter, } = require('../../../database/adapters/index.js'); -const { - DplDetectorRepository, - DplProcessRepository, - HostRepository, - DplProcessExecutionRepository, -} = require('../../../database/repositories/index.js'); const { getRunOrFail } = require('../run/getRunOrFail.js'); const { getDplDetectorOrFail } = require('./getDplDetectorOrFail.js'); const { getDplProcessOrFail } = require('./getDplProcessOrFail.js'); @@ -33,7 +27,13 @@ const { getOrCreateHostByHostname } = require('../host/getOrCreateHost.js'); const { createDplProcessExecution } = require('./createDplProcessExecution.js'); const { getOrCreateDplProcessTypeByLabel } = require('./getOrCreateDplProcessType.js'); const { getDplProcessExecution } = require('./getDplProcessExecution.js'); -const { Op } = require('sequelize'); +const { getAllDplDetectors } = require('./getAllDplDetectors.js'); +const { getAllDplProcessExecutions } = require('./getAllDplProcessExecutions.js'); +const { getAllDplProcesses } = require('./getAllDplProcesses.js'); +const { getAllHosts } = require('../host/getAllHosts.js'); +const { getDplDetectorIdsWithExecutedProcessesInRun } = require('./getDplDetectorIdsWithExecutedProcessesInRun.js'); +const { getDplProcessIdsExecutedInRunByDetector } = require('./getDplProcessIdsExecutedInRunByDetector.js'); +const { getHostIdsWithExecutedDplProcess } = require('./getHostIdsWithExecutedDplProcess.js'); const { cacheAsyncFunction } = require('../../../utilities/cacheAsyncFunction.js'); const cachedGetRunOrFail = cacheAsyncFunction((runIdentifier) => getRunOrFail(runIdentifier) @@ -65,25 +65,11 @@ class DplProcessService { const run = await getRunOrFail(runIdentifier); // Do the requests in two steps because some tests randomly fail, maybe because of a bug in sequelize? - const detectors = await DplDetectorRepository.findAll({ - include: { - association: 'processesExecutions', - where: { - runNumber: run.runNumber, - }, - required: true, - attributes: [], - }, - raw: true, - attributes: ['id'], - order: [['name', 'ASC']], - }); + const detectorIds = await getDplDetectorIdsWithExecutedProcessesInRun(run.runNumber); - const detectorIds = detectors.map(({ id }) => id); - - const sortedDetectors = await DplDetectorRepository.findAll({ - where: { id: { [Op.in]: detectorIds } }, - order: [['name', 'ASC']], + const sortedDetectors = await getAllDplDetectors((queryBuilder) => { + queryBuilder.where('id').oneOf(...detectorIds); + queryBuilder.orderBy('name', 'ASC'); }); return sortedDetectors.map(dplDetectorAdapter.toEntity); @@ -101,27 +87,12 @@ class DplProcessService { const detector = await getDplDetectorOrFail(detectorIdentifier); // Do the requests in two steps because some tests randomly fail, maybe because of a bug in sequelize? - const processes = await DplProcessRepository.findAll({ - include: { - association: 'processesExecutions', - where: { - runNumber: run.runNumber, - detectorId: detector.id, - }, - required: true, - attributes: [], - }, - raw: true, - attributes: ['id'], - order: [['name', 'ASC']], - }); + const processIds = await getDplProcessIdsExecutedInRunByDetector(run.runNumber, detector.id); - const processIds = processes.map(({ id }) => id); - - const sortedProcesses = await DplProcessRepository.findAll({ - where: { id: { [Op.in]: processIds } }, - include: 'type', - order: [['name', 'ASC']], + const sortedProcesses = await getAllDplProcesses((queryBuilder) => { + queryBuilder.where('id').oneOf(...processIds); + queryBuilder.include({ association: 'type' }); + queryBuilder.orderBy('name', 'ASC'); }); return sortedProcesses.map(dplProcessAdapter.toEntity); @@ -141,27 +112,11 @@ class DplProcessService { const process = await getDplProcessOrFail(processIdentifier); // Do the requests in two steps because some tests randomly fail, maybe because of a bug in sequelize? - const hosts = await HostRepository.findAll({ - include: { - association: 'processesExecutions', - where: { - runNumber: run.runNumber, - detectorId: detector.id, - processId: process.id, - }, - required: true, - attributes: [], - order: [['name', 'ASC']], - }, - raw: true, - attributes: ['id'], - }); - - const hostIds = hosts.map(({ id }) => id); + const hostIds = await getHostIdsWithExecutedDplProcess(run.runNumber, detector.id, process.id); - const sortedHosts = await HostRepository.findAll({ - where: { id: { [Op.in]: hostIds } }, - order: [['hostname', 'ASC']], + const sortedHosts = await getAllHosts((queryBuilder) => { + queryBuilder.where('id').oneOf(...hostIds); + queryBuilder.orderBy('hostname', 'ASC'); }); return sortedHosts.map(hostAdapter.toEntity); @@ -184,13 +139,11 @@ class DplProcessService { getHostOrFail(hostIdentifier), ]); - const processExecutions = await DplProcessExecutionRepository.findAll({ - where: { - runNumber: run.runNumber, - detectorId: detector.id, - processId: process.id, - hostId: host.id, - }, + const processExecutions = await getAllDplProcessExecutions((queryBuilder) => { + queryBuilder.where('runNumber').is(run.runNumber); + queryBuilder.where('detectorId').is(detector.id); + queryBuilder.where('processId').is(process.id); + queryBuilder.where('hostId').is(host.id); }); return processExecutions.map(dplProcessExecutionAdapter.toEntity); diff --git a/lib/server/services/dpl/getAllDplDetectors.js b/lib/server/services/dpl/getAllDplDetectors.js new file mode 100644 index 0000000000..57255f938f --- /dev/null +++ b/lib/server/services/dpl/getAllDplDetectors.js @@ -0,0 +1,32 @@ +/** + * @license + * Copyright CERN and copyright holders of ALICE O2. This software is + * distributed under the terms of the GNU General Public License v3 (GPL + * Version 3), copied verbatim in the file "COPYING". + * + * See http://alice-o2.web.cern.ch/license for full licensing information. + * + * In applying this license CERN does not waive the privileges and immunities + * granted to it by virtue of its status as an Intergovernmental Organization + * or submit itself to any jurisdiction. + */ + +const { dataSource } = require('../../../database/DataSource.js'); +const { DplDetectorRepository } = require('../../../database/repositories/index.js'); + +/** + * Find and return the DPL detectors + * + * @param {(function(QueryBuilder):void)|null} [qbConfiguration=null] function called with the find query builder as parameter to add specific + * configuration to the query + * @return {Promise} resolves with the DPL detectors found + */ +exports.getAllDplDetectors = (qbConfiguration = null) => { + const queryBuilder = dataSource.createQueryBuilder(); + + if (qbConfiguration) { + qbConfiguration(queryBuilder); + } + + return DplDetectorRepository.findAll(queryBuilder); +}; diff --git a/lib/server/services/dpl/getAllDplProcessExecutions.js b/lib/server/services/dpl/getAllDplProcessExecutions.js new file mode 100644 index 0000000000..1b7ae60e9d --- /dev/null +++ b/lib/server/services/dpl/getAllDplProcessExecutions.js @@ -0,0 +1,32 @@ +/** + * @license + * Copyright CERN and copyright holders of ALICE O2. This software is + * distributed under the terms of the GNU General Public License v3 (GPL + * Version 3), copied verbatim in the file "COPYING". + * + * See http://alice-o2.web.cern.ch/license for full licensing information. + * + * In applying this license CERN does not waive the privileges and immunities + * granted to it by virtue of its status as an Intergovernmental Organization + * or submit itself to any jurisdiction. + */ + +const { dataSource } = require('../../../database/DataSource.js'); +const { DplProcessExecutionRepository } = require('../../../database/repositories/index.js'); + +/** + * Find and return the DPL processes executions + * + * @param {(function(QueryBuilder):void)|null} [qbConfiguration=null] function called with the find query builder as parameter to add specific + * configuration to the query + * @return {Promise} resolves with the DPL processes executions found + */ +exports.getAllDplProcessExecutions = (qbConfiguration = null) => { + const queryBuilder = dataSource.createQueryBuilder(); + + if (qbConfiguration) { + qbConfiguration(queryBuilder); + } + + return DplProcessExecutionRepository.findAll(queryBuilder); +}; diff --git a/lib/server/services/dpl/getAllDplProcesses.js b/lib/server/services/dpl/getAllDplProcesses.js new file mode 100644 index 0000000000..108975c953 --- /dev/null +++ b/lib/server/services/dpl/getAllDplProcesses.js @@ -0,0 +1,32 @@ +/** + * @license + * Copyright CERN and copyright holders of ALICE O2. This software is + * distributed under the terms of the GNU General Public License v3 (GPL + * Version 3), copied verbatim in the file "COPYING". + * + * See http://alice-o2.web.cern.ch/license for full licensing information. + * + * In applying this license CERN does not waive the privileges and immunities + * granted to it by virtue of its status as an Intergovernmental Organization + * or submit itself to any jurisdiction. + */ + +const { dataSource } = require('../../../database/DataSource.js'); +const { DplProcessRepository } = require('../../../database/repositories/index.js'); + +/** + * Find and return the DPL processes + * + * @param {(function(QueryBuilder):void)|null} [qbConfiguration=null] function called with the find query builder as parameter to add specific + * configuration to the query + * @return {Promise} resolves with the DPL processes found + */ +exports.getAllDplProcesses = (qbConfiguration = null) => { + const queryBuilder = dataSource.createQueryBuilder(); + + if (qbConfiguration) { + qbConfiguration(queryBuilder); + } + + return DplProcessRepository.findAll(queryBuilder); +}; diff --git a/lib/server/services/dpl/getDplDetectorIdsWithExecutedProcessesInRun.js b/lib/server/services/dpl/getDplDetectorIdsWithExecutedProcessesInRun.js new file mode 100644 index 0000000000..c628a63241 --- /dev/null +++ b/lib/server/services/dpl/getDplDetectorIdsWithExecutedProcessesInRun.js @@ -0,0 +1,36 @@ +/** + * @license + * Copyright CERN and copyright holders of ALICE O2. This software is + * distributed under the terms of the GNU General Public License v3 (GPL + * Version 3), copied verbatim in the file "COPYING". + * + * See http://alice-o2.web.cern.ch/license for full licensing information. + * + * In applying this license CERN does not waive the privileges and immunities + * granted to it by virtue of its status as an Intergovernmental Organization + * or submit itself to any jurisdiction. + */ + +const { DplDetectorRepository } = require('../../../database/repositories/index.js'); + +/** + * Return the ids of the DPL detectors that have at least one executed process in a given run, sorted by detector name + * + * @param {number} runNumber the run number of the run + * @return {Promise} resolves with the ids of the DPL detectors + */ +exports.getDplDetectorIdsWithExecutedProcessesInRun = async (runNumber) => { + const detectors = await DplDetectorRepository.findAll({ + include: { + association: 'processesExecutions', + where: { runNumber }, + required: true, + attributes: [], + }, + raw: true, + attributes: ['id'], + order: [['name', 'ASC']], + }); + + return detectors.map(({ id }) => id); +}; diff --git a/lib/server/services/dpl/getDplProcessIdsExecutedInRunByDetector.js b/lib/server/services/dpl/getDplProcessIdsExecutedInRunByDetector.js new file mode 100644 index 0000000000..579ba5200b --- /dev/null +++ b/lib/server/services/dpl/getDplProcessIdsExecutedInRunByDetector.js @@ -0,0 +1,37 @@ +/** + * @license + * Copyright CERN and copyright holders of ALICE O2. This software is + * distributed under the terms of the GNU General Public License v3 (GPL + * Version 3), copied verbatim in the file "COPYING". + * + * See http://alice-o2.web.cern.ch/license for full licensing information. + * + * In applying this license CERN does not waive the privileges and immunities + * granted to it by virtue of its status as an Intergovernmental Organization + * or submit itself to any jurisdiction. + */ + +const { DplProcessRepository } = require('../../../database/repositories/index.js'); + +/** + * Return the ids of the DPL processes that have been executed at least once in a given run for a given DPL detector, sorted by process name + * + * @param {number} runNumber the run number of the run + * @param {number} detectorId the id of the DPL detector + * @return {Promise} resolves with the ids of the DPL processes + */ +exports.getDplProcessIdsExecutedInRunByDetector = async (runNumber, detectorId) => { + const processes = await DplProcessRepository.findAll({ + include: { + association: 'processesExecutions', + where: { runNumber, detectorId }, + required: true, + attributes: [], + }, + raw: true, + attributes: ['id'], + order: [['name', 'ASC']], + }); + + return processes.map(({ id }) => id); +}; diff --git a/lib/server/services/dpl/getHostIdsWithExecutedDplProcess.js b/lib/server/services/dpl/getHostIdsWithExecutedDplProcess.js new file mode 100644 index 0000000000..ae2aa5989d --- /dev/null +++ b/lib/server/services/dpl/getHostIdsWithExecutedDplProcess.js @@ -0,0 +1,38 @@ +/** + * @license + * Copyright CERN and copyright holders of ALICE O2. This software is + * distributed under the terms of the GNU General Public License v3 (GPL + * Version 3), copied verbatim in the file "COPYING". + * + * See http://alice-o2.web.cern.ch/license for full licensing information. + * + * In applying this license CERN does not waive the privileges and immunities + * granted to it by virtue of its status as an Intergovernmental Organization + * or submit itself to any jurisdiction. + */ + +const { HostRepository } = require('../../../database/repositories/index.js'); + +/** + * Return the ids of the hosts on which a given DPL process has been executed in a given run for a given DPL detector + * + * @param {number} runNumber the run number of the run + * @param {number} detectorId the id of the DPL detector + * @param {number} processId the id of the DPL process + * @return {Promise} resolves with the ids of the hosts + */ +exports.getHostIdsWithExecutedDplProcess = async (runNumber, detectorId, processId) => { + const hosts = await HostRepository.findAll({ + include: { + association: 'processesExecutions', + where: { runNumber, detectorId, processId }, + required: true, + attributes: [], + order: [['name', 'ASC']], + }, + raw: true, + attributes: ['id'], + }); + + return hosts.map(({ id }) => id); +}; diff --git a/lib/server/services/host/getAllHosts.js b/lib/server/services/host/getAllHosts.js new file mode 100644 index 0000000000..49ce1d8ee9 --- /dev/null +++ b/lib/server/services/host/getAllHosts.js @@ -0,0 +1,32 @@ +/** + * @license + * Copyright CERN and copyright holders of ALICE O2. This software is + * distributed under the terms of the GNU General Public License v3 (GPL + * Version 3), copied verbatim in the file "COPYING". + * + * See http://alice-o2.web.cern.ch/license for full licensing information. + * + * In applying this license CERN does not waive the privileges and immunities + * granted to it by virtue of its status as an Intergovernmental Organization + * or submit itself to any jurisdiction. + */ + +const { dataSource } = require('../../../database/DataSource.js'); +const { HostRepository } = require('../../../database/repositories/index.js'); + +/** + * Find and return the hosts + * + * @param {(function(QueryBuilder):void)|null} [qbConfiguration=null] function called with the find query builder as parameter to add specific + * configuration to the query + * @return {Promise} resolves with the hosts found + */ +exports.getAllHosts = (qbConfiguration = null) => { + const queryBuilder = dataSource.createQueryBuilder(); + + if (qbConfiguration) { + qbConfiguration(queryBuilder); + } + + return HostRepository.findAll(queryBuilder); +}; diff --git a/test/api/dplProcess.test.js b/test/api/dplProcess.test.js index ddddd57c30..9c51481d85 100644 --- a/test/api/dplProcess.test.js +++ b/test/api/dplProcess.test.js @@ -492,4 +492,25 @@ module.exports = () => { expect(response.body.errors[0].detail).to.equal('"query.hostId" is required'); }); }); + + describe('Validation of the ids', () => { + it('Should return a 400 when an id is not a positive integer', async () => { + for (const [url, query, field, message] of [ + ['/api/dpl-process/detectors', { runNumber: 0 }, 'runNumber', 'must be a positive number'], + ['/api/dpl-process/processes', { runNumber: 106, detectorId: -1 }, 'detectorId', 'must be a positive number'], + ['/api/dpl-process/hosts', { runNumber: 106, detectorId: 1, processId: 0.5 }, 'processId', 'must be an integer'], + [ + '/api/dpl-process/executions', + { runNumber: 106, detectorId: 1, processId: 1, hostId: 0 }, + 'hostId', + 'must be a positive number', + ], + ]) { + const response = await request(server).get(buildUrl(url, query)); + + expect(response.status, url).to.equal(400); + expect(response.body.errors.map(({ detail }) => detail), url).to.eql([`"query.${field}" ${message}`]); + } + }); + }); }; diff --git a/test/lib/server/services/dpl/dplProcessQueries.test.js b/test/lib/server/services/dpl/dplProcessQueries.test.js new file mode 100644 index 0000000000..03a5473acc --- /dev/null +++ b/test/lib/server/services/dpl/dplProcessQueries.test.js @@ -0,0 +1,109 @@ +/** + * @license + * Copyright CERN and copyright holders of ALICE O2. This software is + * distributed under the terms of the GNU General Public License v3 (GPL + * Version 3), copied verbatim in the file "COPYING". + * + * See http://alice-o2.web.cern.ch/license for full licensing information. + * + * In applying this license CERN does not waive the privileges and immunities + * granted to it by virtue of its status as an Intergovernmental Organization + * or submit itself to any jurisdiction. + */ + +const { expect } = require('chai'); +const { + getDplDetectorIdsWithExecutedProcessesInRun, +} = require('../../../../../lib/server/services/dpl/getDplDetectorIdsWithExecutedProcessesInRun.js'); +const { getAllDplDetectors } = require('../../../../../lib/server/services/dpl/getAllDplDetectors.js'); +const { + getDplProcessIdsExecutedInRunByDetector, +} = require('../../../../../lib/server/services/dpl/getDplProcessIdsExecutedInRunByDetector.js'); +const { getAllDplProcesses } = require('../../../../../lib/server/services/dpl/getAllDplProcesses.js'); +const { getHostIdsWithExecutedDplProcess } = require('../../../../../lib/server/services/dpl/getHostIdsWithExecutedDplProcess.js'); +const { getAllHosts } = require('../../../../../lib/server/services/host/getAllHosts.js'); +const { getAllDplProcessExecutions } = require('../../../../../lib/server/services/dpl/getAllDplProcessExecutions.js'); + +module.exports = () => { + describe('getDplDetectorIdsWithExecutedProcessesInRun', () => { + it('should return the ids of the detectors having an executed process in the run, sorted by name', async () => { + expect(await getDplDetectorIdsWithExecutedProcessesInRun(106)).to.eql([1, 2]); + }); + + it('should return an empty list for a run without executed process', async () => { + expect(await getDplDetectorIdsWithExecutedProcessesInRun(999)).to.eql([]); + }); + }); + + describe('getAllDplDetectors', () => { + it('should return the detectors matching the query builder configuration', async () => { + const detectors = await getAllDplDetectors((queryBuilder) => { + queryBuilder.where('id').oneOf(1, 2); + queryBuilder.orderBy('name', 'ASC'); + }); + + expect(detectors.map(({ id }) => id)).to.eql([1, 2]); + }); + + it('should return all the detectors without configuration', async () => { + expect((await getAllDplDetectors()).map(({ id }) => id)).to.include.members([1, 2]); + }); + }); + + describe('getDplProcessIdsExecutedInRunByDetector', () => { + it('should return the ids of the processes executed in the run for the detector, sorted by name', async () => { + expect(await getDplProcessIdsExecutedInRunByDetector(106, 1)).to.eql([1, 3, 2]); + }); + + it('should return an empty list when no process was executed for the detector', async () => { + expect(await getDplProcessIdsExecutedInRunByDetector(106, 999)).to.eql([]); + }); + }); + + describe('getAllDplProcesses', () => { + it('should return the processes matching the query builder configuration, with their type', async () => { + const processes = await getAllDplProcesses((queryBuilder) => { + queryBuilder.where('id').oneOf(1, 2, 3); + queryBuilder.include({ association: 'type' }); + queryBuilder.orderBy('name', 'ASC'); + }); + + expect(processes.map(({ id }) => id)).to.eql([1, 3, 2]); + expect(processes.every(({ type }) => type !== null && typeof type === 'object')).to.be.true; + }); + }); + + describe('getHostIdsWithExecutedDplProcess', () => { + it('should return the ids of the hosts on which the process was executed in the run for the detector', async () => { + expect(await getHostIdsWithExecutedDplProcess(106, 1, 1)).to.have.members([1, 2]); + }); + + it('should return an empty list when the process was not executed for the detector', async () => { + expect(await getHostIdsWithExecutedDplProcess(106, 999, 1)).to.eql([]); + }); + }); + + describe('getAllHosts', () => { + it('should return the hosts matching the query builder configuration, sorted as asked', async () => { + const getHostsIds = async (order) => (await getAllHosts((queryBuilder) => { + queryBuilder.where('id').oneOf(1, 2); + queryBuilder.orderBy('hostname', order); + })).map(({ id }) => id); + + const ascendingIds = await getHostsIds('ASC'); + expect(ascendingIds).to.have.members([1, 2]); + expect(ascendingIds).to.eql([...await getHostsIds('DESC')].reverse()); + }); + }); + + describe('getAllDplProcessExecutions', () => { + it('should return the executions matching the query builder configuration', async () => { + const executions = await getAllDplProcessExecutions((queryBuilder) => { + queryBuilder.where('runNumber').is(106); + }); + + expect(executions).to.not.be.empty; + expect(executions.every(({ runNumber }) => runNumber === 106)).to.be.true; + }); + }); +}; diff --git a/test/lib/server/services/dpl/index.js b/test/lib/server/services/dpl/index.js index fde22a3571..3ceb51fe1d 100644 --- a/test/lib/server/services/dpl/index.js +++ b/test/lib/server/services/dpl/index.js @@ -13,8 +13,10 @@ const { resetDatabaseContent } = require('../../../../utilities/resetDatabaseContent.js'); const DplProcessServiceTest = require('./DplProcessService.test.js'); +const DplProcessQueriesTest = require('./dplProcessQueries.test.js'); module.exports = () => { before(resetDatabaseContent); describe('DplProcessService', DplProcessServiceTest); + describe('DPL process small functions', DplProcessQueriesTest); };