Skip to content

Commit

Permalink
Add error state when pipeline version is deleted
Browse files Browse the repository at this point in the history
  • Loading branch information
ppadti committed Jun 14, 2024
1 parent 2d7ae79 commit 950660e
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,10 @@ class PipelineRunDetails extends RunDetails {
findOutputArtifacts() {
return cy.findByTestId('Output-artifacts');
}

findErrorstate() {
return cy.findByTestId('error-state-title');
}
}

class PipelineRunBottomDrawer extends Contextual<HTMLDivElement> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ import {
bulkRestoreRunModal,
archiveRunModal,
bulkArchiveRunModal,
pipelineRunDetails,
pipelineDetails,
} from '~/__tests__/cypress/cypress/pages/pipelines';
import { verifyRelativeURL } from '~/__tests__/cypress/cypress/utils/url';
import { be } from '~/__tests__/cypress/cypress/utils/should';
Expand Down Expand Up @@ -71,6 +73,13 @@ const mockActiveRuns = [
created_at: '2024-02-10T00:00:00Z',
state: RuntimeStateKF.CANCELED,
}),
buildMockRunKF({
display_name: 'Test active run 4',
run_id: 'run-4',
experiment_id: 'test-experiment-1',
created_at: '2024-02-10T00:00:00Z',
state: RuntimeStateKF.SUCCEEDED,
}),
];

const mockExperimentIds = [...new Set(mockActiveRuns.map((mockRun) => mockRun.experiment_id))];
Expand Down Expand Up @@ -309,7 +318,7 @@ describe('Pipeline runs', () => {

activeRunsTable.findActionsKebab().findDropdownItem('Archive').click();
activeRunsTable.mockGetRuns([], mockActiveRuns, projectName);
bulkArchiveRunModal.findConfirmInput().type('Archive 3 runs');
bulkArchiveRunModal.findConfirmInput().type('Archive 4 runs');
bulkArchiveRunModal.findSubmitButton().click();
activeRunsTable.findEmptyState().should('exist');

Expand All @@ -319,6 +328,67 @@ describe('Pipeline runs', () => {
);
});

it('should display error state when the pipeline version deleted', () => {
cy.interceptOdh(
'GET /api/service/pipelines/:namespace/:serviceName/apis/v2beta1/runs/:runId',
{
path: {
namespace: projectName,
serviceName: 'dspa',
runId: mockActiveRuns[3].run_id,
},
},
mockActiveRuns[3],
);
activeRunsTable
.getRowByName('Test active run 4')
.findColumnName('Test active run 4')
.click();
pipelineRunDetails.findErrorstate().should('have.text', 'Error loading pipeline run graph');

// check details tab
pipelineRunDetails.findBottomDrawer().findBottomDrawerDetailsTab().click();
pipelineRunDetails
.findBottomDrawer()
.findBottomDrawerDetailItem('Name')
.findValue()
.contains(mockActiveRuns[3].display_name);
pipelineRunDetails
.findBottomDrawer()
.findBottomDrawerDetailItem('Pipeline version')
.findValue()
.contains('No pipeline version');
pipelineRunDetails
.findBottomDrawer()
.findBottomDrawerDetailItem('Project')
.findValue()
.contains('Test project');
pipelineRunDetails
.findBottomDrawer()
.findBottomDrawerDetailItem('Run ID')
.findValue()
.contains(mockActiveRuns[3].run_id);
pipelineRunDetails
.findBottomDrawer()
.findBottomDrawerDetailItem('Workflow name')
.findValue()
.contains(mockActiveRuns[3].display_name);

// check input parameters tab
pipelineRunDetails.findBottomDrawer().findBottomDrawerInputTab().click();
pipelineRunDetails
.findBottomDrawer()
.findBottomDrawerDetailItem('min_max_scaler')
.findValue()
.contains('False');

// check run output tab
pipelineRunDetails.findBottomDrawer().findBottomDrawerYamlTab().click();
pipelineRunDetails.findYamlOutput().click();
const pipelineDashboardCodeEditor = pipelineDetails.getPipelineDashboardCodeEditor();
pipelineDashboardCodeEditor.findInput().should('not.be.empty');
});

describe('Navigation', () => {
it('navigate to create run page', () => {
pipelineRunsGlobal.findCreateRunButton().click();
Expand Down Expand Up @@ -351,6 +421,7 @@ describe('Pipeline runs', () => {
`/pipelineRuns/${projectName}/pipelineRun/view/${mockActiveRuns[0].run_id}`,
);
});

it('navigate to pipeline version details page', () => {
const selectedVersion = mockVersions.find(
(mockVersion) =>
Expand All @@ -373,7 +444,7 @@ describe('Pipeline runs', () => {
describe('Table filter', () => {
it('filter by name', () => {
// Verify initial run rows exist
activeRunsTable.findRows().should('have.length', 3);
activeRunsTable.findRows().should('have.length', 4);

// Select the "Run" filter, enter a value to filter by
pipelineRunsGlobal
Expand All @@ -400,7 +471,7 @@ describe('Pipeline runs', () => {
pipelineRunFilterBar.mockExperiments(mockExperiments, projectName);

// Verify initial run rows exist
activeRunsTable.findRows().should('have.length', 3);
activeRunsTable.findRows().should('have.length', 4);

// Select the "Experiment" filter, enter a value to filter by
pipelineRunsGlobal
Expand All @@ -421,9 +492,10 @@ describe('Pipeline runs', () => {
pipelineRunFilterBar.selectExperimentByName('Test Experiment 1');

// Verify only rows with selected experiment exist
activeRunsTable.findRows().should('have.length', 2);
activeRunsTable.findRows().should('have.length', 3);
activeRunsTable.getRowByName('Test active run 1').find().should('exist');
activeRunsTable.getRowByName('Test active run 3').find().should('exist');
activeRunsTable.getRowByName('Test active run 4').find().should('exist');
});

it('filter by pipeline version', () => {
Expand Down Expand Up @@ -455,7 +527,7 @@ describe('Pipeline runs', () => {

it('filter by started', () => {
// Verify initial run rows exist
activeRunsTable.findRows().should('have.length', 3);
activeRunsTable.findRows().should('have.length', 4);

// Select the "Started" filter, select a value to filter by
pipelineRunsGlobal
Expand Down Expand Up @@ -498,7 +570,7 @@ describe('Pipeline runs', () => {

it('filter by status', () => {
// Verify initial run rows exist
activeRunsTable.findRows().should('have.length', 3);
activeRunsTable.findRows().should('have.length', 4);

// Select the "Status" filter
pipelineRunsGlobal
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ import {
Spinner,
Truncate,
EmptyStateHeader,
PageSection,
} from '@patternfly/react-core';
import { ExclamationTriangleIcon } from '@patternfly/react-icons';
import { useNavigate, useParams } from 'react-router-dom';
import { ExclamationCircleIcon } from '@patternfly/react-icons/dist/esm/icons/exclamation-circle-icon';
import ApplicationsPage from '~/pages/ApplicationsPage';
Expand Down Expand Up @@ -79,11 +81,10 @@ const PipelineRunDetails: PipelineCoreDetailsPageComponent = ({ breadcrumbPath,
() => nodes.find((n) => n.id === selectedId),
[selectedId, nodes],
);

const getFirstNode = (firstId: string) => nodes.find((n) => n.id === firstId);

const loaded = runLoaded && (versionLoaded || !!run?.pipeline_spec);
const error = versionError || runError;
const error = runError;

if (error) {
return (
Expand All @@ -98,7 +99,7 @@ const PipelineRunDetails: PipelineCoreDetailsPageComponent = ({ breadcrumbPath,
);
}

if (!loaded || (!executionsLoaded && !executionsError)) {
if ((!loaded && !versionError) || (!executionsLoaded && !executionsError)) {
return (
<Bullseye>
<Spinner />
Expand Down Expand Up @@ -129,7 +130,7 @@ const PipelineRunDetails: PipelineCoreDetailsPageComponent = ({ breadcrumbPath,
setDetailsTab(selection);
setSelectedId(null);
}}
pipelineRunDetails={run && pipelineSpec ? run : undefined}
pipelineRunDetails={run ?? undefined}
/>
}
>
Expand Down Expand Up @@ -158,6 +159,7 @@ const PipelineRunDetails: PipelineCoreDetailsPageComponent = ({ breadcrumbPath,
}
loaded={loaded}
loadError={error}
versionError={versionError}
breadcrumb={
<Breadcrumb>
{breadcrumbPath}
Expand All @@ -175,7 +177,27 @@ const PipelineRunDetails: PipelineCoreDetailsPageComponent = ({ breadcrumbPath,
}
empty={false}
>
{nodes.length === 0 ? (
{versionError ? (
<PageSection isFilled>
<EmptyState>
<EmptyStateHeader
data-testid="error-state-title"
titleText="Error loading pipeline run graph"
icon={
<EmptyStateIcon
color="var(--pf-v5-global--warning-color--100)"
icon={ExclamationTriangleIcon}
/>
}
headingLevel="h2"
/>
<EmptyStateBody>
Unable to load this graph because the pipeline version that it belongs to
has been deleted.
</EmptyStateBody>
</EmptyState>
</PageSection>
) : nodes.length === 0 ? (
<PipelineTopologyEmpty />
) : (
<PipelineTopology
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ const PipelineRunTabDetails: React.FC<PipelineRunTabDetailsProps> = ({
),
},
]
: error
? [{ key: 'Pipeline version', value: 'No pipeline version' }]
: []),
{
key: 'Project',
Expand Down
4 changes: 3 additions & 1 deletion frontend/src/pages/ApplicationsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ type ApplicationsPageProps = {
loaded: boolean;
empty: boolean;
loadError?: Error;
versionError?: Error;
children?: React.ReactNode;
errorMessage?: string;
emptyMessage?: string;
Expand All @@ -44,6 +45,7 @@ const ApplicationsPage: React.FC<ApplicationsPageProps> = ({
loaded,
empty,
loadError,
versionError,
children,
errorMessage,
emptyMessage,
Expand Down Expand Up @@ -97,7 +99,7 @@ const ApplicationsPage: React.FC<ApplicationsPageProps> = ({
);
}

if (!loaded) {
if (!loaded && !versionError) {
return (
loadingContent || (
<PageSection isFilled>
Expand Down

0 comments on commit 950660e

Please sign in to comment.