[ARVADOS] created: 2d411bb86d5c73072ced3606a5393a6f3618fd76

Git user git at public.curoverse.com
Mon Sep 5 20:46:43 EDT 2016


        at  2d411bb86d5c73072ced3606a5393a6f3618fd76 (commit)


commit 2d411bb86d5c73072ced3606a5393a6f3618fd76
Author: Tom Clegg <tom at curoverse.com>
Date:   Mon Sep 5 20:46:36 2016 -0400

    9679: Mention container state changes in container [request] log messages.

diff --git a/apps/workbench/app/assets/javascripts/work_unit_log.js b/apps/workbench/app/assets/javascripts/work_unit_log.js
index 0760692..400c88b 100644
--- a/apps/workbench/app/assets/javascripts/work_unit_log.js
+++ b/apps/workbench/app/assets/javascripts/work_unit_log.js
@@ -1,18 +1,62 @@
 $(document).on('arv-log-event', '.arv-log-event-handler-append-logs', function(event, eventData){
+    var wasatbottom, txt;
     if (this != event.target) {
         // Not interested in events sent to child nodes.
         return;
     }
-    var wasatbottom = ($(this).scrollTop() + $(this).height() >= this.scrollHeight);
 
-    if (eventData.properties != null && eventData.properties.text != null) {
-        if( eventData.prepend ) {
-            $(this).prepend(eventData.properties.text);
-        } else {
-            $(this).append(eventData.properties.text);
+    if (!('properties' in eventData)) {
+        return;
+    }
+
+    txt = '';
+    if ('text' in eventData.properties) {
+        txt += eventData.properties.text;
+    }
+    if (eventData.event_type == 'update' &&
+        eventData.object_uuid.indexOf("-dz642-") == 5 &&
+        'old_attributes' in eventData.properties &&
+        'new_attributes' in eventData.properties) {
+        // Container update
+        if (eventData.properties.old_attributes.state != eventData.properties.new_attributes.state) {
+            switch(eventData.properties.new_attributes.state) {
+            case "Queued":
+                txt += "Container "+eventData.object_uuid+" was returned to the queue\n";
+                break;
+            case "Locked":
+                txt += "Container "+eventData.object_uuid+" was taken from the queue by a dispatch process\n";
+                break;
+            case "Running":
+                txt += "Container "+eventData.object_uuid+" started\n";
+                break;
+            case "Complete":
+                var outcome = eventData.properties.new_attributes.exit_code === 0 ? "success" : "failure";
+                txt += "Container "+eventData.object_uuid+" finished with exit code " +
+                    eventData.properties.new_attributes.exit_code +
+                    "("+outcome+")\n";
+                break;
+            case "Cancelled":
+                txt += "Container "+eventData.object_uuid+" was cancelled\n";
+                break;
+            default:
+                // Unknown state -- unexpected, might as well log it.
+                txt += "Container "+eventData.object_uuid+" changed state to " +
+                    eventData.properties.new_attributes.state + "\n";
+                break;
+            }
         }
     }
 
+    if (txt == '') {
+        return;
+    }
+
+    wasatbottom = ($(this).scrollTop() + $(this).height() >= this.scrollHeight);
+    if (eventData.prepend) {
+        $(this).prepend(txt);
+    } else {
+        $(this).append(txt);
+    }
     if (wasatbottom) {
         this.scrollTop = this.scrollHeight;
     }
diff --git a/apps/workbench/app/models/container_work_unit.rb b/apps/workbench/app/models/container_work_unit.rb
index 2580105..be526ca 100644
--- a/apps/workbench/app/models/container_work_unit.rb
+++ b/apps/workbench/app/models/container_work_unit.rb
@@ -131,7 +131,7 @@ class ContainerWorkUnit < ProxyWorkUnit
   end
 
   def log_object_uuids
-    [get_combined(:uuid), get(:uuid)].uniq
+    [get(:uuid, @container), get(:uuid, @proxied)].compact
   end
 
   def render_log
diff --git a/apps/workbench/test/helpers/fake_websocket_helper.rb b/apps/workbench/test/helpers/fake_websocket_helper.rb
new file mode 100644
index 0000000..5dab940
--- /dev/null
+++ b/apps/workbench/test/helpers/fake_websocket_helper.rb
@@ -0,0 +1,17 @@
+module FakeWebsocketHelper
+  def use_fake_websocket_driver
+    Capybara.current_driver = :poltergeist_with_fake_websocket
+  end
+
+  def fake_websocket_event(logdata)
+    defaults = {
+      owner_uuid: api_fixture('users')['system_user']['uuid'],
+      event_at: Time.now,
+      created_at: Time.now,
+      updated_at: Time.now,
+    }
+    event = {data: Oj.dump(defaults.merge(logdata), mode: :compat)}
+    script = '$(window).data("arv-websocket").onmessage('+Oj.dump(event, mode: :compat)+');'
+    page.evaluate_script(script)
+  end
+end
diff --git a/apps/workbench/test/integration/work_units_test.rb b/apps/workbench/test/integration/work_units_test.rb
index 7d19fcc..87a2b48 100644
--- a/apps/workbench/test/integration/work_units_test.rb
+++ b/apps/workbench/test/integration/work_units_test.rb
@@ -1,6 +1,9 @@
+require 'helpers/fake_websocket_helper'
 require 'integration_helper'
 
 class WorkUnitsTest < ActionDispatch::IntegrationTest
+  include FakeWebsocketHelper
+
   setup do
     need_javascript
   end
@@ -128,4 +131,68 @@ class WorkUnitsTest < ActionDispatch::IntegrationTest
       assert_selector 'a', text: template_name
     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: '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
 end
diff --git a/apps/workbench/test/integration_helper.rb b/apps/workbench/test/integration_helper.rb
index c94fc61..f0c811a 100644
--- a/apps/workbench/test/integration_helper.rb
+++ b/apps/workbench/test/integration_helper.rb
@@ -44,6 +44,11 @@ Capybara.register_driver :poltergeist_debug do |app|
   Capybara::Poltergeist::Driver.new app, poltergeist_opts.merge(inspector: true)
 end
 
+Capybara.register_driver :poltergeist_with_fake_websocket do |app|
+  js = File.expand_path '../support/fake_websocket.js', __FILE__
+  Capybara::Poltergeist::Driver.new app, poltergeist_opts.merge(extensions: [js])
+end
+
 Capybara.register_driver :poltergeist_without_file_api do |app|
   js = File.expand_path '../support/remove_file_api.js', __FILE__
   Capybara::Poltergeist::Driver.new app, poltergeist_opts.merge(extensions: [js])
diff --git a/apps/workbench/test/support/fake_websocket.js b/apps/workbench/test/support/fake_websocket.js
new file mode 100644
index 0000000..b10f10f
--- /dev/null
+++ b/apps/workbench/test/support/fake_websocket.js
@@ -0,0 +1,15 @@
+sockets = [];
+window.WebSocket = function(url) {
+    sockets.push(this);
+    window.setTimeout(function() {
+        sockets.map(function(s) {
+            s.onopen();
+        });
+        sockets.splice(0);
+    }, 1);
+}
+
+window.WebSocket.prototype.send = function(msg) {
+    // Uncomment for debugging:
+    // console.log("fake WebSocket: send: "+msg);
+}
diff --git a/apps/workbench/test/test_helper.rb b/apps/workbench/test/test_helper.rb
index b8aa82e..72b5a89 100644
--- a/apps/workbench/test/test_helper.rb
+++ b/apps/workbench/test/test_helper.rb
@@ -83,7 +83,7 @@ module ApiFixtureLoader
         file = file[0, trim_index] if trim_index
         YAML.load(file)
       end
-      keys.inject(@@api_fixtures[name]) { |hash, key| hash[key] }
+      keys.inject(@@api_fixtures[name]) { |hash, key| hash[key].deep_dup }
     end
   end
   def api_fixture(name, *keys)

commit bf6dfd5785f6767d2700dadfebb8591a8595d5f3
Author: Tom Clegg <tom at curoverse.com>
Date:   Mon Sep 5 16:23:48 2016 -0400

    9679: Extricate container/job log code from pipeline-specific code.

diff --git a/apps/workbench/app/assets/javascripts/pipeline_instances.js b/apps/workbench/app/assets/javascripts/pipeline_instances.js
index 1617a92..ec43747 100644
--- a/apps/workbench/app/assets/javascripts/pipeline_instances.js
+++ b/apps/workbench/app/assets/javascripts/pipeline_instances.js
@@ -101,26 +101,6 @@ $(document).on('ready ajax:success', function() {
     });
 });
 
-$(document).on('arv-log-event', '.arv-log-event-handler-append-logs', function(event, eventData){
-    if (this != event.target) {
-        // Not interested in events sent to child nodes.
-        return;
-    }
-    var wasatbottom = ($(this).scrollTop() + $(this).height() >= this.scrollHeight);
-
-    if (eventData.properties != null && eventData.properties.text != null) {
-        if( eventData.prepend ) {
-            $(this).prepend(eventData.properties.text);
-        } else {
-            $(this).append(eventData.properties.text);
-        }
-    }
-
-    if (wasatbottom) {
-        this.scrollTop = this.scrollHeight;
-    }
-});
-
 // Set up all events for the pipeline instances compare button.
 (function() {
     var compare_form = '#compare';
diff --git a/apps/workbench/app/assets/javascripts/work_unit_log.js b/apps/workbench/app/assets/javascripts/work_unit_log.js
new file mode 100644
index 0000000..0760692
--- /dev/null
+++ b/apps/workbench/app/assets/javascripts/work_unit_log.js
@@ -0,0 +1,19 @@
+$(document).on('arv-log-event', '.arv-log-event-handler-append-logs', function(event, eventData){
+    if (this != event.target) {
+        // Not interested in events sent to child nodes.
+        return;
+    }
+    var wasatbottom = ($(this).scrollTop() + $(this).height() >= this.scrollHeight);
+
+    if (eventData.properties != null && eventData.properties.text != null) {
+        if( eventData.prepend ) {
+            $(this).prepend(eventData.properties.text);
+        } else {
+            $(this).append(eventData.properties.text);
+        }
+    }
+
+    if (wasatbottom) {
+        this.scrollTop = this.scrollHeight;
+    }
+});

-----------------------------------------------------------------------


hooks/post-receive
-- 




More information about the arvados-commits mailing list