X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/4ed794e2803ef9812dbc7ae938a8e17b3b9714c1..25ce0f6576f76f569502bc55629c2f292dbba07e:/apps/workbench/test/integration/work_units_test.rb diff --git a/apps/workbench/test/integration/work_units_test.rb b/apps/workbench/test/integration/work_units_test.rb index 63ba275e6b..ed214d62cc 100644 --- a/apps/workbench/test/integration/work_units_test.rb +++ b/apps/workbench/test/integration/work_units_test.rb @@ -1,6 +1,13 @@ +# Copyright (C) The Arvados Authors. All rights reserved. +# +# SPDX-License-Identifier: AGPL-3.0 + +require 'helpers/fake_websocket_helper' require 'integration_helper' class WorkUnitsTest < ActionDispatch::IntegrationTest + include FakeWebsocketHelper + setup do need_javascript end @@ -55,4 +62,241 @@ class WorkUnitsTest < ActionDispatch::IntegrationTest assert_no_selector "a[href=\"#{link}\"]" end end + + [ + ['jobs', 'running_job_with_components', true, true], + ['pipeline_instances', 'components_is_jobspec', true, true], + ['containers', 'running', false], + ['container_requests', 'running', true], + ].each do |type, fixture, cancelable, confirm_cancellation| + test "cancel button for #{type}/#{fixture}" do + if cancelable + need_selenium 'to cancel' + end + + obj = api_fixture(type)[fixture] + visit page_with_token "active", "/#{type}/#{obj['uuid']}" + + assert_text 'created_at' + if cancelable + assert_text 'priority: 1' if type.include?('container') + if type.include?('pipeline') + assert_selector 'a', text: 'Pause' + first('a,link', text: 'Pause').click + else + assert_selector 'button', text: 'Cancel' + first('a,button', text: 'Cancel').click + end + if confirm_cancellation + alert = page.driver.browser.switch_to.alert + alert.accept + end + wait_for_ajax + end + + if type.include?('pipeline') + assert_selector 'a', text: 'Resume' + assert_no_selector 'a', text: 'Pause' + elsif type.include?('job') + assert_text 'Cancelled' + assert_text 'Paused' # this job has a pipeline child which was also cancelled + assert_no_selector 'button', text: 'Cancel' + elsif cancelable + assert_text 'priority: 0' + end + end + end + + [ + ['jobs', 'running_job_with_components'], + ['pipeline_instances', 'has_component_with_completed_jobs'], + ['container_requests', 'running'], + ['container_requests', 'completed'], + ].each do |type, fixture| + test "edit description for #{type}/#{fixture}" do + obj = api_fixture(type)[fixture] + visit page_with_token "active", "/#{type}/#{obj['uuid']}" + + within('.arv-description-as-subtitle') do + find('.fa-pencil').click + find('.editable-input textarea').set('*Textile description for object*') + find('.editable-submit').click + end + wait_for_ajax + + # verify description + assert page.has_no_text? '*Textile description for object*' + assert page.has_text? 'Textile description for object' + end + end + + [ + ['Pipeline with default input specifications', 'part-one', 'Provide values for the following'], + ['Workflow with default input specifications', 'this workflow has inputs specified', 'Provide a value for the following'], + ].each do |template_name, preview_txt, process_txt| + test "run a process using template #{template_name} from dashboard" do + visit page_with_token('admin') + assert_text 'Recent pipelines and processes' # seeing dashboard now + + within('.recent-processes-actions') do + assert page.has_link?('All processes') + find('a', text: 'Run a process').click + end + + # in the chooser, verify preview and click Next button + within('.modal-dialog') do + find('.selectable', text: template_name).click + assert_text preview_txt + find('.btn', text: 'Next: choose inputs').click + end + + # in the process page now + assert_text process_txt + assert_selector 'a', text: template_name + + assert_equal "Set value for ex_string_def", find('div.form-group > div > p.form-control-static > a', text: "hello-testing-123")[:"data-title"] + + page.assert_selector 'a.disabled,button.disabled', text: 'Run' + end + end + + test 'display container state changes in Container Request live log' do + use_fake_websocket_driver + c = api_fixture('containers')['queued'] + cr = api_fixture('container_requests')['queued'] + visit page_with_token('active', '/container_requests/'+cr['uuid']) + click_link('Log') + + # The attrs of the "terminal window" text div in the log tab + # indicates which objects' events are worth displaying. Events + # that arrive too early (before that div exists) are not + # shown. For the user's sake, these early logs should also be + # retrieved and shown one way or another -- but in this particular + # test, we are only interested in logs that arrive by + # websocket. Therefore, to avoid races, we wait for the log tab to + # display before sending any events. + assert_text 'Recent logs' + + [[{ + event_type: 'dispatch', + properties: { + text: "dispatch logged a fake message\n", + }, + }, "dispatch logged"], + [{ + event_type: 'update', + properties: { + old_attributes: {state: 'Locked'}, + new_attributes: {state: 'Queued'}, + }, + }, "Container #{c['uuid']} was returned to the queue"], + [{ + event_type: 'update', + properties: { + old_attributes: {state: 'Queued'}, + new_attributes: {state: 'Locked'}, + }, + }, "Container #{c['uuid']} was taken from the queue by a dispatch process"], + [{ + event_type: 'crunch-run', + properties: { + text: "according to fake crunch-run,\nsome setup stuff happened on the compute node\n", + }, + }, "setup stuff happened"], + [{ + event_type: 'update', + properties: { + old_attributes: {state: 'Locked'}, + new_attributes: {state: 'Running'}, + }, + }, "Container #{c['uuid']} started"], + [{ + event_type: 'update', + properties: { + old_attributes: {state: 'Running'}, + new_attributes: {state: 'Complete', exit_code: 1}, + }, + }, "Container #{c['uuid']} finished with exit code 1 (failure)"], + # It's unrealistic for state to change again once it's Complete, + # but the logging code doesn't care, so we do it to keep the test + # simple. + [{ + event_type: 'update', + properties: { + old_attributes: {state: 'Running'}, + new_attributes: {state: 'Cancelled'}, + }, + }, "Container #{c['uuid']} was cancelled"], + ].each do |send_event, expect_log_text| + assert_no_text(expect_log_text) + fake_websocket_event(send_event.merge(object_uuid: c['uuid'])) + assert_text(expect_log_text) + end + end + + [ + ['jobs', 'active', 'running_job_with_components', 'component1', '/jobs/zzzzz-8i9sb-jyq01m7in1jlofj#Log'], + ['pipeline_instances', 'active', 'pipeline_in_running_state', 'foo', '/jobs/zzzzz-8i9sb-pshmckwoma9plh7#Log'], + ['pipeline_instances', nil, 'pipeline_in_publicly_accessible_project_but_other_objects_elsewhere', 'foo', 'Log unavailable'], + ].each do |type, token, fixture, child, log_link| + test "link_to_log for #{fixture} for #{token}" do + obj = api_fixture(type)[fixture] + if token + visit page_with_token token, "/#{type}/#{obj['uuid']}" + else + Rails.configuration.anonymous_user_token = + api_fixture("api_client_authorizations", "anonymous", "api_token") + visit "/#{type}/#{obj['uuid']}" + end + + click_link(child) + + if token + assert_selector "a[href=\"#{log_link}\"]" + else + assert_text log_link + end + end + end + + test 'Run from workflows index page' do + visit page_with_token('active', '/workflows') + + wf_count = page.all('a[data-original-title="show workflow"]').count + assert_equal true, wf_count>0 + + # Run one of the workflows + wf_name = 'Workflow with input specifications' + within('tr', text: wf_name) do + find('a,button', text: 'Run').click + end + + # Choose project for the container_request being created + within('.modal-dialog') do + find('.selectable', text: 'A Project').click + find('button', text: 'Choose').click + end + + # In newly created container_request page now + assert_text 'A Project' # CR created in "A Project" + assert_text "This container request was created from the workflow #{wf_name}" + assert_match /Provide a value for .* then click the \"Run\" button to start the workflow/, page.text + end + + test 'Run workflow from show page' do + visit page_with_token('active', '/workflows/zzzzz-7fd4e-validwithinputs') + + find('a,button', text: 'Run this workflow').click + + # Choose project for the container_request being created + within('.modal-dialog') do + find('.selectable', text: 'A Project').click + find('button', text: 'Choose').click + end + + # In newly created container_request page now + assert_text 'A Project' # CR created in "A Project" + assert_text "This container request was created from the workflow" + assert_match /Provide a value for .* then click the \"Run\" button to start the workflow/, page.text + end end