diff --git a/.github/workflows/e2e-tests.yaml b/.github/workflows/e2e-tests.yaml index d95984401..9267f0257 100644 --- a/.github/workflows/e2e-tests.yaml +++ b/.github/workflows/e2e-tests.yaml @@ -43,8 +43,6 @@ jobs: fi done wget -qO- -S --content-on-error localhost:8080 - - name: 'Cleanup Deployments' - run: pnpm e2e-tests cleanup-deployments - name: 'Execute E2E Tests' run: pnpm test:e2e - name: 'Slack Notification' diff --git a/tests/e2e-tests/README.md b/tests/e2e-tests/README.md index f727d0ff4..f1ac95a03 100644 --- a/tests/e2e-tests/README.md +++ b/tests/e2e-tests/README.md @@ -22,4 +22,4 @@ End-to-end tests for the SAP Cloud SDK for AI. ## Remote Testing -Trigger the [GitHub Action](https://github.com/SAP/ai-sdk-js/actions/workflows/e2e-test.yml). +Trigger the [GitHub Action](https://github.com/SAP/ai-sdk-js/actions/workflows/e2e-tests.yaml). diff --git a/tests/e2e-tests/src/deployment-api.test.ts b/tests/e2e-tests/src/deployment-api.test.ts index 69906c4df..b3c4b80c3 100644 --- a/tests/e2e-tests/src/deployment-api.test.ts +++ b/tests/e2e-tests/src/deployment-api.test.ts @@ -1,26 +1,23 @@ import { DeploymentApi } from '@sap-ai-sdk/ai-api'; import { getDeployments, createDeployment } from '@sap-ai-sdk/sample-code'; import { loadEnv } from './utils/load-env.js'; -import { - configurationId, - resourceGroup, - waitForDeploymentToReachStatus -} from './utils/ai-api-utils.js'; -import type { AiApiError, AiDeploymentList } from '@sap-ai-sdk/ai-api'; +import { configurationId, resourceGroup } from './utils/ai-api-utils.js'; loadEnv(); describe('DeploymentApi', () => { let createdDeploymentId: string | undefined; - let initialDeployments: AiDeploymentList | undefined; - beforeAll(async () => { + it('should get all deployments', async () => { const queryResponse = await getDeployments(resourceGroup); expect(queryResponse).toBeDefined(); - initialDeployments = queryResponse; + expect(queryResponse).toMatchObject({ + count: expect.any(Number), + resources: expect.any(Array) + }); }); - it('should create a deployment and wait for it to run', async () => { + it('should create and delete a deployment', async () => { const createResponse = await createDeployment( configurationId, resourceGroup @@ -32,123 +29,40 @@ describe('DeploymentApi', () => { }) ); - const runningDeployment = await waitForDeploymentToReachStatus( - createResponse.id, - 'RUNNING' - ); - expect(runningDeployment).toEqual( - expect.objectContaining({ - status: 'RUNNING', - deploymentUrl: expect.any(String) - }) - ); + createdDeploymentId = createResponse.id; - createdDeploymentId = runningDeployment.id; - }, 200000); + // A deployment initially has status: 'UNKNOWN' and can be deleted immediately + // without needing to stop the deployment - it('should stop the deployment', async () => { - const deploymentId = await checkCreatedDeployment( + const deleteResponse = await DeploymentApi.deploymentDelete( createdDeploymentId, - 'RUNNING' - ); - - const modifyResponse = await DeploymentApi.deploymentModify( - deploymentId, - { targetStatus: 'STOPPED' }, - { 'AI-Resource-Group': resourceGroup } + { + 'AI-Resource-Group': resourceGroup + } ).execute(); - expect(modifyResponse).toEqual( - expect.objectContaining({ - message: 'Deployment modification scheduled' - }) - ); - - const stoppedDeployment = await waitForDeploymentToReachStatus( - deploymentId, - 'STOPPED' - ); - expect(stoppedDeployment).toEqual( - expect.objectContaining({ - status: 'STOPPED' - }) - ); - }, 200000); - - it('should delete the deployment', async () => { - const deploymentId = await checkCreatedDeployment( - createdDeploymentId, - 'STOPPED' - ); - - const deleteResponse = await DeploymentApi.deploymentDelete(deploymentId, { - 'AI-Resource-Group': resourceGroup - }).execute(); expect(deleteResponse).toEqual( expect.objectContaining({ message: 'Deletion scheduled' }) ); - // Wait for deletion to complete - await new Promise(r => setTimeout(r, 30000)); - await expect( - DeploymentApi.deploymentGet( - deploymentId, - {}, - { 'AI-Resource-Group': resourceGroup } - ).execute() - ).rejects.toThrow(); - }, 150000); - - it('should validate consistency of deployments after test flow', async () => { - const queryResponse = await getDeployments(resourceGroup); - expect(queryResponse).toBeDefined(); - - const initialFilteredDeployments = filterDeployments( - initialDeployments, - createdDeploymentId - ); - const finalFilteredDeployments = filterDeployments( - queryResponse, - createdDeploymentId - ); - expect(finalFilteredDeployments.resources).toStrictEqual( - initialFilteredDeployments.resources - ); + const deletedDeployment = await DeploymentApi.deploymentGet( + createdDeploymentId, + {}, + { 'AI-Resource-Group': resourceGroup } + ).execute(); + expect(deletedDeployment.targetStatus).toBe('DELETED'); }); -}); -const filterDeployments = ( - deployments: AiDeploymentList | undefined, - createdDeployentId: string | undefined -) => ({ - ...deployments, - resources: deployments?.resources - .filter(deployment => deployment.id === createdDeployentId) - // eslint-disable-next-line @typescript-eslint/no-unused-vars - .map(({ modifiedAt, ...rest }) => rest) -}); + afterAll(async () => { + // Wait for deployment to be deleted + await new Promise(r => setTimeout(r, 60000)); + const finalDeployments = await getDeployments(resourceGroup); -async function checkCreatedDeployment( - deploymentId: string | undefined, - status: 'RUNNING' | 'STOPPED' -): Promise { - if (!deploymentId) { - try { - const response = await getDeployments(resourceGroup, status); - if (!response.count) { - throw new Error( - `No ${status} deployments found, please ${status === 'RUNNING' ? 'create' : 'stop'} a deployment first to ${status === 'RUNNING' ? 'modify' : 'delete'} it.` - ); - } - return response.resources[0].id; - } catch (error: any) { - if (error.response) { - const apiError = error.response.data.error as AiApiError; - throw new Error(`Request failed: ${apiError.message}`); - } - throw error; + if (finalDeployments.count) { + expect( + finalDeployments.resources.map(deployment => deployment.id) + ).not.toContain(createdDeploymentId); } - } - return deploymentId; -} + }, 75000); +});