diff --git a/test/api/transfer/list-transfer-stats.test.ts b/test/api/transfer/list-transfer-stats.test.ts new file mode 100644 index 00000000..02d90682 --- /dev/null +++ b/test/api/transfer/list-transfer-stats.test.ts @@ -0,0 +1,80 @@ +import { ListTransferStatsRequest } from '@/lib/core/usecase-models/list-transfer-stats-usecase-models' +import { ListTransferStatsControllerParameters } from '@/lib/infrastructure/controller/list-transfer-stats-controller' +import appContainer from '@/lib/infrastructure/ioc/container-config' +import CONTROLLERS from '@/lib/infrastructure/ioc/ioc-symbols-controllers' +import { BaseController } from '@/lib/sdk/controller' +import { NextApiResponse } from 'next' +import { Readable } from 'stream' +import { MockHttpStreamableResponseFactory } from 'test/fixtures/http-fixtures' +import MockRucioServerFactory, { MockEndpoint } from 'test/fixtures/rucio-server' + +describe('List Transfer Statistics Feature tests', () => { + beforeEach(() => { + fetchMock.doMock() + const transferStatsStream = Readable.from([ + JSON.stringify({ + source_rse_id: '59fcad356a68434cbe8c43737ccb3f83', + dest_rse_id: '328c926f09ea4dc0a5ddfbe62c8e3bd5', + activity: 'Rebalance', + state: 'S', + source_rse: 'SWIFT', + dest_rse: 'AMAZON-BOTO', + account: 'root', + counter: 3, + bytes: 2000000, + }) + ].join('\n')) + + const listTransferStatsEndpoint: MockEndpoint = { + url: `${MockRucioServerFactory.RUCIO_HOST}/requests/metrics`, + method: 'GET', + includes: 'requests/metrics', + response: { + status: 200, + headers: { + 'Content-Type': 'application/x-json-stream', + }, + body: transferStatsStream, + }, + } + + MockRucioServerFactory.createMockRucioServer(true, [listTransferStatsEndpoint]) + }) + afterEach(() => { + fetchMock.dontMock() + }) + it('should list transfer statistics as a stream', async () => { + const res = MockHttpStreamableResponseFactory.getMockResponse() + + const controller = appContainer.get< + BaseController + >(CONTROLLERS.LIST_TRANSFER_STATS) + const controllerParams: ListTransferStatsControllerParameters = { + rucioAuthToken: MockRucioServerFactory.VALID_RUCIO_TOKEN, + response: res as unknown as NextApiResponse, + } + + await controller.execute(controllerParams) + const receivedData: any[] = [] + const onData = (data: any) => { + receivedData.push(JSON.parse(data)) + } + + const done = new Promise((resolve, reject) => { + res.on('data', onData) + res.on('end', () => { + res.off('data', onData) + resolve() + }) + res.on('error', err => { + res.off('data', onData) + reject(err) + }) + }) + + await done + + expect(receivedData.length).toEqual(1) + expect(receivedData[0].state).toEqual('S') + }) +}) \ No newline at end of file diff --git a/test/api/transfer/list-transfers.test.ts b/test/api/transfer/list-transfers.test.ts new file mode 100644 index 00000000..ee82b012 --- /dev/null +++ b/test/api/transfer/list-transfers.test.ts @@ -0,0 +1,148 @@ +import { ListTransfersRequest } from '@/lib/core/usecase-models/list-transfers-usecase-models' +import { ListTransfersControllerParameters } from '@/lib/infrastructure/controller/list-transfers-controller' +import appContainer from '@/lib/infrastructure/ioc/container-config' +import CONTROLLERS from '@/lib/infrastructure/ioc/ioc-symbols-controllers' +import { BaseController } from '@/lib/sdk/controller' +import { NextApiResponse } from 'next' +import { Readable } from 'stream' +import { MockHttpStreamableResponseFactory } from 'test/fixtures/http-fixtures' +import MockRucioServerFactory, { MockEndpoint } from 'test/fixtures/rucio-server' + +describe('List Transfers Feature tests', () => { + beforeEach(() => { + fetchMock.doMock() + const transferStream = Readable.from([ + JSON.stringify({ + id: 'dummy_transfer_1', + request_type: 'T', + scope: 'test', + name: 'file1', + did_type: 'File', + attributes: '', + retry_count: 0, + rule_id: 'rule1', + bytes: 500000, + activity: 'Rebalance', + state: 'S', + source_rse_id: '59fcad356a68434cbe8c43737ccb3f83', + dest_rse_id: '328c926f09ea4dc0a5ddfbe62c8e3bd5', + source_rse: 'SWIFT', + dest_rse: 'AMAZON-BOTO', + transfertool: 'fts', + priority: 10, + account: 'root', + requested_at: 'Sat, 11 Nov 2023 06:00:00 UTC', + submitted_at: 'Sat, 11 Nov 2023 06:00:10 UTC', + started_at: 'Sat, 11 Nov 2023 06:00:15 UTC', + transferred_at: null, + }), + JSON.stringify({ + id: 'dummy_transfer_2', + request_type: 'T', + scope: 'test', + name: 'file2', + did_type: 'File', + attributes: '', + retry_count: 0, + rule_id: 'rule1', + bytes: 500000, + activity: 'Rebalance', + state: 'S', + source_rse_id: '59fcad356a68434cbe8c43737ccb3f83', + dest_rse_id: '328c926f09ea4dc0a5ddfbe62c8e3bd5', + source_rse: 'SWIFT', + dest_rse: 'AMAZON-BOTO', + transfertool: 'fts', + priority: 10, + account: 'root', + requested_at: 'Sat, 11 Nov 2023 06:00:01 UTC', + submitted_at: 'Sat, 11 Nov 2023 06:00:10 UTC', + started_at: 'Sat, 11 Nov 2023 06:00:15 UTC', + transferred_at: null, + }), + JSON.stringify({ + id: 'dummy_transfer_3', + request_type: 'T', + scope: 'test', + name: 'file3', + did_type: 'File', + attributes: '', + retry_count: 0, + rule_id: 'rule1', + bytes: 1000000, + activity: 'Rebalance', + state: 'S', + source_rse_id: '59fcad356a68434cbe8c43737ccb3f83', + dest_rse_id: '328c926f09ea4dc0a5ddfbe62c8e3bd5', + source_rse: 'SWIFT', + dest_rse: 'AMAZON-BOTO', + transfertool: 'fts', + priority: 10, + account: 'root', + requested_at: 'Sat, 11 Nov 2023 06:00:02 UTC', + submitted_at: 'Sat, 11 Nov 2023 06:00:10 UTC', + started_at: 'Sat, 11 Nov 2023 06:00:15 UTC', + transferred_at: null, + }), + ].join('\n')) + + const listTransfersEndpoint: MockEndpoint = { + url: `${MockRucioServerFactory.RUCIO_HOST}/requests/list?src_rse=SWIFT&dest_rse=AMAZON-BOTO`, + method: 'GET', + includes: 'requests/list?src_rse=SWIFT&dest_rse=AMAZON-BOTO', + response: { + status: 200, + headers: { + 'Content-Type': 'application/x-json-stream', + }, + body: transferStream, + }, + } + + MockRucioServerFactory.createMockRucioServer(true, [listTransfersEndpoint]) + }) + + afterEach(() => { + fetchMock.dontMock() + }) + + it('should list transfers as a stream', async () => { + const res = MockHttpStreamableResponseFactory.getMockResponse() + const controller = appContainer.get< + BaseController + >(CONTROLLERS.LIST_TRANSFERS) + const controllerParams: ListTransfersControllerParameters = { + rucioAuthToken: MockRucioServerFactory.VALID_RUCIO_TOKEN, + response: res as unknown as NextApiResponse, + sourceRSE: 'SWIFT', + destRSE: 'AMAZON-BOTO', + } + + await controller.execute(controllerParams) + + const receivedData: any[] = [] + const onData = (data: any) => { + receivedData.push(JSON.parse(data)) + } + + const done = new Promise((resolve, reject) => { + res.on('data', onData) + res.on('end', () => { + res.off('daat', onData) + resolve() + }) + res.on('error', err => { + res.off('data', onData) + reject(err) + }) + }) + + await done + + expect(receivedData.length).toEqual(3) + receivedData.forEach((d) => { + expect(d.source_rse).toEqual(controllerParams.sourceRSE) + expect(d.dest_rse).toEqual(controllerParams.destRSE) + }) + }) +}) \ No newline at end of file diff --git a/test/gateway/transfer/transfer-gateway-get-transfer-stats.test.ts b/test/gateway/transfer/transfer-gateway-get-transfer-stats.test.ts new file mode 100644 index 00000000..a47d99ed --- /dev/null +++ b/test/gateway/transfer/transfer-gateway-get-transfer-stats.test.ts @@ -0,0 +1,59 @@ +import { ListTransferStatisticsDTO, TransferStatisticsDTO } from "@/lib/core/dto/transfer-dto"; +import { Readable } from "stream"; +import TransferGatewayOutputPort from "@/lib/core/port/secondary/transfer-gateway-output-port"; +import appContainer from "@/lib/infrastructure/ioc/container-config"; +import GATEWAYS from "@/lib/infrastructure/ioc/ioc-symbols-gateway"; +import MockRucioServerFactory, { MockEndpoint } from "test/fixtures/rucio-server"; +import { collectStreamedData } from "test/fixtures/stream-test-utils"; + +describe('TransferGateway Get Transfer Statistics', () => { + beforeEach(() => { + fetchMock.doMock(); + + const transferStatsStream = Readable.from([ + JSON.stringify({ + source_rse_id: '59fcad356a68434cbe8c43737ccb3f83', + dest_rse_id: '328c926f09ea4dc0a5ddfbe62c8e3bd5', + activity: 'Rebalance', + state: 'S', + source_rse: 'SWIFT', + dest_rse: 'AMAZON-BOTO', + account: 'root', + counter: 3, + bytes: 2000000, + }) + ].join('\n')) + + const listTransferStatsEndpoint: MockEndpoint = { + url: `${MockRucioServerFactory.RUCIO_HOST}/requests/metrics`, + method: 'GET', + includes: 'requests/metrics', + response: { + status: 200, + headers: { + 'Content-Type': 'application/x-json-stream', + }, + body: transferStatsStream, + }, + } + + MockRucioServerFactory.createMockRucioServer(true, [listTransferStatsEndpoint]) + }) + afterEach(() => { + fetchMock.dontMock(); + }) + it('should fetch the list of transfer statistics', async () => { + const transferGateway: TransferGatewayOutputPort = appContainer.get(GATEWAYS.TRANSFER) + const listTransferStatisticsDTO: ListTransferStatisticsDTO = await transferGateway.listTransferStatistics( MockRucioServerFactory.VALID_RUCIO_TOKEN ) + expect(listTransferStatisticsDTO.status).toEqual('success') + + const tsStream = listTransferStatisticsDTO.stream + if ( tsStream == null || tsStream == undefined ) { + fail('Transfer Statistics stream is null or undefined') + } + + const receivedData: TransferStatisticsDTO[] = await collectStreamedData(tsStream) + expect(receivedData.length).toEqual(1) + expect(receivedData[0].state).toEqual('S') + }) +}) \ No newline at end of file diff --git a/test/gateway/transfer/transfer-gateway-get-transfers.test.ts b/test/gateway/transfer/transfer-gateway-get-transfers.test.ts new file mode 100644 index 00000000..471615c6 --- /dev/null +++ b/test/gateway/transfer/transfer-gateway-get-transfers.test.ts @@ -0,0 +1,122 @@ +import { ListTransfersDTO, TransferDTO } from "@/lib/core/dto/transfer-dto"; +import TransferGatewayOutputPort from "@/lib/core/port/secondary/transfer-gateway-output-port"; +import appContainer from "@/lib/infrastructure/ioc/container-config"; +import GATEWAYS from "@/lib/infrastructure/ioc/ioc-symbols-gateway"; +import { Readable } from "stream"; +import MockRucioServerFactory, { MockEndpoint } from "test/fixtures/rucio-server"; +import { collectStreamedData } from "test/fixtures/stream-test-utils"; + +describe('TransferGateway', () => { + beforeEach(() => { + fetchMock.doMock(); + const transferStream = Readable.from([ + JSON.stringify({ + id: 'dummy_transfer_1', + request_type: 'T', + scope: 'test', + name: 'file1', + did_type: 'File', + attributes: '', + retry_count: 0, + rule_id: 'rule1', + bytes: 500000, + activity: 'Rebalance', + state: 'S', + source_rse_id: '59fcad356a68434cbe8c43737ccb3f83', + dest_rse_id: '328c926f09ea4dc0a5ddfbe62c8e3bd5', + source_rse: 'SWIFT', + dest_rse: 'AMAZON-BOTO', + transfertool: 'fts', + priority: 10, + account: 'root', + requested_at: 'Sat, 11 Nov 2023 06:00:00 UTC', + submitted_at: 'Sat, 11 Nov 2023 06:00:10 UTC', + started_at: 'Sat, 11 Nov 2023 06:00:15 UTC', + transferred_at: null, + }), + JSON.stringify({ + id: 'dummy_transfer_2', + request_type: 'T', + scope: 'test', + name: 'file2', + did_type: 'File', + attributes: '', + retry_count: 0, + rule_id: 'rule1', + bytes: 500000, + activity: 'Rebalance', + state: 'S', + source_rse_id: '59fcad356a68434cbe8c43737ccb3f83', + dest_rse_id: '328c926f09ea4dc0a5ddfbe62c8e3bd5', + source_rse: 'SWIFT', + dest_rse: 'AMAZON-BOTO', + transfertool: 'fts', + priority: 10, + account: 'root', + requested_at: 'Sat, 11 Nov 2023 06:00:01 UTC', + submitted_at: 'Sat, 11 Nov 2023 06:00:10 UTC', + started_at: 'Sat, 11 Nov 2023 06:00:15 UTC', + transferred_at: null, + }), + JSON.stringify({ + id: 'dummy_transfer_3', + request_type: 'T', + scope: 'test', + name: 'file3', + did_type: 'File', + attributes: '', + retry_count: 0, + rule_id: 'rule1', + bytes: 1000000, + activity: 'Rebalance', + state: 'S', + source_rse_id: '59fcad356a68434cbe8c43737ccb3f83', + dest_rse_id: '328c926f09ea4dc0a5ddfbe62c8e3bd5', + source_rse: 'SWIFT', + dest_rse: 'AMAZON-BOTO', + transfertool: 'fts', + priority: 10, + account: 'root', + requested_at: 'Sat, 11 Nov 2023 06:00:02 UTC', + submitted_at: 'Sat, 11 Nov 2023 06:00:10 UTC', + started_at: 'Sat, 11 Nov 2023 06:00:15 UTC', + transferred_at: null, + }), + ].join('\n')) + + const listTransfersEndpoint: MockEndpoint = { + url: `${MockRucioServerFactory.RUCIO_HOST}/requests/list?src_rse=SWIFT&dest_rse=AMAZON-BOTO`, + method: 'GET', + includes: 'requests/list?src_rse=SWIFT&dest_rse=AMAZON-BOTO', + response: { + status: 200, + headers: { + 'Content-Type': 'application/x-json-stream', + }, + body: transferStream, + }, + } + + MockRucioServerFactory.createMockRucioServer(true, [listTransfersEndpoint]) + }) + afterEach(() => { + fetchMock.dontMock(); + }) + it('Should fetch a list of Transfers', async () => { + const TransferGateway: TransferGatewayOutputPort = appContainer.get(GATEWAYS.TRANSFER) + const listTransfersDTO: ListTransfersDTO = await TransferGateway.listTransfers( MockRucioServerFactory.VALID_RUCIO_TOKEN, 'SWIFT', 'AMAZON-BOTO' ) + expect(listTransfersDTO.status).toEqual('success') + + const transferStream = listTransfersDTO.stream + if (transferStream == null || transferStream == undefined) { + fail('Transfer stream is null or undefined') + } + + const receivedData: TransferDTO[] = await collectStreamedData(transferStream) + expect(receivedData.length).toEqual(3) + receivedData.forEach((d) => { + expect(d.source_rse).toEqual('SWIFT') + expect(d.dest_rse).toEqual('AMAZON-BOTO') + }) + }) +}) \ No newline at end of file