Skip to content

Commit eaf9a0a

Browse files
committed
Updates to e2e test
1 parent accf223 commit eaf9a0a

6 files changed

Lines changed: 175 additions & 146 deletions

File tree

packages/cypress/cypress/fixtures/e2e/dataScienceProjects/testSingleModelAdminCreation.yaml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,8 @@ projectSingleModelAdminResourceName: "cy-single-model-admin-test"
44
singleModelAdminName: "cy-openvino-model"
55
modelOpenVinoPath: "kserve-openvino-test/openvino-example-model"
66
modelFormat: 'openvino_ir - opset13'
7-
servingRuntime: 'OpenVINO Model Server'
7+
servingRuntime: 'OpenVINO Model Server'
8+
# Legacy KServe deployment test data
9+
legacyModelLocationURI: 'hf://facebook/opt-125m'
10+
legacyServingRuntime: 'vLLM CPU .x86. ServingRuntime for KServe'
11+
legacyHardwareProfileName: 'cypress-llmd-hardware-profile-model'
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
apiVersion: serving.kserve.io/v1alpha1
2+
kind: LLMInferenceServiceConfig
3+
metadata:
4+
annotations:
5+
description: vLLM CPU LLMInferenceServiceConfig for LLMInferenceService.
6+
opendatahub.io/runtime-version: v0.1
7+
openshift.io/display-name: vLLM CPU LLMInferenceServiceConfig
8+
name: kserve-config-llm-template-cpu
9+
labels:
10+
opendatahub.io/config-type: accelerator
11+
spec:
12+
template:
13+
containers:
14+
- image: quay.io/pierdipi/vllm-cpu:latest
15+
name: main

packages/cypress/cypress/tests/e2e/dataScienceProjects/models/testDeployLLMDServing.cy.ts

Lines changed: 20 additions & 127 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import {
1313
modelServingGlobal,
1414
modelServingSection,
1515
modelServingWizard,
16-
modelServingWizardEdit,
1716
deleteModelServingModal,
1817
inferenceServiceActions,
1918
} from '../../../../pages/modelServing';
@@ -24,6 +23,11 @@ import {
2423
createCleanHardwareProfile,
2524
cleanupHardwareProfiles,
2625
} from '../../../../utils/oc_commands/hardwareProfiles';
26+
import {
27+
createCleanLLMInferenceServiceConfig,
28+
cleanupLLMInferenceServiceConfig,
29+
checkLLMInferenceServiceConfigState,
30+
} from '../../../../utils/oc_commands/llmInferenceServiceConfig';
2731
import { checkLLMInferenceServiceState } from '../../../../utils/oc_commands/modelServing';
2832
import { stubClipboard, getClipboardContent } from '../../../../utils/clipboardUtils';
2933

@@ -35,12 +39,11 @@ let hardwareProfileResourceName: string;
3539
let hardwareProfileYamlPath: string;
3640
let modelURI: string;
3741
let servingRuntime: string;
38-
let existingImage: string;
39-
let replaceImage: string;
4042
let yamlEditorModelName: string;
4143
let yamlEditorModelPath: string;
42-
let legacyModelName: string;
43-
let legacyServingRuntime: string;
44+
const llmInferenceServiceConfigName = 'kserve-config-llm-template-cpu';
45+
const llmInferenceServiceConfigYamlPath =
46+
'resources/modelServing/llmd-inference-service-config.yaml';
4447

4548
describe('A user can deploy an LLMD model', () => {
4649
retryableBefore(() => {
@@ -54,21 +57,20 @@ describe('A user can deploy an LLMD model', () => {
5457
servingRuntime = testData.servingRuntime;
5558
hardwareProfileResourceName = `${testData.hardwareProfileName}`;
5659
hardwareProfileYamlPath = `resources/yaml/llmd-hardware-profile.yaml`;
57-
existingImage = testData.existingImage;
58-
replaceImage = testData.replaceImage;
5960
yamlEditorModelName = testData.yamlEditorModelName;
6061
yamlEditorModelPath = 'cypress/fixtures/resources/yaml/yaml_editor_model_serving.yaml';
61-
legacyModelName = `${testData.singleModelName}-legacy`;
62-
legacyServingRuntime = testData.legacyServingRuntime;
63-
6462
cy.log(`Loaded project name: ${projectName}`);
6563
createCleanProject(projectName);
6664
})
6765
.then(() => {
6866
// Load Hardware Profile
6967
cy.log(`Load Hardware Profile Name: ${hardwareProfileResourceName}`);
70-
// Cleanup Hardware Profile if it already exists
7168
createCleanHardwareProfile(hardwareProfileYamlPath);
69+
})
70+
.then(() => {
71+
// Load LLMInferenceServiceConfig
72+
cy.log(`Load LLMInferenceServiceConfig: ${llmInferenceServiceConfigName}`);
73+
createCleanLLMInferenceServiceConfig(llmInferenceServiceConfigYamlPath);
7274
});
7375
});
7476

@@ -77,6 +79,8 @@ describe('A user can deploy an LLMD model', () => {
7779
cy.log(`Cleaning up Hardware Profile: ${testData.hardwareProfileName}`);
7880
// Call cleanupHardwareProfiles with the actual name from the YAML file
7981
cleanupHardwareProfiles(hardwareProfileResourceName);
82+
cy.log(`Cleaning up LLMInferenceServiceConfig: ${llmInferenceServiceConfigName}`);
83+
cleanupLLMInferenceServiceConfig(llmInferenceServiceConfigName);
8084
// Delete provisioned Project - wait for completion due to RHOAIENG-19969 to support test retries, 5 minute timeout
8185
// TODO: Review this timeout once RHOAIENG-19969 is resolved
8286
deleteOpenShiftProject(projectName, { wait: true, ignoreNotFound: true, timeout: 300000 });
@@ -142,18 +146,14 @@ describe('A user can deploy an LLMD model', () => {
142146
modelServingWizard.findYAMLViewerToggle(YAMLViewerToggleOption.YAML).should('exist').click();
143147
modelServingWizard.findYAMLCodeEditor().waitForReady();
144148

145-
cy.step('Patch YAML to use CPU image (workaround for non-GPU cluster)');
146-
// Add the CPU image to the containers spec so deployment works without GPU
147-
modelServingWizard.findYAMLCodeEditor().replaceInEditor(existingImage, replaceImage);
149+
cy.step('Verify YAML content includes the LLMInferenceServiceConfig CPU image');
148150
modelServingWizard.findYAMLCodeEditor().copyToClipboard().click();
149-
// Verify the actual copied YAML content
150151
getClipboardContent('copiedYAML').then((copied) => {
151152
expect(copied).to.have.length.at.least(1);
152153
const yamlContent = copied[0];
153154
expect(yamlContent).to.include('apiVersion: serving.kserve.io/v1alpha1');
154155
expect(yamlContent).to.include('kind: LLMInferenceService');
155156
expect(yamlContent).to.include(`name: ${modelName}`);
156-
expect(yamlContent).to.include(replaceImage);
157157
});
158158
modelServingWizard.findYAMLCodeEditor().download().should('exist').click();
159159
// Back to Form view
@@ -175,10 +175,12 @@ describe('A user can deploy an LLMD model', () => {
175175

176176
cy.step('Verify that the Model is ready');
177177
cy.get<string>('@resourceName').then((resourceName) => {
178-
checkLLMInferenceServiceState(resourceName, projectName, { checkReady: true });
178+
checkLLMInferenceServiceState(resourceName, projectName);
179179
});
180+
checkLLMInferenceServiceConfigState(llmInferenceServiceConfigName);
180181

181182
cy.step('Verify the model Row');
183+
cy.reload();
182184
const llmdRow = modelServingGlobal.getDeploymentRow(modelName);
183185
llmdRow.findStatusLabel(ModelStateLabel.STARTED).should('exist');
184186
llmdRow.findServingRuntime().should('have.text', servingRuntime);
@@ -207,14 +209,7 @@ describe('A user can deploy an LLMD model', () => {
207209

208210
cy.step('Deploy LLMD Model From YAML Editor');
209211
projectDetails.findSectionTab('model-server').click();
210-
cy.get('[data-testid="kserve-select-button"], [data-testid="deploy-button"]', {
211-
timeout: 15000,
212-
}).should('have.length.at.least', 1);
213-
cy.get('body').then(($body) => {
214-
if ($body.find('[data-testid="kserve-select-button"]').length > 0) {
215-
modelServingGlobal.findSingleServingModelButton().click();
216-
}
217-
});
212+
modelServingGlobal.selectSingleServingModelButtonIfExists();
218213
modelServingGlobal.findDeployModelButton().click();
219214

220215
cy.step('Enter Manual YAML editor Mode');
@@ -243,106 +238,4 @@ describe('A user can deploy an LLMD model', () => {
243238
modelServingWizard.findSubmitButton().should('be.enabled').click();
244239
},
245240
);
246-
it(
247-
'Verify Legacy Checkbox deploys via KServe and edit shows legacy as locked',
248-
{
249-
tags: ['@Smoke', '@SmokeSet3', '@Dashboard', '@ModelServing', '@NonConcurrent'],
250-
},
251-
() => {
252-
cy.step('Log into the application as admin');
253-
cy.visitWithLogin(
254-
'/?devFeatureFlags=deploymentWizardYAMLViewer=true,vLLMDeploymentOnMaaS=true',
255-
HTPASSWD_CLUSTER_ADMIN_USER,
256-
);
257-
258-
cy.step(`Navigate to the Project list tab and search for ${projectName}`);
259-
projectListPage.navigate();
260-
projectListPage.filterProjectByName(projectName);
261-
projectListPage.findProjectLink(projectName).click();
262-
263-
cy.step('Open the deploy model wizard');
264-
projectDetails.findSectionTab('model-server').click();
265-
// Wait for tab content to load — either platform selection or deploy button will appear
266-
cy.get('[data-testid="kserve-select-button"], [data-testid="deploy-button"]', {
267-
timeout: 15000,
268-
}).should('have.length.at.least', 1);
269-
cy.get('body').then(($body) => {
270-
if ($body.find('[data-testid="kserve-select-button"]').length > 0) {
271-
modelServingGlobal.findSingleServingModelButton().click();
272-
}
273-
});
274-
modelServingGlobal.findDeployModelButton().click();
275-
276-
cy.step('Select model source with Generative type');
277-
modelServingWizard.findModelLocationSelectOption(ModelLocationSelectOption.URI).click();
278-
modelServingWizard.findUrilocationInput().clear().type(modelURI);
279-
modelServingWizard.findSaveConnectionCheckbox().should('be.checked');
280-
modelServingWizard.findSaveConnectionInput().clear().type(`${legacyModelName}-connection`);
281-
modelServingWizard.findModelTypeSelectOption(ModelTypeLabel.GENERATIVE).click();
282-
283-
cy.step('Verify legacy checkbox appears and is unchecked by default');
284-
modelServingWizard.findLegacyModeCheckbox().should('exist').should('not.be.checked');
285-
286-
cy.step('Check the legacy deployment checkbox');
287-
modelServingWizard.findLegacyModeCheckbox().check();
288-
modelServingWizard.findLegacyModeCheckbox().should('be.checked');
289-
290-
cy.step('Navigate to deployment step and verify KServe serving runtime path');
291-
modelServingWizard.findNextButton().should('be.enabled').click();
292-
modelServingWizard.findModelDeploymentNameInput().should('exist');
293-
modelServingWizard.findServingRuntimeTemplateSearchSelector().should('exist');
294-
modelServingWizard.findServingRuntimeTemplateSearchSelector().should('exist');
295-
296-
cy.step('Configure legacy model deployment');
297-
modelServingWizard.findModelDeploymentNameInput().clear().type(legacyModelName);
298-
modelServingWizard.findResourceNameButton().click();
299-
modelServingWizard
300-
.findResourceNameInput()
301-
.should('be.visible')
302-
.invoke('val')
303-
.as('legacyResourceName');
304-
modelServingWizard.findHardProfileSelection().then(($el) => {
305-
if ($el.prop('disabled') || $el.hasClass('pf-m-disabled')) {
306-
cy.log('Hardware profile auto-selected (dropdown disabled)');
307-
} else {
308-
modelServingWizard.findHardProfileSelection().click();
309-
cy.findByTestId(hardwareProfileResourceName).find('[role="option"]').click();
310-
}
311-
});
312-
modelServingWizard.findServingRuntimeTemplateSearchSelector().click();
313-
modelServingWizard
314-
.findGlobalScopedTemplateOption(legacyServingRuntime)
315-
.should('exist')
316-
.click();
317-
modelServingWizard.findNextButton().should('be.enabled').click();
318-
319-
cy.step('Skip advanced settings');
320-
modelServingWizard.findNextButton().click();
321-
322-
cy.step('Submit legacy deployment');
323-
modelServingWizard.findSubmitButton().click();
324-
325-
cy.step('Wait for legacy deployment to appear');
326-
modelServingSection.findModelServerDeployedName(legacyModelName);
327-
328-
cy.step('Edit the legacy deployment and verify form state');
329-
const legacyRow = modelServingGlobal.getDeploymentRow(legacyModelName);
330-
legacyRow.findKebab().click();
331-
inferenceServiceActions.findEditInferenceServiceAction().click();
332-
333-
modelServingWizardEdit
334-
.findModelTypeSelect()
335-
.should('have.text', ModelTypeLabel.GENERATIVE)
336-
.should('be.disabled');
337-
modelServingWizardEdit.findLegacyModeCheckbox().should('be.checked').should('be.disabled');
338-
modelServingWizardEdit.findCancelButton().click();
339-
cy.findByRole('button', { name: 'Discard' }).click();
340-
341-
cy.step('Delete the legacy deployment');
342-
legacyRow.findKebab().click();
343-
inferenceServiceActions.findDeleteInferenceServiceAction().click();
344-
deleteModelServingModal.findInput().clear().type(legacyModelName);
345-
deleteModelServingModal.findSubmitButton().should('be.enabled').click();
346-
},
347-
);
348241
});

0 commit comments

Comments
 (0)