Merge branch 'master' into 3889-functional-testing
authorradhika <radhika@curoverse.com>
Sat, 27 Sep 2014 01:50:16 +0000 (21:50 -0400)
committerradhika <radhika@curoverse.com>
Sat, 27 Sep 2014 01:50:16 +0000 (21:50 -0400)
apps/workbench/app/helpers/pipeline_components_helper.rb
apps/workbench/app/helpers/pipeline_instances_helper.rb
apps/workbench/app/views/pipeline_instances/_running_component.html.erb
apps/workbench/app/views/pipeline_instances/_show_components_json.html.erb
apps/workbench/test/functional/pipeline_instances_controller_test.rb
services/api/test/fixtures/pipeline_instances.yml
services/fuse/arvados_fuse/__init__.py
services/fuse/bin/arv-mount

index 28adfa9f99b2152cac5a8c1a98bbb1b544a74c9e..9fead2c8f0ed0a5c167984ab50cd260b1b0d665b 100644 (file)
@@ -8,7 +8,8 @@ module PipelineComponentsHelper
       logger.error "#{e.backtrace.join("\n\t")}"
       case fallback
       when :json
-        render(partial: "pipeline_instances/show_components_json")
+        render(partial: "pipeline_instances/show_components_json",
+               locals: {error_name: e.inspect, backtrace: e.backtrace.join("\n\t")})
       end
     end
   end
index ae8384eeeab84cb74d2e590f2300629ed1ccc6c9..06d61e033f12caeb36fc4ed01596c1952e439fbb 100644 (file)
@@ -102,9 +102,14 @@ module PipelineInstancesHelper
       end
       if c[:job] and c[:job][:uuid] and job[c[:job][:uuid]]
         pj[:job] = job[c[:job][:uuid]]
-      else
-        pj[:job] = c[:job].is_a?(Hash) ? c[:job] : {}
-
+      elsif c[:job].is_a?(Hash)
+        pj[:job] = c[:job]
+        if pj[:job][:started_at].is_a? String
+          pj[:job][:started_at] = Time.parse(pj[:job][:started_at])
+        end
+        if pj[:job][:finished_at].is_a? String
+          pj[:job][:finished_at] = Time.parse(pj[:job][:finished_at])
+        end
         # If necessary, figure out the state based on the other fields.
         pj[:job][:state] ||= if pj[:job][:cancelled_at]
                                "Cancelled"
@@ -117,6 +122,8 @@ module PipelineInstancesHelper
                              else
                                "Queued"
                              end
+      else
+        pj[:job] = {}
       end
       pj[:percent_done] = 0
       pj[:percent_running] = 0
@@ -179,7 +186,7 @@ module PipelineInstancesHelper
       pj[:nondeterministic] = pj[:job][:nondeterministic] || c[:nondeterministic]
       pj[:output] = pj[:job][:output]
       pj[:output_uuid] = c[:output_uuid]
-      pj[:finished_at] = (Time.parse(pj[:job][:finished_at]) rescue nil)
+      pj[:finished_at] = pj[:job][:finished_at]
       ret << pj
     end
     ret
index 8613d54a100515bd2f1093757a8f62d366c33e80..038efece35e06fb00dc5431d95e58a287c78e72d 100644 (file)
@@ -18,9 +18,9 @@
 
             <div class="col-md-3">
               <% if current_job[:started_at] %>
-                <% walltime = ((if current_job.finished_at then current_job.finished_at else Time.now() end) - current_job.started_at) %>
+                <% walltime = ((if current_job[:finished_at] then current_job[:finished_at] else Time.now() end) - current_job[:started_at]) %>
                 <% cputime = tasks.map { |task|
-                     if task.started_at and task.job_uuid == current_job.uuid
+                     if task.started_at and task.job_uuid == current_job[:uuid]
                        (if task.finished_at then task.finished_at else Time.now() end) - task.started_at
                      else
                        0
@@ -35,7 +35,7 @@
               <div class="col-md-5 text-overflow-ellipsis">
                 <% if pj[:output_uuid] %>
                   <%= link_to_if_arvados_object pj[:output_uuid], friendly_name: true %>
-                <% elsif current_job.andand[:output] %>
+                <% elsif current_job[:output] %>
                   <%= link_to_if_arvados_object current_job[:output], link_text: "Output of #{pj[:name]}" %>
                 <% else %>
                   No output.
@@ -46,7 +46,7 @@
                 <%= pj[:progress_bar] %>
               </div>
               <div class="col-md-1 pipeline-instance-spacing">
-                <%= form_tag "/jobs/#{current_job.uuid}/cancel", style: "display:inline; padding-left: 1em" do |f| %>
+                <%= form_tag "/jobs/#{current_job[:uuid]}/cancel", style: "display:inline; padding-left: 1em" do |f| %>
                 <%= hidden_field_tag :return_to, url_for(@object) %>
                 <%= button_tag "Cancel", {class: 'btn btn-xs btn-danger', id: "cancel-job-button"} %>
             </div>
               <% queuetime = Time.now - current_job[:created_at] %>
               Queued for <%= render_runtime(queuetime, true) %>.
               <% begin %>
-              <% if current_job.queue_position == 0 %>
+              <% if current_job[:queue_position] == 0 %>
                 This job is next in the queue to run.
-              <% elsif current_job.queue_position == 1 %>
+              <% elsif current_job[:queue_position] == 1 %>
                 There is 1 job in the queue ahead of this one.
               <% else  %>
-                There are <%= current_job.queue_position %> jobs in the queue ahead of this one.
+                There are <%= current_job[:queue_position] %> jobs in the queue ahead of this one.
               <% end %>
               <% rescue %>
           <% end %>
index 3cdd5aedb38c3f154122d9636d54e91534689b03..9d1edbf264ff34a7d0c139aa2d7df8c3f3a9486e 100644 (file)
@@ -1,5 +1,7 @@
 <p>The components of this pipeline are in a format that Workbench does not recognize.</p>
 
+<p>Error encountered: <b><%= error_name %></b></p>
+
     <div id="components-accordion" class="panel panel-default">
       <div class="panel-heading">
         <h4 class="panel-title">
           <pre><%= Oj.dump(@object.components, indent: 2) %></pre>
         </div>
       </div>
+      <div class="panel-heading">
+        <h4 class="panel-title">
+          <a data-toggle="collapse" data-parent="#components-accordion" href="#components-backtrace">
+            Show backtrace
+          </a>
+        </h4>
+      </div>
+      <div id="components-backtrace" class="panel-collapse collapse">
+        <div class="panel-body">
+          <pre><%= backtrace %></pre>
+        </div>
+      </div>
     </div>
index 6fe44242bb89f3f0c96b656e7d4799a6f614f894..20886b5ab6d834fd01e03226ef69e751374b506f 100644 (file)
@@ -75,4 +75,15 @@ class PipelineInstancesControllerTest < ActionController::TestCase
         session_for(:active))
     assert_response :success
   end
+
+  test "dates in JSON components are parsed" do
+    get(:show,
+        {id: api_fixture('pipeline_instances')['has_component_with_completed_jobs']['uuid']},
+        session_for(:active))
+    assert_response :success
+    assert_not_nil assigns(:object)
+    assert_not_nil assigns(:object).components[:foo][:job]
+    assert assigns(:object).components[:foo][:job][:started_at].is_a? Time
+    assert assigns(:object).components[:foo][:job][:finished_at].is_a? Time
+  end
 end
index ccbc90bf27c0cc967fd4addf376d3ade6222744f..d405c5fa01fd729fa751789722eeb54e9c671bde 100644 (file)
@@ -25,6 +25,26 @@ has_component_with_empty_script_parameters:
     script: foo
     script_version: master
 
+has_component_with_completed_jobs:
+  # Test that the job "started_at" and "finished_at" fields are
+  # parsed into Time fields when rendering. This job must *not*
+  # have its own fixture; the point is to force the
+  # pipeline_instances_controller_test in Workbench to parse
+  # the "components" field.
+  state: Complete
+  uuid: zzzzz-d1hrv-i3e77t9z5y8j9cc
+  owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz
+  components:
+   foo:
+    script: foo
+    script_version: master
+    script_parameters: {}
+    job:
+      uuid: zzzzz-8i9sb-rft1xdewxkwgxnz
+      script_version: master
+      started_at: <%= 10.minute.ago.to_s(:db) %>
+      finished_at: <%= 9.minute.ago.to_s(:db) %>
+
 has_job:
   name: pipeline_with_job
   state: Ready
index e40b88ce9e24db679a4e1b9bb685aaafbd5d11d2..c261bc31972079b1119f300b506945e893e0e4aa 100644 (file)
@@ -728,12 +728,13 @@ class Operations(llfuse.Operations):
     so request handlers do not run concurrently unless the lock is explicitly released
     using "with llfuse.lock_released:"'''
 
-    def __init__(self, uid, gid):
+    def __init__(self, uid, gid, encoding="utf-8"):
         super(Operations, self).__init__()
 
         self.inodes = Inodes()
         self.uid = uid
         self.gid = gid
+        self.encoding = encoding
 
         # dict of inode to filehandle
         self._filehandles = {}
@@ -785,6 +786,7 @@ class Operations(llfuse.Operations):
         return entry
 
     def lookup(self, parent_inode, name):
+        name = unicode(name, self.encoding)
         _logger.debug("arv-mount lookup: parent_inode %i name %s",
                       parent_inode, name)
         inode = None
@@ -882,7 +884,10 @@ class Operations(llfuse.Operations):
         e = off
         while e < len(handle.entry):
             if handle.entry[e][1].inode in self.inodes:
-                yield (handle.entry[e][0], self.getattr(handle.entry[e][1].inode), e+1)
+                try:
+                    yield (handle.entry[e][0].encode(self.encoding), self.getattr(handle.entry[e][1].inode), e+1)
+                except UnicodeEncodeError:
+                    pass
             e += 1
 
     def releasedir(self, fh):
index e92b1b48325b4746e89dc50f8e2e39274c203ff1..5b161fd2be57345dc52b1b120dc5079ecca3f28e 100755 (executable)
@@ -43,6 +43,7 @@ with "--".
     parser.add_argument('--debug', action='store_true', help="""Debug mode""")
     parser.add_argument('--logfile', help="""Write debug logs and errors to the specified file (default stderr).""")
     parser.add_argument('--foreground', action='store_true', help="""Run in foreground (default is to daemonize unless --exec specified)""", default=False)
+    parser.add_argument('--encoding', type=str, help="Character encoding to use for filesystem, default is utf-8 (see Python codec registry for list of available encodings)", default="utf-8")
     parser.add_argument('--exec', type=str, nargs=argparse.REMAINDER,
                         dest="exec_args", metavar=('command', 'args', '...', '--'),
                         help="""Mount, run a command, then unmount and exit""")
@@ -79,7 +80,7 @@ with "--".
 
     try:
         # Create the request handler
-        operations = Operations(os.getuid(), os.getgid())
+        operations = Operations(os.getuid(), os.getgid(), args.encoding)
         api = SafeApi(arvados.config)
 
         usr = api.users().current().execute(num_retries=args.retries)