[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