X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/f075cec933827186d93d5d16ab5ab6803b31d40d..4d95f6cc422bc4dea97da79bbfbb2e7809ee20fc:/apps/workbench/test/integration/websockets_test.rb diff --git a/apps/workbench/test/integration/websockets_test.rb b/apps/workbench/test/integration/websockets_test.rb index 65784af523..655ad92c94 100644 --- a/apps/workbench/test/integration/websockets_test.rb +++ b/apps/workbench/test/integration/websockets_test.rb @@ -1,13 +1,8 @@ require 'integration_helper' -require 'selenium-webdriver' -require 'headless' class WebsocketTest < ActionDispatch::IntegrationTest - setup do - headless = Headless.new - headless.start - Capybara.current_driver = :selenium + need_selenium "to make websockets work" end test "test page" do @@ -30,55 +25,61 @@ class WebsocketTest < ActionDispatch::IntegrationTest event_type: "stderr", properties: {"text" => "123 hello"}}}) assert_text '123 hello' - Thread.current[:arvados_api_token] = nil end - test "test live logging scrolling" do - visit(page_with_token("admin", "/pipeline_instances/zzzzz-d1hrv-9fm8l10i9z2kqc6")) - click_link("Log") - assert_no_text '123 hello' - api = ArvadosApiClient.new + [["pipeline_instances", api_fixture("pipeline_instances")['pipeline_with_newer_template']['uuid']], + ["jobs", api_fixture("jobs")['running']['uuid']]].each do |c| + test "test live logging scrolling #{c[0]}" do - text = "" - (1..1000).each do |i| - text << "#{i} hello\n" - end + controller = c[0] + uuid = c[1] - Thread.current[:arvados_api_token] = @@API_AUTHS["admin"]['api_token'] - api.api("logs", "", {log: { - object_uuid: "zzzzz-d1hrv-9fm8l10i9z2kqc6", - event_type: "stderr", - properties: {"text" => text}}}) - assert_text '1000 hello' + visit(page_with_token("admin", "/#{controller}/#{uuid}")) + click_link("Log") + assert_no_text '123 hello' - # First test that when we're already at the bottom of the page, it scrolls down - # when a new line is added. - old_top = page.evaluate_script("$('#pipeline_event_log_div').scrollTop()") + api = ArvadosApiClient.new - api.api("logs", "", {log: { - object_uuid: "zzzzz-d1hrv-9fm8l10i9z2kqc6", - event_type: "stderr", - properties: {"text" => "1001 hello\n"}}}) - assert_text '1001 hello' + text = "" + (1..1000).each do |i| + text << "#{i} hello\n" + end - # Check that new value of scrollTop is greater than the old one - assert page.evaluate_script("$('#pipeline_event_log_div').scrollTop()") > old_top + Thread.current[:arvados_api_token] = @@API_AUTHS["admin"]['api_token'] + api.api("logs", "", {log: { + object_uuid: uuid, + event_type: "stderr", + properties: {"text" => text}}}) + assert_text '1000 hello' - # Now scroll to 30 pixels from the top - page.execute_script "$('#pipeline_event_log_div').scrollTop(30)" - assert_equal 30, page.evaluate_script("$('#pipeline_event_log_div').scrollTop()") + # First test that when we're already at the bottom of the page, it scrolls down + # when a new line is added. + old_top = page.evaluate_script("$('#event_log_div').scrollTop()") - api.api("logs", "", {log: { - object_uuid: "zzzzz-d1hrv-9fm8l10i9z2kqc6", - event_type: "stderr", - properties: {"text" => "1002 hello\n"}}}) - assert_text '1002 hello' + api.api("logs", "", {log: { + object_uuid: uuid, + event_type: "stderr", + properties: {"text" => "1001 hello\n"}}}) + assert_text '1001 hello' + + # Check that new value of scrollTop is greater than the old one + new_top = page.evaluate_script("$('#event_log_div').scrollTop()") + assert_operator new_top, :>, old_top - # Check that we haven't changed scroll position - assert_equal 30, page.evaluate_script("$('#pipeline_event_log_div').scrollTop()") + # Now scroll to 30 pixels from the top + page.execute_script "$('#event_log_div').scrollTop(30)" + assert_equal 30, page.evaluate_script("$('#event_log_div').scrollTop()") - Thread.current[:arvados_api_token] = nil + api.api("logs", "", {log: { + object_uuid: uuid, + event_type: "stderr", + properties: {"text" => "1002 hello\n"}}}) + assert_text '1002 hello' + + # Check that we haven't changed scroll position + assert_equal 30, page.evaluate_script("$('#event_log_div').scrollTop()") + end end test "pipeline instance arv-refresh-on-log-event" do @@ -107,8 +108,6 @@ class WebsocketTest < ActionDispatch::IntegrationTest assert page.has_no_link? 'Pause' assert_text 'Complete' assert page.has_link? 'Re-run with latest' - - Thread.current[:arvados_api_token] = nil end test "job arv-refresh-on-log-event" do @@ -119,15 +118,13 @@ class WebsocketTest < ActionDispatch::IntegrationTest visit(page_with_token("admin", "/jobs/#{p.uuid}")) assert_no_text 'complete' - assert_no_text 'Re-run same version' + assert_no_text 'Re-run job' p.state = "Complete" p.save! assert_text 'complete' - assert_text 'Re-run same version' - - Thread.current[:arvados_api_token] = nil + assert_text 'Re-run job' end test "dashboard arv-refresh-on-log-event" do @@ -145,8 +142,137 @@ class WebsocketTest < ActionDispatch::IntegrationTest }) assert_text 'test dashboard arv-refresh-on-log-event' + end + + test 'job graph appears when first data point is already in logs table' do + job_graph_first_datapoint_test + end + + test 'job graph appears when first data point arrives by websocket' do + use_token :admin do + Log.find(api_fixture('logs')['crunchstat_for_running_job']['uuid']).destroy + end + job_graph_first_datapoint_test expect_existing_datapoints: false + end + + def job_graph_first_datapoint_test expect_existing_datapoints: true + uuid = api_fixture('jobs')['running']['uuid'] + + visit page_with_token "active", "/jobs/#{uuid}" + click_link "Log" + + assert_selector '#event_log_div', visible: true + + if expect_existing_datapoints + assert_selector '#log_graph_div', visible: true + # Magic numbers 12.99 etc come from the job log fixture: + assert_last_datapoint 'T1-cpu', (((12.99+0.99)/10.0002)/8) + else + # Until graphable data arrives, we should see the text log but not the graph. + assert_no_selector '#log_graph_div', visible: true + end + + text = "2014-11-07_23:33:51 #{uuid} 31708 1 stderr crunchstat: cpu 1970.8200 user 60.2700 sys 8 cpus -- interval 10.0002 seconds 35.3900 user 0.8600 sys" + + assert_triggers_dom_event 'arv-log-event' do + use_token :active do + api = ArvadosApiClient.new + api.api("logs", "", {log: { + object_uuid: uuid, + event_type: "stderr", + properties: {"text" => text}}}) + end + end + + # Graph should have appeared (even if it hadn't above). It's + # important not to wait like matchers usually do: we are + # confirming the graph is visible _immediately_ after the first + # data point arrives. + using_wait_time 0 do + assert_selector '#log_graph_div', visible: true + end + assert_last_datapoint 'T1-cpu', (((35.39+0.86)/10.0002)/8) + end + + test "live log charting from replayed log" do + uuid = api_fixture("jobs")['running']['uuid'] + + visit page_with_token "active", "/jobs/#{uuid}" + click_link "Log" + + assert_triggers_dom_event 'arv-log-event' do + ApiServerForTests.new.run_rake_task("replay_job_log", "test/job_logs/crunchstatshort.log,1.0,#{uuid}") + end - Thread.current[:arvados_api_token] = nil + assert_last_datapoint 'T1-cpu', (((35.39+0.86)/10.0002)/8) end + def assert_last_datapoint series, value + datum = page.evaluate_script("jobGraphData[jobGraphData.length-1]['#{series}']") + assert_in_epsilon value, datum.to_f + end + + test "test running job with just a few previous log records" do + Thread.current[:arvados_api_token] = @@API_AUTHS["admin"]['api_token'] + job = Job.where(uuid: api_fixture("jobs")['running']['uuid']).results.first + visit page_with_token("admin", "/jobs/#{job.uuid}") + + api = ArvadosApiClient.new + + # Create just one old log record + api.api("logs", "", {log: { + object_uuid: job.uuid, + event_type: "stderr", + properties: {"text" => "Historic log message"}}}) + + click_link("Log") + + # Expect "all" historic log records because we have less than + # default Rails.configuration.running_job_log_records_to_fetch count + assert_text 'Historic log message' + + # Create new log record and expect it to show up in log tab + api.api("logs", "", {log: { + object_uuid: job.uuid, + event_type: "stderr", + properties: {"text" => "Log message after subscription"}}}) + assert_text 'Log message after subscription' + end + + test "test running job with too many previous log records" do + Rails.configuration.running_job_log_records_to_fetch = 5 + + Thread.current[:arvados_api_token] = @@API_AUTHS["admin"]['api_token'] + job = Job.where(uuid: api_fixture("jobs")['running']['uuid']).results.first + + visit page_with_token("admin", "/jobs/#{job.uuid}") + + api = ArvadosApiClient.new + + # Create Rails.configuration.running_job_log_records_to_fetch + 1 log records + (0..Rails.configuration.running_job_log_records_to_fetch).each do |count| + api.api("logs", "", {log: { + object_uuid: job.uuid, + event_type: "stderr", + properties: {"text" => "Old log message #{count}"}}}) + end + + # Go to log tab, which results in subscribing to websockets + click_link("Log") + + # Expect all but the first historic log records, + # because that was one too many than fetch count. + (1..Rails.configuration.running_job_log_records_to_fetch).each do |count| + assert_text "Old log message #{count}" + end + assert_no_text 'Old log message 0' + + # Create one more log record after subscription + api.api("logs", "", {log: { + object_uuid: job.uuid, + event_type: "stderr", + properties: {"text" => "Life goes on!"}}}) + # Expect it to show up in log tab + assert_text 'Life goes on!' + end end