18881: Fixes process state indicator, with tests.
authorLucas Di Pentima <lucas.dipentima@curii.com>
Fri, 1 Apr 2022 15:20:40 +0000 (12:20 -0300)
committerLucas Di Pentima <lucas.dipentima@curii.com>
Thu, 7 Apr 2022 17:47:23 +0000 (14:47 -0300)
Arvados-DCO-1.1-Signed-off-by: Lucas Di Pentima <lucas.dipentima@curii.com>

src/common/custom-theme.ts
src/store/process-panel/process-panel-actions.ts
src/store/processes/process.ts
src/views-components/data-explorer/renderers.test.tsx

index 74dee7f6c9cec71047ad0373162b5d10dc6786d1..cff18538424c57cdc5194a0c05afe9c1e2e4321e 100644 (file)
@@ -26,10 +26,12 @@ interface Colors {
     yellow700: string;
     red900: string;
     blue500: string;
+    grey500: string;
     purple: string;
 }
 
 const arvadosPurple = '#361336';
+const grey500 = grey["500"];
 const grey600 = grey["600"];
 const grey700 = grey["700"];
 const grey900 = grey["900"];
@@ -44,6 +46,7 @@ export const themeOptions: ArvadosThemeOptions = {
             yellow700: yellow["700"],
             red900: red['900'],
             blue500: blue['500'],
+            grey500: grey500,
             purple: arvadosPurple
         }
     },
index 962f5dfcf3b6a123aaaa3a7993ef7844bf77a39c..e77c300d8c07cc50a73da44734a59b69b1737211 100644 (file)
@@ -56,6 +56,8 @@ export const initProcessPanelFilters = processPanelActions.SET_PROCESS_PANEL_FIL
     ProcessStatus.COMPLETED,
     ProcessStatus.FAILED,
     ProcessStatus.RUNNING,
-    ProcessStatus.LOCKED,
+    ProcessStatus.ONHOLD,
+    ProcessStatus.FAILING,
+    ProcessStatus.WARNING,
     ProcessStatus.CANCELLED
 ]);
index 60505be0c4c0f6a20ca160501206b8c28994b9fd..37cdd2b34668a0dc45bbb34941662a6bd6811edb 100644 (file)
@@ -19,10 +19,12 @@ export enum ProcessStatus {
     CANCELLED = 'Cancelled',
     COMPLETED = 'Completed',
     DRAFT = 'Draft',
+    FAILING = 'Failing',
     FAILED = 'Failed',
-    LOCKED = 'Locked',
+    ONHOLD = 'On hold',
     QUEUED = 'Queued',
     RUNNING = 'Running',
+    WARNING = 'Warning',
     UNKNOWN = 'Unknown',
 }
 
@@ -71,17 +73,20 @@ export const getProcessRuntime = ({ container }: Process) => {
     }
 };
 
-export const getProcessStatusColor = (status: string, { customs, palette }: ArvadosTheme) => {
+export const getProcessStatusColor = (status: string, { customs }: ArvadosTheme) => {
     switch (status) {
         case ProcessStatus.RUNNING:
             return customs.colors.blue500;
         case ProcessStatus.COMPLETED:
             return customs.colors.green700;
+        case ProcessStatus.WARNING:
+            return customs.colors.yellow700;
+        case ProcessStatus.FAILING:
         case ProcessStatus.CANCELLED:
         case ProcessStatus.FAILED:
             return customs.colors.red900;
         default:
-            return palette.grey["500"];
+            return customs.colors.grey500;
     }
 };
 
@@ -90,18 +95,26 @@ export const getProcessStatus = ({ containerRequest, container }: Process): Proc
         case containerRequest.state === ContainerRequestState.UNCOMMITTED:
             return ProcessStatus.DRAFT;
 
+        case containerRequest.priority === 0:
+            return ProcessStatus.ONHOLD;
+
         case container && container.state === ContainerState.COMPLETE && container.exitCode === 0:
             return ProcessStatus.COMPLETED;
 
-        case containerRequest.priority === 0:
         case container && container.state === ContainerState.CANCELLED:
             return ProcessStatus.CANCELLED;
 
-        case container && container.state === ContainerState.QUEUED:
+        case container && (container.state === ContainerState.QUEUED ||
+            container.state === ContainerState.LOCKED):
             return ProcessStatus.QUEUED;
 
-        case container && container.state === ContainerState.LOCKED:
-            return ProcessStatus.LOCKED;
+        case container && container.state === ContainerState.RUNNING &&
+            !!container.runtimeStatus.error:
+            return ProcessStatus.FAILING;
+
+        case container && container.state === ContainerState.RUNNING &&
+            !!container.runtimeStatus.warning:
+            return ProcessStatus.WARNING;
 
         case container && container.state === ContainerState.RUNNING:
             return ProcessStatus.RUNNING;
index f0efdf74322345f9ac661aa2e72d3f244164baed..fc9325bd2db66a47459000e74162a9dbf56fb09a 100644 (file)
@@ -4,11 +4,14 @@
 
 import React from 'react';
 import { mount, configure } from 'enzyme';
-import { ResourceFileSize } from './renderers';
+import { ProcessStatus, ResourceFileSize } from './renderers';
 import Adapter from "enzyme-adapter-react-16";
 import { Provider } from 'react-redux';
 import configureMockStore from 'redux-mock-store'
 import { ResourceKind } from '../../models/resource';
+import { ContainerRequestState as CR } from '../../models/container-request';
+import { ContainerState as C } from '../../models/container';
+import { ProcessStatus as PS } from '../../store/processes/process';
 
 const middlewares = [];
 const mockStore = configureMockStore(middlewares);
@@ -18,6 +21,65 @@ configure({ adapter: new Adapter() });
 describe('renderers', () => {
     let props = null;
 
+    describe('ProcessStatus', () => {
+        props = {
+            uuid: 'zzzzz-xvhdp-zzzzzzzzzzzzzzz',
+            theme: {
+                customs: {
+                    colors: {
+                        // Color values are arbitrary, but they should be
+                        // representative of the colors used in the UI.
+                        blue500: 'rgb(0, 0, 255)',
+                        green700: 'rgb(0, 255, 0)',
+                        yellow700: 'rgb(255, 255, 0)',
+                        red900: 'rgb(255, 0, 0)',
+                        grey500: 'rgb(128, 128, 128)',
+                    }
+                }
+            },
+        };
+
+        [
+            // CR Status ; Priority ; C Status ; Exit Code ; C RuntimeStatus ; Expected label ; Expected Color
+            [CR.COMMITTED, 1, C.RUNNING, null, {}, PS.RUNNING, props.theme.customs.colors.blue500],
+            [CR.COMMITTED, 1, C.RUNNING, null, {error: 'whoops'}, PS.FAILING, props.theme.customs.colors.red900],
+            [CR.COMMITTED, 1, C.RUNNING, null, {warning: 'watch out!'}, PS.WARNING, props.theme.customs.colors.yellow700],
+            [CR.FINAL, 1, C.CANCELLED, null, {}, PS.CANCELLED, props.theme.customs.colors.red900],
+            [CR.FINAL, 1, C.COMPLETE, 137, {}, PS.FAILED, props.theme.customs.colors.red900],
+            [CR.FINAL, 1, C.COMPLETE, 0, {}, PS.COMPLETED, props.theme.customs.colors.green700],
+            [CR.COMMITTED, 0, C.LOCKED, null, {}, PS.ONHOLD, props.theme.customs.colors.grey500],
+            [CR.COMMITTED, 0, C.QUEUED, null, {}, PS.ONHOLD, props.theme.customs.colors.grey500],
+            [CR.COMMITTED, 1, C.LOCKED, null, {}, PS.QUEUED, props.theme.customs.colors.grey500],
+            [CR.COMMITTED, 1, C.QUEUED, null, {}, PS.QUEUED, props.theme.customs.colors.grey500],
+        ].forEach(([crState, crPrio, cState, exitCode, rs, eLabel, eColor]) => {
+            it(`should render the state label '${eLabel}' and color '${eColor}' for CR state=${crState}, priority=${crPrio}, C state=${cState}, exitCode=${exitCode} and RuntimeStatus=${JSON.stringify(rs)}`, () => {
+                const containerUuid = 'zzzzz-dz642-zzzzzzzzzzzzzzz';
+                const store = mockStore({ resources: {
+                    [props.uuid]: {
+                        kind: ResourceKind.CONTAINER_REQUEST,
+                        state: crState,
+                        containerUuid: containerUuid,
+                        priority: crPrio,
+                    },
+                    [containerUuid]: {
+                        kind: ResourceKind.CONTAINER,
+                        state: cState,
+                        runtimeStatus: rs,
+                        exitCode: exitCode,
+                    },
+                }});
+
+                const wrapper = mount(<Provider store={store}>
+                        <ProcessStatus {...props} />
+                    </Provider>);
+
+                expect(wrapper.text()).toEqual(eLabel);
+                expect(getComputedStyle(wrapper.getDOMNode())
+                    .getPropertyValue('color')).toEqual(eColor);
+            });
+        })
+    });
+
     describe('ResourceFileSize', () => {
         beforeEach(() => {
             props = {