Skip to content

Commit

Permalink
Set experiment as Default on create run/schedule page
Browse files Browse the repository at this point in the history
  • Loading branch information
DaoDaoNoCode committed Jul 15, 2024
1 parent 48b04aa commit d606180
Show file tree
Hide file tree
Showing 6 changed files with 194 additions and 71 deletions.
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
/* eslint-disable camelcase */
import type {
ExperimentKFv2,
PipelineKFv2,
PipelineRecurringRunKFv2,
PipelineRunKFv2,
PipelineVersionKFv2,
import {
type ExperimentKFv2,
type PipelineKFv2,
type PipelineRecurringRunKFv2,
type PipelineRunKFv2,
type PipelineVersionKFv2,
} from '~/concepts/pipelines/kfTypes';
import { buildMockExperiments, buildMockRunKF } from '~/__mocks__';
import { buildMockRunKF } from '~/__mocks__';
import { buildMockPipelines } from '~/__mocks__/mockPipelinesProxy';
import { buildMockPipelineVersionsV2 } from '~/__mocks__/mockPipelineVersionsProxy';
import { Contextual } from '~/__tests__/cypress/cypress/pages/components/Contextual';
Expand Down Expand Up @@ -159,13 +159,58 @@ export class CreateRunPage {
cy.findByTestId('pipeline-selector-table-list').find('td').contains(name).click();
}

mockGetExperiments(namespace: string, experiments?: ExperimentKFv2[]): Cypress.Chainable<null> {
mockGetExperiments(namespace: string, experiments: ExperimentKFv2[]): Cypress.Chainable<null> {
return cy.interceptOdh(
'GET /api/service/pipelines/:namespace/:serviceName/apis/v2beta1/experiments',
{
path: { namespace, serviceName: 'dspa' },
},
buildMockExperiments(experiments),
(req) => {
// eslint-disable-next-line @typescript-eslint/naming-convention
const { filter, sort_by, page_size } = req.query;
let results = experiments;
if (sort_by) {
const fields = sort_by.toString().split(' ');
const sortField = fields[0];
const sortDirection = fields[1];
// more fields to be added
if (sortField === 'created_at') {
if (sortDirection === 'desc') {
results = results.toSorted(
(a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime(),
);
} else {
results = results.toSorted(
(a, b) => new Date(a.created_at).getTime() - new Date(b.created_at).getTime(),
);
}
}
}
if (filter) {
const { predicates } = JSON.parse(filter.toString());

if (predicates.length > 0) {
predicates.forEach((predicate: { key: string; string_value: string }) => {
// eslint-disable-next-line @typescript-eslint/naming-convention
const { key, string_value } = predicate;
if (key === 'storage_state') {
results = results.filter((experiment) => experiment.storage_state === string_value);
}
if (key === 'name') {
results = results.filter((experiment) =>
experiment.display_name.includes(string_value),
);
}
});
}
}

if (page_size) {
results = results.slice(0, Number(page_size));
}

req.reply({ experiments: results, total_size: results.length });
},
);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* eslint-disable camelcase */

import type { ExperimentKFv2 } from '~/concepts/pipelines/kfTypes';
import { type ExperimentKFv2 } from '~/concepts/pipelines/kfTypes';
import { TableRow } from '~/__tests__/cypress/cypress/pages/components/table';

class ExperimentsTabs {
Expand Down Expand Up @@ -30,29 +30,57 @@ class ExperimentsTabs {
return new ExperimentsTable(() => cy.findByTestId('experiments-archived-tab-content'));
}

mockGetExperiments(
namespace: string,
activeExperiments: ExperimentKFv2[],
archivedExperiments: ExperimentKFv2[] = [],
) {
mockGetExperiments(namespace: string, experiments: ExperimentKFv2[]): Cypress.Chainable<null> {
return cy.interceptOdh(
'GET /api/service/pipelines/:namespace/:serviceName/apis/v2beta1/experiments',
{
path: { namespace, serviceName: 'dspa' },
},
(req) => {
const { predicates } = JSON.parse(req.query.filter.toString());

if (predicates.length === 0) {
req.reply({ experiments: activeExperiments, total_size: activeExperiments.length });
} else {
const [{ string_value: experimentState }] = predicates;
if (experimentState === 'ARCHIVED') {
req.reply({ experiments: archivedExperiments, total_size: archivedExperiments.length });
} else {
req.reply({ experiments: activeExperiments, total_size: activeExperiments.length });
// eslint-disable-next-line @typescript-eslint/naming-convention
const { filter, sort_by, page_size } = req.query;
let results = experiments;
if (sort_by) {
const fields = sort_by.toString().split(' ');
const sortField = fields[0];
const sortDirection = fields[1];
// more fields to be added
if (sortField === 'created_at') {
if (sortDirection === 'desc') {
results = results.toSorted(
(a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime(),
);
} else {
results = results.toSorted(
(a, b) => new Date(a.created_at).getTime() - new Date(b.created_at).getTime(),
);
}
}
}
if (filter) {
const { predicates } = JSON.parse(filter.toString());

if (predicates.length > 0) {
predicates.forEach((predicate: { key: string; string_value: string }) => {
// eslint-disable-next-line @typescript-eslint/naming-convention
const { key, string_value } = predicate;
if (key === 'storage_state') {
results = results.filter((experiment) => experiment.storage_state === string_value);
}
if (key === 'name') {
results = results.filter((experiment) =>
experiment.display_name.includes(string_value),
);
}
});
}
}

if (page_size) {
results = results.slice(0, Number(page_size));
}

req.reply({ experiments: results, total_size: results.length });
},
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@ const mockExperiments = [
}),
];

const mockArchivedExperiments = mockExperiments.map((experiment) => ({
...experiment,
storage_state: StorageStateKF.ARCHIVED,
}));

const mockActiveRuns = buildMockRunKF({
display_name: 'Test active run 4',
run_id: 'run-4',
Expand Down Expand Up @@ -109,10 +114,7 @@ describe('Experiments', () => {
experimentsTabs.getActiveExperimentsTable().findFilterTextField().type('Test experiment 2');

// Mock experiments (filtered by typed experiment name)
experimentsTabs.mockGetExperiments(
projectName,
mockExperiments.filter((exp) => exp.display_name.includes('Test experiment 2')),
);
experimentsTabs.mockGetExperiments(projectName, mockExperiments);

// Verify only rows with the typed experiment name exist
experimentsTabs.getActiveExperimentsTable().findRows().should('have.length', 1);
Expand All @@ -125,6 +127,7 @@ describe('Experiments', () => {

it('archive a single experiment', () => {
const [experimentToArchive] = mockExperiments;
const [experimentArchived] = mockArchivedExperiments;

const activeExperimentsTable = experimentsTabs.getActiveExperimentsTable();

Expand All @@ -134,14 +137,14 @@ describe('Experiments', () => {
.findKebabAction('Archive')
.click();

experimentsTabs.mockGetExperiments(
projectName,
[mockExperiments[1], mockExperiments[2]],
[experimentToArchive],
);
archiveExperimentModal.findConfirmInput().type(experimentToArchive.display_name);
experimentsTabs.mockGetExperiments(projectName, [
mockExperiments[1],
mockExperiments[2],
experimentArchived,
]);
archiveExperimentModal.findConfirmInput().type(experimentArchived.display_name);
archiveExperimentModal.findSubmitButton().click();
activeExperimentsTable.shouldRowNotBeVisible(experimentToArchive.display_name);
activeExperimentsTable.shouldRowNotBeVisible(experimentArchived.display_name);

experimentsTabs.findArchivedTab().click();
experimentsTabs
Expand All @@ -159,7 +162,7 @@ describe('Experiments', () => {
});

activeExperimentsTable.findActionsKebab().findDropdownItem('Archive').click();
experimentsTabs.mockGetExperiments(projectName, [], mockExperiments);
experimentsTabs.mockGetExperiments(projectName, mockArchivedExperiments);
bulkArchiveExperimentModal.findConfirmInput().type('Archive 3 experiments');
bulkArchiveExperimentModal.findSubmitButton().click();
activeExperimentsTable.findEmptyState().should('exist');
Expand All @@ -178,12 +181,13 @@ describe('Experiments', () => {
describe('Archived experiments', () => {
beforeEach(() => {
initIntercepts();
experimentsTabs.mockGetExperiments(projectName, [], mockExperiments);
experimentsTabs.mockGetExperiments(projectName, mockArchivedExperiments);
experimentsTabs.visit(projectName);
experimentsTabs.findArchivedTab().click();
});
it('restore a single experiment', () => {
const [experimentToRestore] = mockExperiments;
const [experimentToRestore] = mockArchivedExperiments;
const [experimentRestored] = mockExperiments;

const archivedExperimentsTable = experimentsTabs.getArchivedExperimentsTable();

Expand All @@ -196,11 +200,11 @@ describe('Experiments', () => {
.findKebabAction('Restore')
.click();

experimentsTabs.mockGetExperiments(
projectName,
[experimentToRestore],
[mockExperiments[1], mockExperiments[2]],
);
experimentsTabs.mockGetExperiments(projectName, [
mockArchivedExperiments[1],
mockArchivedExperiments[2],
experimentRestored,
]);
restoreExperimentModal.findSubmitButton().click();
archivedExperimentsTable.shouldRowNotBeVisible(experimentToRestore.display_name);

Expand All @@ -214,7 +218,7 @@ describe('Experiments', () => {

it('restore multiple experiments', () => {
const archivedExperimentsTable = experimentsTabs.getArchivedExperimentsTable();
mockExperiments.forEach((archivedExperiment) => {
mockArchivedExperiments.forEach((archivedExperiment) => {
archivedExperimentsTable.mockRestoreExperiment(
archivedExperiment.experiment_id,
projectName,
Expand All @@ -225,7 +229,7 @@ describe('Experiments', () => {
.click();
});
archivedExperimentsTable.findRestoreExperimentButton().click();
experimentsTabs.mockGetExperiments(projectName, mockExperiments, []);
experimentsTabs.mockGetExperiments(projectName, mockExperiments);
bulkRestoreExperimentModal.findSubmitButton().click();
archivedExperimentsTable.findEmptyState().should('exist');

Expand Down Expand Up @@ -318,7 +322,7 @@ describe('Experiments', () => {

describe('Runs page for archived experiment', () => {
const archivedExperimentsTable = experimentsTabs.getArchivedExperimentsTable();
const mockExperiment = { ...mockExperiments[0], storage_state: StorageStateKF.ARCHIVED };
const [mockArchivedExperiment] = mockArchivedExperiments;

beforeEach(() => {
initIntercepts();
Expand All @@ -328,10 +332,10 @@ describe('Runs page for archived experiment', () => {
path: {
namespace: projectName,
serviceName: 'dspa',
experimentId: mockExperiment.experiment_id,
experimentId: mockArchivedExperiment.experiment_id,
},
},
mockExperiment,
mockArchivedExperiment,
);
cy.interceptOdh(
'GET /api/service/pipelines/:namespace/:serviceName/apis/v2beta1/runs',
Expand All @@ -348,14 +352,20 @@ describe('Runs page for archived experiment', () => {
},
{ recurringRuns: [buildMockRecurringRunKF({ status: RecurringRunStatus.DISABLED })] },
);
experimentsTabs.mockGetExperiments(projectName, [], mockExperiments);
experimentsTabs.mockGetExperiments(projectName, mockArchivedExperiments);
experimentsTabs.visit(projectName);
experimentsTabs.findArchivedTab().click();
archivedExperimentsTable.getRowByName(mockExperiment.display_name).find().find('a').click();
archivedExperimentsTable
.getRowByName(mockArchivedExperiment.display_name)
.find()
.find('a')
.click();
});

it('navigates to the runs page when clicking an experiment name', () => {
verifyRelativeURL(`/experiments/${projectName}/${mockExperiment.experiment_id}/runs`);
verifyRelativeURL(
`/experiments/${projectName}/${mockArchivedExperiment.experiment_id}/runs/archived`,
);
cy.findByLabelText('Breadcrumb').findByText(`Experiments - ${projectName}`);
});

Expand Down
Loading

0 comments on commit d606180

Please sign in to comment.