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

feat: e2e add experiment row "kill" action tests #10148

Closed
wants to merge 18 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
7f06950
feat: Add ExperimentMoveModal component and update ExperimentActionDr…
thiagodallacqua-hpe Oct 16, 2024
76ec63d
refactor(e2e): Remove unused V1Workspace import and clean up test code.
thiagodallacqua-hpe Oct 16, 2024
1f5fbb2
refactor: Add destinationWorkspace to move experiment function.
thiagodallacqua-hpe Oct 16, 2024
7a876ef
lint
thiagodallacqua-hpe Oct 18, 2024
de9a8d4
lint
thiagodallacqua-hpe Oct 18, 2024
c9c50ca
feat: Update move experiment test with correct workspace and project …
thiagodallacqua-hpe Oct 18, 2024
bee56b2
refactor: Improve code readability by formatting lines in experimentL…
thiagodallacqua-hpe Oct 21, 2024
0f897e7
refactor: Update data-test attributes and improve selectors.
thiagodallacqua-hpe Oct 22, 2024
10f4b88
refactor: Simplify experiment move actions in e2e test.
thiagodallacqua-hpe Oct 22, 2024
dd87db5
chore: fix assertion
thiagodallacqua-hpe Oct 22, 2024
304300b
fix: removed/add properties to fix config files
thiagodallacqua-hpe Oct 29, 2024
26aa3d1
feat(webui): refactor experiment list waitTableStable function and ad…
thiagodallacqua-hpe Oct 29, 2024
73c8f31
rebased
thiagodallacqua-hpe Oct 29, 2024
19fc774
refactor: Update experiment creation process in test suites
thiagodallacqua-hpe Oct 30, 2024
0a9b212
chore: remove bilerplate file from playwrite
thiagodallacqua-hpe Oct 30, 2024
06df08e
feat: Add experiment kill command in experimentList spec
thiagodallacqua-hpe Oct 31, 2024
3bde7fc
refactor(tests): remove console log from experiment list test
thiagodallacqua-hpe Nov 1, 2024
ab520da
feat(tests): pause experiment creation in E2E tests
thiagodallacqua-hpe Nov 5, 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
4 changes: 4 additions & 0 deletions examples/tutorials/core_api/2_checkpoints.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,9 @@ entrypoint: python3 2_checkpoints.py
searcher:
name: single
metric: x
max_length: 14
smaller_is_better: true
source_checkpoint_uuid: null
source_trial_id: null

max_restarts: 0
1 change: 1 addition & 0 deletions examples/tutorials/mnist_pytorch/adaptive.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ searcher:
metric: validation_loss
smaller_is_better: true
max_trials: 16
max_length: 14
time_metric: batches
max_time: 937 # 60,000 training images with batch size 64
entrypoint: python3 train.py --epochs 1
2 changes: 1 addition & 1 deletion webui/react/src/components/ExperimentStopModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ const ExperimentStopModalComponent: React.FC<Props> = ({ experimentId, onClose }
}}
title="Confirm Stop"
onClose={onClose}>
<div>
<div data-test="experiment">
Are you sure you want to {actionCopy} {experimentId}?
</div>
<Checkbox checked={type === ActionType.Cancel} onChange={handleCheckBoxChange}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { DropdownMenu } from 'e2e/models/common/hew/Dropdown';

import ExperimentEditModal from './ExperimentEditModal';
import ExperimentMoveModal from './ExperimentMoveModal';
import ExperimentStopModal from './ExperimentStopModal';

/**
* Represents the ExperimentActionDropdown component in src/components/ExperimentActionDropdown.tsx
Expand All @@ -18,4 +19,7 @@ export class ExperimentActionDropdown extends DropdownMenu {
readonly moveModal = new ExperimentMoveModal({
root: this.root,
});
readonly stopKillModal = new ExperimentStopModal({
root: this.root,
});
}
12 changes: 12 additions & 0 deletions webui/react/src/e2e/models/components/ExperimentStopModal.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { Modal } from 'e2e/models/common/hew/Modal';
import { Select } from 'e2e/models/common/hew/Select';

/**
* Represents the ExperimentStopModal component in src/components/ExperimentStopModal.tsx
*/
export default class ExperimentStopModal extends Modal {
readonly targetExperiment = new Select({
parent: this,
selector: '[data-test="experiment"]',
});
}
53 changes: 48 additions & 5 deletions webui/react/src/e2e/tests/experimentList.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { detExecSync, fullPath } from 'e2e/utils/detCLI';
import { safeName } from 'e2e/utils/naming';
import { repeatWithFallback } from 'e2e/utils/polling';
import { V1Project } from 'services/api-ts-sdk';
import { ExperimentBase } from 'types';
import { ExperimentBase, RunState } from 'types';

dayjs.extend(utcPlugin);

Expand Down Expand Up @@ -600,6 +600,7 @@ test.describe('Experiment List', () => {
test.describe('Row Actions', () => {
let destinationProject: V1Project;
let experimentId: number;
let killExperiment: number;

// create a new project, workspace and experiment
test.beforeAll(
Expand All @@ -616,15 +617,13 @@ test.describe('Experiment List', () => {
)
).project;

const expId = Number(
experimentId = Number(
detExecSync(
`experiment create ${fullPath('examples/tutorials/mnist_pytorch/adaptive.yaml')} --paused --project_id ${project.id}`,
).split(' ')[2],
); // returns in the format "Created experiment <exp_id>"

if (Number.isNaN(expId)) throw new Error('No experiment ID was found');

experimentId = expId;
if (Number.isNaN(experimentId)) throw new Error('No experiment ID was found');
},
);

Expand All @@ -634,6 +633,10 @@ test.describe('Experiment List', () => {
detExecSync(`experiment kill ${experimentId}`);
detExecSync(`experiment delete ${experimentId} --y`);
}
if (killExperiment !== undefined) {
detExecSync(`experiment kill ${killExperiment}`);
detExecSync(`experiment delete ${killExperiment} --y`);
}

await backgroundApiProject.deleteProject(destinationProject.id);
});
Expand Down Expand Up @@ -677,5 +680,45 @@ test.describe('Experiment List', () => {
);
await expect(newProjectRows.length).toBe(1);
});

test('kill experiment', async ({
newProject: {
response: { project },
},
newWorkspace: {
response: { workspace },
},
}) => {
killExperiment = Number(
detExecSync(
`experiment create ${fullPath('examples/tutorials/core_api/2_checkpoints.yaml')} --paused --project_id ${project.id}`,
).split(' ')[2],
);
if (Number.isNaN(killExperiment)) throw new Error('No experiment ID was found');

const grid = projectDetailsPage.f_experimentList.dataGrid;
await grid.setColumnHeight();
await grid.headRow.setColumnDefs();
const newExperimentRow =
await projectDetailsPage.f_experimentList.dataGrid.getRowByColumnValue(
'ID',
killExperiment.toString(),
);

const experimentActionDropdown = await newExperimentRow.experimentActionDropdown.open();

await experimentActionDropdown.menuItem('Kill').pwLocator.click();

await experimentActionDropdown.stopKillModal.pwLocator.waitFor({ state: 'visible' });
await experimentActionDropdown.stopKillModal.footer.pwLocator.getByText('Kill').click();
await experimentActionDropdown.stopKillModal.pwLocator.waitFor({ state: 'hidden' });

const experiments: ExperimentBase[] = JSON.parse(
detExecSync(`project list-experiments --json ${workspace.name} ${project.name}`),
);
const killedExperiment = experiments.find(({ id }) => id === killExperiment);
await expect(killedExperiment).not.toBeUndefined();
await expect(killedExperiment?.state).toContain(RunState.Canceled);
});
});
});
Loading