X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/ba638379056591dd0c40a192a8582df8d395b138..a6b824e63de4df4296a17d74d80ff2101820762d:/cypress/integration/process.spec.js diff --git a/cypress/integration/process.spec.js b/cypress/integration/process.spec.js index 071224323f..19544c9ca5 100644 --- a/cypress/integration/process.spec.js +++ b/cypress/integration/process.spec.js @@ -106,7 +106,7 @@ describe('Process tests', function() { }, event_type: 'stdout' }).then(function(log) { - cy.get('[data-cy=process-logs]') + cy.get('[data-cy=process-logs]', {timeout: 7000}) .should('not.contain', 'No logs yet') .and('contain', 'hello world'); }) @@ -206,7 +206,7 @@ describe('Process tests', function() { cy.loginAs(activeUser); cy.goToPath(`/processes/${containerRequest.uuid}`); // Should show main logs by default - cy.get('[data-cy=process-logs-filter]').should('contain', 'Main logs'); + cy.get('[data-cy=process-logs-filter]', {timeout: 7000}).should('contain', 'Main logs'); cy.get('[data-cy=process-logs]') .should('contain', stdoutLogs[Math.floor(Math.random() * stdoutLogs.length)]) .and('not.contain', nodeInfoLogs[Math.floor(Math.random() * nodeInfoLogs.length)]) @@ -300,14 +300,14 @@ describe('Process tests', function() { cy.getAll('@containerRequest').then(function([containerRequest]) { cy.goToPath(`/processes/${containerRequest.uuid}`); - cy.get('[data-cy=process-runtime-status-retry-warning]') + cy.get('[data-cy=process-runtime-status-retry-warning]', {timeout: 7000}) .should('contain', 'Process retried 1 time'); }); cy.getAll('@containerRequest').then(function([containerRequest]) { containerCount = 3; cy.goToPath(`/processes/${containerRequest.uuid}`); - cy.get('[data-cy=process-runtime-status-retry-warning]') + cy.get('[data-cy=process-runtime-status-retry-warning]', {timeout: 7000}) .should('contain', 'Process retried 2 times'); }); }); @@ -440,6 +440,9 @@ describe('Process tests', function() { "location": "keep:00000000000000000000000000000000+03/input3-2.txt" } ] + }, + { + "$import": "import_path" } ] } @@ -463,6 +466,9 @@ describe('Process tests', function() { "basename": "11111111111111111111111111111111+03", "class": "Directory", "location": "keep:11111111111111111111111111111111+03" + }, + { + "$import": "import_path" } ] } @@ -479,7 +485,10 @@ describe('Process tests', function() { "input_int_array": [ 1, 3, - 5 + 5, + { + "$import": "import_path" + } ] } }, @@ -494,7 +503,10 @@ describe('Process tests', function() { input: { "input_long_array": [ 10, - 20 + 20, + { + "$import": "import_path" + } ] } }, @@ -510,7 +522,10 @@ describe('Process tests', function() { "input_float_array": [ 10.2, 10.4, - 10.6 + 10.6, + { + "$import": "import_path" + } ] } }, @@ -526,7 +541,10 @@ describe('Process tests', function() { "input_double_array": [ 20.1, 20.2, - 20.3 + 20.3, + { + "$import": "import_path" + } ] } }, @@ -542,9 +560,91 @@ describe('Process tests', function() { "input_string_array": [ "Hello", "World", - "!" + "!", + { + "$import": "import_path" + } ] } + }, + { + definition: { + "id": "#main/input_bool_include", + "type": "boolean" + }, + input: { + "input_bool_include": { + "$include": "include_path" + } + } + }, + { + definition: { + "id": "#main/input_int_include", + "type": "int" + }, + input: { + "input_int_include": { + "$include": "include_path" + } + } + }, + { + definition: { + "id": "#main/input_float_include", + "type": "float" + }, + input: { + "input_float_include": { + "$include": "include_path" + } + } + }, + { + definition: { + "id": "#main/input_string_include", + "type": "string" + }, + input: { + "input_string_include": { + "$include": "include_path" + } + } + }, + { + definition: { + "id": "#main/input_file_include", + "type": "File" + }, + input: { + "input_file_include": { + "$include": "include_path" + } + } + }, + { + definition: { + "id": "#main/input_directory_include", + "type": "Directory" + }, + input: { + "input_directory_include": { + "$include": "include_path" + } + } + }, + { + definition: { + "id": "#main/input_file_url", + "type": "File" + }, + input: { + "input_file_url": { + "basename": "index.html", + "class": "File", + "location": "http://example.com/index.html" + } + } } ]; @@ -920,13 +1020,22 @@ describe('Process tests', function() { verifyIOParameter('input_file_array', null, null, 'input2.tar', '00000000000000000000000000000000+02'); verifyIOParameter('input_file_array', null, null, 'input3.tar', undefined, true); verifyIOParameter('input_file_array', null, null, 'input3-2.txt', undefined, true); + verifyIOParameter('input_file_array', null, null, 'Cannot display value', undefined, true); verifyIOParameter('input_dir_array', null, null, '/', '11111111111111111111111111111111+02'); verifyIOParameter('input_dir_array', null, null, '/', '11111111111111111111111111111111+03', true); - verifyIOParameter('input_int_array', null, null, ["1", "3", "5"]); - verifyIOParameter('input_long_array', null, null, ["10", "20"]); - verifyIOParameter('input_float_array', null, null, ["10.2", "10.4", "10.6"]); - verifyIOParameter('input_double_array', null, null, ["20.1", "20.2", "20.3"]); - verifyIOParameter('input_string_array', null, null, ["Hello", "World", "!"]); + verifyIOParameter('input_dir_array', null, null, 'Cannot display value', undefined, true); + verifyIOParameter('input_int_array', null, null, ["1", "3", "5", "Cannot display value"]); + verifyIOParameter('input_long_array', null, null, ["10", "20", "Cannot display value"]); + verifyIOParameter('input_float_array', null, null, ["10.2", "10.4", "10.6", "Cannot display value"]); + verifyIOParameter('input_double_array', null, null, ["20.1", "20.2", "20.3", "Cannot display value"]); + verifyIOParameter('input_string_array', null, null, ["Hello", "World", "!", "Cannot display value"]); + verifyIOParameter('input_bool_include', null, null, "Cannot display value"); + verifyIOParameter('input_int_include', null, null, "Cannot display value"); + verifyIOParameter('input_float_include', null, null, "Cannot display value"); + verifyIOParameter('input_string_include', null, null, "Cannot display value"); + verifyIOParameter('input_file_include', null, null, "Cannot display value"); + verifyIOParameter('input_directory_include', null, null, "Cannot display value"); + verifyIOParameter('input_file_url', null, null, "http://example.com/index.html"); }); cy.get('[data-cy=process-io-card] h6').contains('Outputs') .parents('[data-cy=process-io-card]').within((ctx) => { @@ -1035,4 +1144,217 @@ describe('Process tests', function() { }); }); + + it('allows copying processes', function() { + const crName = 'first_container_request'; + const copiedCrName = 'copied_container_request'; + createContainerRequest( + activeUser, + crName, + 'arvados/jobs', + ['echo', 'hello world'], + false, 'Committed') + .then(function(containerRequest) { + cy.loginAs(activeUser); + cy.goToPath(`/processes/${containerRequest.uuid}`); + cy.get('[data-cy=process-details]').should('contain', crName); + + cy.get('[data-cy=process-details]').find('button[title="More options"]').click(); + cy.get('ul[data-cy=context-menu]').contains("Copy and re-run process").click(); + }); + + cy.get('[data-cy=form-dialog]').within(() => { + cy.get('input[name=name]').clear().type(copiedCrName); + cy.get('[data-cy=projects-tree-home-tree-picker]').click(); + cy.get('[data-cy=form-submit-btn]').click(); + }); + + cy.get('[data-cy=process-details]').should('contain', copiedCrName); + 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-run-button]').should('exist'); + cy.get('[data-cy=process-cancel-button]').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-button]').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-button]').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-run-button]').should('exist'); + cy.get('[data-cy=process-cancel-button]').should('not.exist'); + }); + }); + });