[arvados-workbench2] created: 2.5.0-55-g4968c154
git repository hosting
git at public.arvados.org
Wed Feb 15 21:36:16 UTC 2023
at 4968c1548af68dde9760766f6f0db667edaae7de (commit)
commit 4968c1548af68dde9760766f6f0db667edaae7de
Author: Stephen Smith <stephen at curii.com>
Date: Wed Feb 15 16:35:47 2023 -0500
20000: Add test for process cancel button, rename Run Process to Run
Arvados-DCO-1.1-Signed-off-by: Stephen Smith <stephen at curii.com>
diff --git a/cypress/integration/process.spec.js b/cypress/integration/process.spec.js
index 02657b39..851e3395 100644
--- a/cypress/integration/process.spec.js
+++ b/cypress/integration/process.spec.js
@@ -1170,7 +1170,191 @@ describe('Process tests', function() {
});
cy.get('[data-cy=process-details]').should('contain', copiedCrName);
- cy.get('[data-cy=process-details]').find('button').contains('Run Process');
+ cy.get('[data-cy=process-details]').find('button').contains('Run');
+ });
+
+ const getFakeContainer = (fakeContainerUuid) => ({
+ href: `/containers/${fakeContainerUuid}`,
+ kind: "arvados#container",
+ etag: "ecfosljpnxfari9a8m7e4yv06",
+ uuid: fakeContainerUuid,
+ owner_uuid: "zzzzz-tpzed-000000000000000",
+ created_at: "2023-02-13T15:55:47.308915000Z",
+ modified_by_client_uuid: "zzzzz-ozdt8-q6dzdi1lcc03155",
+ modified_by_user_uuid: "zzzzz-tpzed-000000000000000",
+ modified_at: "2023-02-15T19:12:45.987086000Z",
+ command: [
+ "arvados-cwl-runner",
+ "--api=containers",
+ "--local",
+ "--project-uuid=zzzzz-j7d0g-yr18k784zplfeza",
+ "/var/lib/cwl/workflow.json#main",
+ "/var/lib/cwl/cwl.input.json",
+ ],
+ container_image: "4ad7d11381df349e464694762db14e04+303",
+ cwd: "/var/spool/cwl",
+ environment: {},
+ exit_code: null,
+ finished_at: null,
+ locked_by_uuid: null,
+ log: null,
+ output: null,
+ output_path: "/var/spool/cwl",
+ progress: null,
+ runtime_constraints: {
+ API: true,
+ cuda: {
+ device_count: 0,
+ driver_version: "",
+ hardware_capability: "",
+ },
+ keep_cache_disk: 2147483648,
+ keep_cache_ram: 0,
+ ram: 1342177280,
+ vcpus: 1,
+ },
+ runtime_status: {},
+ started_at: null,
+ auth_uuid: null,
+ scheduling_parameters: {
+ max_run_time: 0,
+ partitions: [],
+ preemptible: false,
+ },
+ runtime_user_uuid: "zzzzz-tpzed-vllbpebicy84rd5",
+ runtime_auth_scopes: ["all"],
+ lock_count: 2,
+ gateway_address: null,
+ interactive_session_started: false,
+ output_storage_classes: ["default"],
+ output_properties: {},
+ cost: 0.0,
+ subrequests_cost: 0.0,
+ });
+
+ it('shows cancel button when appropriate', function() {
+ // Ignore collection requests
+ cy.intercept({method: 'GET', url: `**/arvados/v1/collections/*`}, {
+ statusCode: 200,
+ body: {}
+ });
+
+ // Uncommitted container
+ const crUncommitted = `Test process ${Math.floor(Math.random() * 999999)}`;
+ createContainerRequest(
+ activeUser,
+ crUncommitted,
+ 'arvados/jobs',
+ ['echo', 'hello world'],
+ false, 'Uncommitted')
+ .then(function(containerRequest) {
+ // Navigate to process and verify run / cancel button
+ cy.goToPath(`/processes/${containerRequest.uuid}`);
+ cy.waitForDom();
+ cy.get('[data-cy=process-details]').should('contain', crUncommitted);
+ cy.get('[data-cy=process-details]').find('button').contains('Run');
+ cy.get('[data-cy=process-cancel]').should('not.exist');
+ });
+
+ // Queued container
+ const crQueued = `Test process ${Math.floor(Math.random() * 999999)}`;
+ const fakeCrUuid = 'zzzzz-dz642-000000000000001';
+ createContainerRequest(
+ activeUser,
+ crQueued,
+ 'arvados/jobs',
+ ['echo', 'hello world'],
+ false, 'Committed')
+ .then(function(containerRequest) {
+ // Fake container uuid
+ cy.intercept({method: 'GET', url: `**/arvados/v1/container_requests/${containerRequest.uuid}`}, (req) => {
+ req.reply((res) => {
+ res.body.output_uuid = fakeCrUuid;
+ res.body.priority = 500;
+ res.body.state = "Committed";
+ });
+ });
+
+ // Fake container
+ const container = getFakeContainer(fakeCrUuid);
+ cy.intercept({method: 'GET', url: `**/arvados/v1/container/${fakeCrUuid}`}, {
+ statusCode: 200,
+ body: {...container, state: "Queued", priority: 500}
+ });
+
+ // Navigate to process and verify cancel button
+ cy.goToPath(`/processes/${containerRequest.uuid}`);
+ cy.waitForDom();
+ cy.get('[data-cy=process-details]').should('contain', crQueued);
+ cy.get('[data-cy=process-cancel]').contains('Cancel');
+ });
+
+ // Locked container
+ const crLocked = `Test process ${Math.floor(Math.random() * 999999)}`;
+ const fakeCrLockedUuid = 'zzzzz-dz642-000000000000002';
+ createContainerRequest(
+ activeUser,
+ crLocked,
+ 'arvados/jobs',
+ ['echo', 'hello world'],
+ false, 'Committed')
+ .then(function(containerRequest) {
+ // Fake container uuid
+ cy.intercept({method: 'GET', url: `**/arvados/v1/container_requests/${containerRequest.uuid}`}, (req) => {
+ req.reply((res) => {
+ res.body.output_uuid = fakeCrLockedUuid;
+ res.body.priority = 500;
+ res.body.state = "Committed";
+ });
+ });
+
+ // Fake container
+ const container = getFakeContainer(fakeCrLockedUuid);
+ cy.intercept({method: 'GET', url: `**/arvados/v1/container/${fakeCrLockedUuid}`}, {
+ statusCode: 200,
+ body: {...container, state: "Locked", priority: 500}
+ });
+
+ // Navigate to process and verify cancel button
+ cy.goToPath(`/processes/${containerRequest.uuid}`);
+ cy.waitForDom();
+ cy.get('[data-cy=process-details]').should('contain', crLocked);
+ cy.get('[data-cy=process-cancel]').contains('Cancel');
+ });
+
+ // On Hold container
+ const crOnHold = `Test process ${Math.floor(Math.random() * 999999)}`;
+ const fakeCrOnHoldUuid = 'zzzzz-dz642-000000000000003';
+ createContainerRequest(
+ activeUser,
+ crOnHold,
+ 'arvados/jobs',
+ ['echo', 'hello world'],
+ false, 'Committed')
+ .then(function(containerRequest) {
+ // Fake container uuid
+ cy.intercept({method: 'GET', url: `**/arvados/v1/container_requests/${containerRequest.uuid}`}, (req) => {
+ req.reply((res) => {
+ res.body.output_uuid = fakeCrOnHoldUuid;
+ res.body.priority = 0;
+ res.body.state = "Committed";
+ });
+ });
+
+ // Fake container
+ const container = getFakeContainer(fakeCrOnHoldUuid);
+ cy.intercept({method: 'GET', url: `**/arvados/v1/container/${fakeCrOnHoldUuid}`}, {
+ statusCode: 200,
+ body: {...container, state: "Queued", priority: 0}
+ });
+
+ // Navigate to process and verify cancel button
+ cy.goToPath(`/processes/${containerRequest.uuid}`);
+ cy.waitForDom();
+ cy.get('[data-cy=process-details]').should('contain', crOnHold);
+ cy.get('[data-cy=process-details]').find('button').contains('Run');
+ cy.get('[data-cy=process-cancel]').should('not.exist');
+ });
});
});
diff --git a/src/views/process-panel/process-details-card.tsx b/src/views/process-panel/process-details-card.tsx
index 2376822f..be046004 100644
--- a/src/views/process-panel/process-details-card.tsx
+++ b/src/views/process-panel/process-details-card.tsx
@@ -119,7 +119,7 @@ export const ProcessDetailsCard = withStyles(styles)(
className={classes.runButton}
onClick={() => runAction && runAction(process.containerRequest.uuid)}>
<StartIcon />
- Run Process
+ Run
</Button>}
{process.container &&
(process.container.state === ContainerState.QUEUED ||
commit 892b80fe224c37bf06aeddcaac351a47c872ff63
Author: Stephen Smith <stephen at curii.com>
Date: Wed Feb 15 16:35:27 2023 -0500
20000: Use default button color for process run button
Arvados-DCO-1.1-Signed-off-by: Stephen Smith <stephen at curii.com>
diff --git a/src/views/process-panel/process-details-card.tsx b/src/views/process-panel/process-details-card.tsx
index 4a7d195e..2376822f 100644
--- a/src/views/process-panel/process-details-card.tsx
+++ b/src/views/process-panel/process-details-card.tsx
@@ -63,10 +63,6 @@ const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
}
},
runButton: {
- backgroundColor: theme.customs.colors.green700,
- '&:hover': {
- backgroundColor: theme.customs.colors.green800,
- },
padding: "0px 5px 0 0",
marginRight: "5px",
},
commit 638408423401f77842b731642891744458dbbb23
Author: Stephen Smith <stephen at curii.com>
Date: Wed Feb 15 16:34:37 2023 -0500
20000: Add run button to resume cancelled processes (priority 0)
Arvados-DCO-1.1-Signed-off-by: Stephen Smith <stephen at curii.com>
diff --git a/src/store/processes/processes-actions.ts b/src/store/processes/processes-actions.ts
index 815d6aec..cfda51dd 100644
--- a/src/store/processes/processes-actions.ts
+++ b/src/store/processes/processes-actions.ts
@@ -114,12 +114,24 @@ export const cancelRunningWorkflow = (uuid: string) =>
async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
try {
const process = await services.containerRequestService.update(uuid, { priority: 0 });
+ dispatch<any>(updateResources([process]));
return process;
} catch (e) {
throw new Error('Could not cancel the process.');
}
};
+export const resumeOnHoldWorkflow = (uuid: string) =>
+ async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
+ try {
+ const process = await services.containerRequestService.update(uuid, { priority: 500 });
+ dispatch<any>(updateResources([process]));
+ return process;
+ } catch (e) {
+ throw new Error('Could not resume the process.');
+ }
+ };
+
export const startWorkflow = (uuid: string) =>
async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
try {
diff --git a/src/views/process-panel/process-details-card.tsx b/src/views/process-panel/process-details-card.tsx
index 575545e5..4a7d195e 100644
--- a/src/views/process-panel/process-details-card.tsx
+++ b/src/views/process-panel/process-details-card.tsx
@@ -76,13 +76,22 @@ export interface ProcessDetailsCardDataProps {
process: Process;
cancelProcess: (uuid: string) => void;
startProcess: (uuid: string) => void;
+ resumeOnHoldWorkflow: (uuid: string) => void;
onContextMenu: (event: React.MouseEvent<HTMLElement>) => void;
}
type ProcessDetailsCardProps = ProcessDetailsCardDataProps & WithStyles<CssRules> & MPVPanelProps;
export const ProcessDetailsCard = withStyles(styles)(
- ({ cancelProcess, startProcess, onContextMenu, classes, process, doHidePanel, panelName }: ProcessDetailsCardProps) => {
+ ({ cancelProcess, startProcess, resumeOnHoldWorkflow, onContextMenu, classes, process, doHidePanel, panelName }: ProcessDetailsCardProps) => {
+ let runAction: ((uuid: string) => void) | undefined = undefined;
+ if (process.containerRequest.state === ContainerRequestState.UNCOMMITTED) {
+ runAction = startProcess;
+ } else if (process.containerRequest.state === ContainerRequestState.COMMITTED &&
+ process.containerRequest.priority === 0) {
+ runAction = resumeOnHoldWorkflow;
+ }
+
return <Card className={classes.card}>
<CardHeader
className={classes.header}
@@ -106,13 +115,13 @@ export const ProcessDetailsCard = withStyles(styles)(
</Tooltip>}
action={
<div>
- {process.containerRequest.state === ContainerRequestState.UNCOMMITTED &&
+ {runAction !== undefined &&
<Button
variant="contained"
size="small"
color="primary"
className={classes.runButton}
- onClick={() => startProcess(process.containerRequest.uuid)}>
+ onClick={() => runAction && runAction(process.containerRequest.uuid)}>
<StartIcon />
Run Process
</Button>}
diff --git a/src/views/process-panel/process-panel-root.tsx b/src/views/process-panel/process-panel-root.tsx
index 11b31ae0..d99c62ec 100644
--- a/src/views/process-panel/process-panel-root.tsx
+++ b/src/views/process-panel/process-panel-root.tsx
@@ -52,6 +52,7 @@ export interface ProcessPanelRootActionProps {
onToggle: (status: string) => void;
cancelProcess: (uuid: string) => void;
startProcess: (uuid: string) => void;
+ resumeOnHoldWorkflow: (uuid: string) => void;
onLogFilterChange: (filter: FilterOption) => void;
navigateToLog: (uuid: string) => void;
onCopyToClipboard: (uuid: string) => void;
@@ -124,6 +125,7 @@ export const ProcessPanelRoot = withStyles(styles)(
onContextMenu={event => props.onContextMenu(event, process)}
cancelProcess={props.cancelProcess}
startProcess={props.startProcess}
+ resumeOnHoldWorkflow={props.resumeOnHoldWorkflow}
/>
</MPVPanelContent>
<MPVPanelContent forwardProps xs="auto" data-cy="process-cmd">
diff --git a/src/views/process-panel/process-panel.tsx b/src/views/process-panel/process-panel.tsx
index 2ad7e2a3..9dcb72cf 100644
--- a/src/views/process-panel/process-panel.tsx
+++ b/src/views/process-panel/process-panel.tsx
@@ -25,7 +25,7 @@ import {
updateOutputParams,
loadNodeJson
} from 'store/process-panel/process-panel-actions';
-import { cancelRunningWorkflow, startWorkflow } from 'store/processes/processes-actions';
+import { cancelRunningWorkflow, resumeOnHoldWorkflow, startWorkflow } from 'store/processes/processes-actions';
import { navigateToLogCollection, setProcessLogsPanelFilter } from 'store/process-logs-panel/process-logs-panel-actions';
import { snackbarActions, SnackbarKind } from 'store/snackbar/snackbar-actions';
@@ -63,6 +63,7 @@ const mapDispatchToProps = (dispatch: Dispatch): ProcessPanelRootActionProps =>
},
cancelProcess: (uuid) => dispatch<any>(cancelRunningWorkflow(uuid)),
startProcess: (uuid) => dispatch<any>(startWorkflow(uuid)),
+ resumeOnHoldWorkflow: (uuid) => dispatch<any>(resumeOnHoldWorkflow(uuid)),
onLogFilterChange: (filter) => dispatch(setProcessLogsPanelFilter(filter.value)),
navigateToLog: (uuid) => dispatch<any>(navigateToLogCollection(uuid)),
loadInputs: (containerRequest) => dispatch<any>(loadInputs(containerRequest)),
commit f6be4e1d3549279defd4a0c1a38f42017102dcd5
Author: Stephen Smith <stephen at curii.com>
Date: Wed Feb 15 16:33:24 2023 -0500
20000: Correctly show process cancel on locked containers
Arvados-DCO-1.1-Signed-off-by: Stephen Smith <stephen at curii.com>
diff --git a/src/views/process-panel/process-details-card.tsx b/src/views/process-panel/process-details-card.tsx
index 06671a7a..575545e5 100644
--- a/src/views/process-panel/process-details-card.tsx
+++ b/src/views/process-panel/process-details-card.tsx
@@ -117,11 +117,12 @@ export const ProcessDetailsCard = withStyles(styles)(
Run Process
</Button>}
{process.container &&
- (process.container.state === ContainerState.RUNNING ||
- process.container.state === ContainerState.QUEUED) &&
+ (process.container.state === ContainerState.QUEUED ||
+ process.container.state === ContainerState.LOCKED ||
+ process.container.state === ContainerState.RUNNING) &&
process.containerRequest.priority !== null &&
process.containerRequest.priority > 0 &&
- <span className={classes.cancelButton} onClick={() => cancelProcess(process.containerRequest.uuid)}>Cancel</span>}
+ <span data-cy="process-cancel" className={classes.cancelButton} onClick={() => cancelProcess(process.containerRequest.uuid)}>Cancel</span>}
<ProcessStatus uuid={process.containerRequest.uuid} />
<Tooltip title="More options" disableFocusListener>
<IconButton
commit 33feddf6ac09a3b844a8571d360cf07ab9462c28
Author: Stephen Smith <stephen at curii.com>
Date: Tue Feb 14 13:38:32 2023 -0500
20000: Show process cancel on queued processes but only if priority > 0
Arvados-DCO-1.1-Signed-off-by: Stephen Smith <stephen at curii.com>
diff --git a/src/views/process-panel/process-details-card.tsx b/src/views/process-panel/process-details-card.tsx
index 4fa4701a..06671a7a 100644
--- a/src/views/process-panel/process-details-card.tsx
+++ b/src/views/process-panel/process-details-card.tsx
@@ -116,7 +116,11 @@ export const ProcessDetailsCard = withStyles(styles)(
<StartIcon />
Run Process
</Button>}
- {process.container && process.container.state === ContainerState.RUNNING &&
+ {process.container &&
+ (process.container.state === ContainerState.RUNNING ||
+ process.container.state === ContainerState.QUEUED) &&
+ process.containerRequest.priority !== null &&
+ process.containerRequest.priority > 0 &&
<span className={classes.cancelButton} onClick={() => cancelProcess(process.containerRequest.uuid)}>Cancel</span>}
<ProcessStatus uuid={process.containerRequest.uuid} />
<Tooltip title="More options" disableFocusListener>
-----------------------------------------------------------------------
hooks/post-receive
--
More information about the arvados-commits
mailing list