Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test: Import and run a Pipeline #3028

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
72 commits
Select commit Hold shift + click to select a range
766cabf
Provision project and data connection, clean up project
FedeAlonso Jul 23, 2024
d06be9c
fix temporal path
FedeAlonso Jul 23, 2024
ff27d23
add DSPA Secret provision
FedeAlonso Jul 23, 2024
9d5ccdb
Provision and clean-up working properly
FedeAlonso Jul 23, 2024
a43db95
Import a pipeline from DSP modal
FedeAlonso Jul 23, 2024
1e124f8
Test running OK
FedeAlonso Jul 24, 2024
84e183f
clean comments and disable the fetching of backend requests in live t…
FedeAlonso Jul 24, 2024
85e7395
Merge branch 'main' into test/pipelines_base_test
FedeAlonso Jul 24, 2024
8ae9133
fix lintings
FedeAlonso Jul 24, 2024
bd44d23
Merge branch 'test/pipelines_base_test' of github.com:FedeAlonso/odh-…
FedeAlonso Jul 24, 2024
42295a2
Fixes to 2.12 compatibility
FedeAlonso Jul 29, 2024
c656efb
Merge branch 'main' into test/pipelines_base_test
FedeAlonso Jul 29, 2024
eb2a1c9
Merge branch 'test/pipelines_base_test' of github.com:FedeAlonso/odh-…
FedeAlonso Jul 29, 2024
505bb28
Delete finalizers, generation and managedFields from yaml
FedeAlonso Jul 29, 2024
38489b2
Update frontend/src/__tests__/cypress/cypress/pages/pipelines/topolog…
FedeAlonso Jul 30, 2024
10e7da1
some fixes and run pipeline from actions
FedeAlonso Jul 30, 2024
c193e51
delete wait when waiting run status
FedeAlonso Jul 30, 2024
4d9a76b
fix oc commands
FedeAlonso Jul 30, 2024
ea6d831
delete login assertion
FedeAlonso Jul 30, 2024
4a286f3
stop waiting for project deletion
FedeAlonso Jul 30, 2024
0d3fd01
Merge branch 'main' into test/pipelines_base_test
FedeAlonso Jul 30, 2024
28d8d14
AWS like ods-ci
FedeAlonso Jul 31, 2024
b183dc6
Merge branch 'main' into test/pipelines_base_test
FedeAlonso Jul 31, 2024
e74ac03
lint fixes
FedeAlonso Jul 31, 2024
9c7f886
Merge branch 'test/pipelines_base_test' of github.com:FedeAlonso/odh-…
FedeAlonso Jul 31, 2024
6a949ea
modularize the oc calls
FedeAlonso Jul 31, 2024
9f3e7be
lint fixes
FedeAlonso Jul 31, 2024
da20e1b
delete comment
FedeAlonso Jul 31, 2024
6f01376
Use a dummy pipeline from our repo
FedeAlonso Aug 1, 2024
d7049ec
test: Add a dummy pipeline sample
FedeAlonso Aug 1, 2024
caab825
add dummy pipeline
FedeAlonso Aug 1, 2024
b564769
fix pipeline url
FedeAlonso Aug 1, 2024
4e5953a
filter the project before trying to open it in the DSP view
FedeAlonso Aug 1, 2024
cebadf7
fix data-testid for pipeline run status icon
FedeAlonso Aug 1, 2024
209f98c
yml to yaml
FedeAlonso Aug 1, 2024
d793d27
Merge branch 'main' into test/pipelines_base_test
FedeAlonso Aug 2, 2024
d138d30
Merge branch 'main' into test/pipelines_base_test
FedeAlonso Aug 6, 2024
a6ae230
Merge branch 'main' into test/pipelines_base_test
FedeAlonso Aug 7, 2024
3bafb74
delete unused code
FedeAlonso Aug 7, 2024
fd7be8c
filter project name properly
FedeAlonso Aug 8, 2024
776c844
Merge branch 'main' into test/pipelines_base_test
FedeAlonso Aug 8, 2024
8c5da97
Wait for status editable
FedeAlonso Aug 8, 2024
5c9f0f5
make display name not mandatory
FedeAlonso Aug 8, 2024
3f4d1ed
move filterProjectByName
FedeAlonso Aug 8, 2024
da3072f
Merge branch 'main' into test/pipelines_base_test
FedeAlonso Aug 8, 2024
cd7569e
Merge branch 'main' into test/pipelines_base_test
FedeAlonso Aug 12, 2024
caef85f
use proper types
FedeAlonso Aug 12, 2024
305c12f
lint fixes
FedeAlonso Aug 12, 2024
fe3de89
Merge branch 'main' into test/pipelines_base_test
FedeAlonso Aug 13, 2024
ed4654c
Merge branch 'main' into test/pipelines_base_test
FedeAlonso Aug 14, 2024
338cdfe
add lint fixes
FedeAlonso Aug 14, 2024
c520041
Merge branch 'main' into test/pipelines_base_test
FedeAlonso Aug 14, 2024
3b7a4db
Merge branch 'main' into test/pipelines_base_test
FedeAlonso Aug 16, 2024
3e23038
Update frontend/src/__tests__/cypress/cypress/utils/oc_commands/proje…
FedeAlonso Aug 16, 2024
00cd079
Update frontend/src/__tests__/cypress/cypress/utils/oc_commands/dspa.ts
FedeAlonso Aug 16, 2024
3880492
Merge branch 'main' into test/pipelines_base_test
FedeAlonso Aug 16, 2024
2f556c2
delete displayName redundancy
FedeAlonso Aug 16, 2024
a15f321
Update frontend/src/__tests__/cypress/cypress/pages/pipelines/topolog…
FedeAlonso Aug 16, 2024
924f45c
Update frontend/src/__tests__/cypress/cypress/pages/pipelines/topolog…
FedeAlonso Aug 16, 2024
46cad22
Update frontend/src/__tests__/cypress/cypress/pages/projects.ts
FedeAlonso Aug 16, 2024
2b126d1
move uncaught exception to particular test
FedeAlonso Aug 16, 2024
dd73876
Merge branch 'main' into test/pipelines_base_test
FedeAlonso Sep 3, 2024
3a9d8f1
Merge branch 'main' into test/pipelines_base_test
FedeAlonso Sep 3, 2024
e12bf24
delete the uncaught exception control as it's fixed
FedeAlonso Sep 5, 2024
efa2a09
Merge branch 'main' into test/pipelines_base_test
FedeAlonso Sep 6, 2024
828172d
Merge branch 'test/pipelines_base_test' of github.com:FedeAlonso/odh-…
FedeAlonso Sep 6, 2024
86dcd6b
Update frontend/src/__tests__/cypress/cypress/pages/pipelines/topolog…
FedeAlonso Sep 6, 2024
a8f5480
Update frontend/src/__tests__/cypress/cypress/utils/oc_commands/baseC…
FedeAlonso Sep 6, 2024
e829c83
Merge branch 'test/pipelines_base_test' of github.com:FedeAlonso/odh-…
FedeAlonso Sep 6, 2024
6499015
add log when deleting a project using oc
FedeAlonso Sep 6, 2024
a32363a
add a helper which contains the test provisioning
FedeAlonso Sep 6, 2024
a9126b2
lint fixes
FedeAlonso Sep 6, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions frontend/src/__tests__/cypress/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@ cypress/downloads
coverage
results
.nyc_output
test-variables.yml
cypress/temp*.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
kind: Secret
apiVersion: v1
metadata:
name: aws-connection-ods-ci-ds-pipelines
namespace: {{NAMESPACE}}
labels:
opendatahub.io/dashboard: 'true'
opendatahub.io/managed: 'true'
annotations:
opendatahub.io/connection-type: s3
openshift.io/display-name: ods-ci-ds-pipelines
data:
AWS_ACCESS_KEY_ID: {{AWS_ACCESS_KEY_ID}}
AWS_DEFAULT_REGION: {{AWS_DEFAULT_REGION}}
AWS_S3_BUCKET: {{AWS_S3_BUCKET}}
AWS_S3_ENDPOINT: {{AWS_S3_ENDPOINT}}
AWS_SECRET_ACCESS_KEY: {{AWS_SECRET_ACCESS_KEY}}
type: Opaque
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
apiVersion: datasciencepipelinesapplications.opendatahub.io/v1alpha1
kind: DataSciencePipelinesApplication
metadata:
name: dspa
namespace: {{NAMESPACE}}
spec:
apiServer:
caBundleFileMountPath: ''
stripEOF: true
dbConfigConMaxLifetimeSec: 120
applyTektonCustomResource: true
caBundleFileName: ''
deploy: true
enableSamplePipeline: false
autoUpdatePipelineDefaultVersion: true
archiveLogs: false
terminateStatus: Cancelled
enableOauth: true
trackArtifacts: true
collectMetrics: true
injectDefaultScript: true
database:
disableHealthCheck: false
mariaDB:
deploy: true
pipelineDBName: mlpipeline
pvcSize: 10Gi
username: mlpipeline
dspVersion: v2
objectStorage:
disableHealthCheck: false
enableExternalRoute: false
externalStorage:
basePath: ''
bucket: {{AWS_S3_BUCKET}}
host: s3.amazonaws.com
port: ''
region: us-east-1
s3CredentialsSecret:
accessKey: AWS_ACCESS_KEY_ID
secretKey: AWS_SECRET_ACCESS_KEY
secretName: {{DSPA_SECRET_NAME}}
scheme: https
persistenceAgent:
deploy: true
numWorkers: 2
scheduledWorkflow:
cronScheduleTimezone: UTC
deploy: true
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
kind: Secret
apiVersion: v1
metadata:
name: {{DSPA_SECRET_NAME}}
namespace: {{NAMESPACE}}
labels:
opendatahub.io/dashboard: 'true'
data:
AWS_ACCESS_KEY_ID: {{AWS_ACCESS_KEY_ID}}
AWS_SECRET_ACCESS_KEY: {{AWS_SECRET_ACCESS_KEY}}
type: Opaque
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
import { DeleteModal } from '~/__tests__/cypress/cypress/pages/components/DeleteModal';
import { Modal } from '~/__tests__/cypress/cypress/pages/components/Modal';
import { appChrome } from '~/__tests__/cypress/cypress/pages/appChrome';

class PipelinesGlobal {
visit(projectName: string) {
cy.visitWithLogin(`/pipelines/${projectName}`);
this.wait();
}

navigate() {
appChrome.findNavItem('Data Science Pipelines').click();
this.wait();
}

private wait() {
cy.findByTestId('app-page-title').contains('Pipelines');
cy.testA11y();
Expand Down Expand Up @@ -42,7 +48,7 @@ class PipelinesGlobal {
return cy.findByRole('menuitem').get('span').contains('Upload new version');
}

private findProjectSelect() {
findProjectSelect() {
return cy.findByTestId('project-selector-dropdown');
}

Expand Down
12 changes: 10 additions & 2 deletions frontend/src/__tests__/cypress/cypress/pages/pipelines/topology.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,14 @@ class RunDetails extends PipelinesTopology {
return new DetailsItem(() => cy.findByTestId(`detail-item-${key}`));
}

private findStatusLabel(timeout?: number) {
return cy.findByTestId('status-icon', { timeout });
}

expectStatusLabelToBe(statusValue: string, timeout?: number) {
this.findStatusLabel(timeout).should('have.text', statusValue);
}

findRightDrawer() {
return new PipelineRunRightDrawer(() =>
cy.findByTestId('pipeline-run-drawer-right-content').parent(),
Expand Down Expand Up @@ -169,8 +177,8 @@ class PipelineDetails extends PipelinesTopology {
return new DashboardCodeEditor(() => cy.findByTestId('pipeline-dashboard-code-editor'));
}

findPageTitle() {
return cy.findByTestId('app-page-title');
findPageTitle(timeout?: number) {
return cy.findByTestId('app-page-title', { timeout });
}

getTaskDrawer() {
Expand Down
14 changes: 14 additions & 0 deletions frontend/src/__tests__/cypress/cypress/pages/projects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,16 @@ class ProjectListPage {
findCreateWorkbenchButton() {
return cy.findByRole('button', { name: 'Create a workbench' });
}

/**
* Filter Project by name using the Project filter from the Data Science Projects view
* @param projectName Project Name
*/
filterProjectByName = (projectName: string) => {
const projectListToolbar = projectListPage.getTableToolbar();
projectListToolbar.findFilterMenuOption('filter-dropdown-select', 'Name').click();
projectListToolbar.findSearchInput().type(projectName);
};
}

class CreateEditProjectModal extends Modal {
Expand Down Expand Up @@ -159,6 +169,10 @@ class ProjectDetails {
);
}

findImportPipelineButton(timeout?: undefined) {
return cy.findByTestId('import-pipeline-button', { timeout });
}

findSingleModelDeployButton() {
return this.findModelServingPlatform('single').findByTestId('single-serving-deploy-button');
}
Expand Down
5 changes: 5 additions & 0 deletions frontend/src/__tests__/cypress/cypress/support/e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ Cypress.Keyboard.defaults({
keystrokeDelay: 0,
});

before(() => {
// disable Cypress's default behavior of logging all XMLHttpRequests and fetches
cy.intercept({ resourceType: /xhr|fetch/ }, { log: false });
});

beforeEach(() => {
if (Cypress.env('MOCK')) {
// fallback: return 404 for all api requests
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { deleteOpenShiftProject } from '~/__tests__/cypress/cypress/utils/oc_commands/project';
import { ADMIN_USER } from '~/__tests__/cypress/cypress/utils/e2eUsers';
import { projectListPage, projectDetails } from '~/__tests__/cypress/cypress/pages/projects';
import { pipelineImportModal } from '~/__tests__/cypress/cypress/pages/pipelines/pipelineImportModal';
import { createRunPage } from '~/__tests__/cypress/cypress/pages/pipelines/createRunPage';
import {
pipelineDetails,
pipelineRunDetails,
} from '~/__tests__/cypress/cypress/pages/pipelines/topology';
import { provisionProjectForPipelines } from '~/__tests__/cypress/cypress/utils/pipelines';

const projectName = 'test-pipelines-prj';
const dspaSecretName = 'dashboard-dspa-secret';
const testPipelineName = 'test-pipelines-pipeline';
const testRunName = 'test-pipelines-run';

describe('An admin user can import and run a pipeline', { testIsolation: false }, () => {
before(() => {
// Create a Project for pipelines
provisionProjectForPipelines(projectName, dspaSecretName);
});

after(() => {
// Delete provisioned Project
deleteOpenShiftProject(projectName);
});

it('An admin User can Import and Run a Pipeline', () => {
// Login as an admin
cy.visitWithLogin('/', ADMIN_USER);
FedeAlonso marked this conversation as resolved.
Show resolved Hide resolved

/**
* Import Pipeline by URL from Project Details view
*/
projectListPage.navigate();

// Open the project
projectListPage.filterProjectByName(projectName);
projectListPage.findProjectLink(projectName).click();

// Increasing the timeout to ~3mins so the DSPA can be loaded
projectDetails.findImportPipelineButton(180000).click();

// Fill tue Import Pipeline modal
pipelineImportModal.findPipelineNameInput().type(testPipelineName);
pipelineImportModal.findPipelineDescriptionInput().type('Pipeline Description');
pipelineImportModal.findImportPipelineRadio().click();
pipelineImportModal
.findPipelineUrlInput()
//TODO: modify this URL once the PR is merged
.type(
'https://raw.githubusercontent.com/opendatahub-io/odh-dashboard/caab82536b4dd5d39fb7a06a6c3248f10c183417/frontend/src/__tests__/resources/pipelines_samples/dummy_pipeline_compiled.yaml',
);
FedeAlonso marked this conversation as resolved.
Show resolved Hide resolved
pipelineImportModal.submit();

// Verify that we are at the details page of the pipeline by checking the title
// It can take a little longer to load
pipelineDetails.findPageTitle(60000).should('have.text', testPipelineName);

/**
* Run the Pipeline using the Actions button in the pipeline detail view
*/

pipelineDetails.selectActionDropdownItem('Create run');

//Fill the Create run fields
createRunPage.findExperimentSelect().click();
createRunPage.selectExperimentByName('Default');
createRunPage.fillName(testRunName);
createRunPage.fillDescription('Run Description');
createRunPage.findSubmitButton().click();

//Redirected to the Graph view of the created run
pipelineRunDetails.expectStatusLabelToBe('Succeeded', 180000);
});
});
41 changes: 41 additions & 0 deletions frontend/src/__tests__/cypress/cypress/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,49 @@ export type UserAuthConfig = {
PASSWORD: string;
};

export type AWSS3BucketDetails = {
NAME: string;
REGION: string;
ENDPOINT: string;
};

export type AWSS3Buckets = {
AWS_ACCESS_KEY_ID: string;
AWS_SECRET_ACCESS_KEY: string;
BUCKET_2: AWSS3BucketDetails;
};

export type DataConnectionReplacements = {
NAMESPACE: string;
AWS_ACCESS_KEY_ID: string;
AWS_DEFAULT_REGION: string;
AWS_S3_BUCKET: string;
AWS_S3_ENDPOINT: string;
AWS_SECRET_ACCESS_KEY: string;
};

export type DspaSecretReplacements = {
DSPA_SECRET_NAME: string;
NAMESPACE: string;
AWS_ACCESS_KEY_ID: string;
AWS_SECRET_ACCESS_KEY: string;
};

export type DspaReplacements = {
DSPA_SECRET_NAME: string;
NAMESPACE: string;
AWS_S3_BUCKET: string;
};

export type CommandLineResult = {
code: number;
stdout: string;
stderr: string;
};

export type TestConfig = {
ODH_DASHBOARD_URL: string;
TEST_USER: UserAuthConfig;
OCP_ADMIN_USER: UserAuthConfig;
S3: AWSS3Buckets;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import type { CommandLineResult } from '~/__tests__/cypress/cypress/types';

/**
* Applies the given YAML content using the `oc apply` command.
*
* @param yamlContent YAML content to be applied
* @returns Cypress Chainable
*/
export const applyOpenShiftYaml = (yamlContent: string): Cypress.Chainable<CommandLineResult> => {
const ocCommand = `oc apply -f - <<EOF\n${yamlContent}\nEOF`;
return cy.exec(ocCommand, { failOnNonZeroExit: false }).then((result: CommandLineResult) => {
if (result.code !== 0) {
// If there is an error, log the error and fail the test
cy.log(`ERROR applying YAML content
stdout: ${result.stdout}
stderr: ${result.stderr}`);
throw new Error(`Command failed with code ${result.code}`);
}
return result;
});
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import type {
DataConnectionReplacements,
CommandLineResult,
} from '~/__tests__/cypress/cypress/types';
import { replacePlaceholdersInYaml } from '~/__tests__/cypress/cypress/utils/yaml_files';
import { applyOpenShiftYaml } from './baseCommands';

/**
* Try to create a data connection based on the dataConnectionReplacements config
* @param dataConnectionReplacements Dictionary with the config values
* Dict Structure:
* dataConnectionReplacements = {
* NAMESPACE: <PROJECT NAME>,
* AWS_ACCESS_KEY_ID: <AWS ACCESS KEY ID>,
* AWS_DEFAULT_REGION: <AWS REGION>,
* AWS_S3_BUCKET: <AWS BUCKET NAME>,
* AWS_S3_ENDPOINT: <AWS ENDPOINT>,
* AWS_SECRET_ACCESS_KEY: <AWS SECRET>,
* }
* @param yamlFilePath
*/
export const createDataConnection = (
dataConnectionReplacements: DataConnectionReplacements,
yamlFilePath = 'resources/yaml/data_connection.yaml',
): Cypress.Chainable<CommandLineResult> => {
return cy.fixture(yamlFilePath).then((yamlContent) => {
const modifiedYamlContent = replacePlaceholdersInYaml(yamlContent, dataConnectionReplacements);
return applyOpenShiftYaml(modifiedYamlContent);
});
};
Loading
Loading