9498: show top-level container requests in project#Pipelines_and_processes tab.
authorradhika <radhika@curoverse.com>
Tue, 28 Jun 2016 19:58:27 +0000 (15:58 -0400)
committerradhika <radhika@curoverse.com>
Mon, 4 Jul 2016 21:21:40 +0000 (17:21 -0400)
19 files changed:
apps/workbench/app/assets/javascripts/infinite_scroll.js
apps/workbench/app/controllers/application_controller.rb
apps/workbench/app/controllers/container_requests_controller.rb
apps/workbench/app/controllers/containers_controller.rb
apps/workbench/app/controllers/projects_controller.rb
apps/workbench/app/models/container_request.rb
apps/workbench/app/views/projects/_show_jobs_and_pipelines.html.erb [deleted file]
apps/workbench/app/views/projects/_show_pipelines_and_processes.html.erb [new file with mode: 0644]
apps/workbench/test/controllers/projects_controller_test.rb
apps/workbench/test/integration/anonymous_access_test.rb
apps/workbench/test/integration/pipeline_instances_test.rb
apps/workbench/test/integration/projects_test.rb
doc/api/methods/groups.html.textile.liquid
services/api/app/controllers/arvados/v1/groups_controller.rb
services/api/test/fixtures/container_requests.yml
services/api/test/fixtures/groups.yml
services/api/test/fixtures/jobs.yml
services/api/test/fixtures/pipeline_instances.yml
services/api/test/functional/arvados/v1/groups_controller_test.rb

index 047858c5a0e3a9811408de40442f24605994868d..a0c9efc5231e5b2d27a66e6af6e1489770b12009 100644 (file)
@@ -151,7 +151,8 @@ function mergeInfiniteContentParams($container) {
     // For example, filterable.js writes filters in
     // infiniteContentParamsFilterable ("search for text foo")
     // without worrying about clobbering the filters set up by the
-    // tab pane ("only show jobs and pipelines in this tab").
+    // tab pane ("only show container requests and pipeline instances
+    // in this tab").
     $.each($container.data(), function(datakey, datavalue) {
         // Note: We attach these data to DOM elements using
         // <element data-foo-bar="baz">. We store/retrieve them
index 0ed629403c41fb3b10ca545af37200515f711fee..648cae85a67006dc46e2410f3b7e3afc99637f8e 100644 (file)
@@ -115,7 +115,7 @@ class ApplicationController < ActionController::Base
   # Column names should always be qualified by a table name and a direction is optional, defaulting to asc
   # (e.g. "collections.name" or "collections.name desc").
   # If a column name is specified, that table will be sorted by that column.
-  # If there are objects from different models that will be shown (such as in Jobs and Pipelines tab),
+  # If there are objects from different models that will be shown (such as in Pipelines and processes tab),
   # then a sort column name can optionally be specified for each model, passed as an comma-separated list (e.g. "jobs.script, pipeline_instances.name")
   # Currently only one sort column name and direction can be specified for each model.
   def load_filters_and_paging_params
index 4a32cd8171c53ffa64d17a1e4640abb7ca837bf6..f5a68fec27eb00f64e1d027d29c3a4079dd0687b 100644 (file)
@@ -1,4 +1,9 @@
 class ContainerRequestsController < ApplicationController
+  skip_around_filter :require_thread_api_token, if: proc { |ctrl|
+    Rails.configuration.anonymous_user_token and
+    'show' == ctrl.action_name
+  }
+
   def show_pane_list
     %w(Status Log Advanced)
   end
index 86582dff4fe85ce5073f9f3a8e8851680028b9f0..1df2c3acb0f5bcba19562c57b8f794c641375c88 100644 (file)
@@ -1,4 +1,9 @@
 class ContainersController < ApplicationController
+  skip_around_filter :require_thread_api_token, if: proc { |ctrl|
+    Rails.configuration.anonymous_user_token and
+    'show' == ctrl.action_name
+  }
+
   def show_pane_list
     %w(Status Log Advanced)
   end
index e49ed1fab65f38b6631c0298f8ba508feacd9087..3674e314a835742dc8071770fe771e41dcef7352 100644 (file)
@@ -63,8 +63,8 @@ class ProjectsController < ApplicationController
       }
     pane_list <<
       {
-        :name => 'Jobs_and_pipelines',
-        :filters => [%w(uuid is_a) + [%w(arvados#job arvados#pipelineInstance)]]
+        :name => 'Pipelines_and_processes',
+        :filters => [%w(uuid is_a) + [%w(arvados#containerRequest arvados#pipelineInstance)]]
       }
     pane_list <<
       {
@@ -213,9 +213,13 @@ class ProjectsController < ApplicationController
       @name_link_for = {}
       kind_filters.each do |attr,op,val|
         (val.is_a?(Array) ? val : [val]).each do |type|
+          filters = @filters - kind_filters + [['uuid', 'is_a', type]]
+          if type == 'arvados#containerRequest'
+            filters = filters + [['container_requests.requesting_container_uuid', '=', nil]]
+          end
           objects = @object.contents(order: @order,
                                      limit: @limit,
-                                     filters: (@filters - kind_filters + [['uuid', 'is_a', type]]),
+                                     filters: filters,
                                     )
           objects.each do |object|
             @name_link_for[object.andand.uuid] = objects.links_for(object, 'name').first
index 62d8bff042c16dec335f746ff6f0991e5e37250e..0148de51f7459a678d49547fe4f24a10e6bc27e9 100644 (file)
@@ -7,6 +7,10 @@ class ContainerRequest < ArvadosBase
     [ 'description' ]
   end
 
+  def self.goes_in_projects?
+    true
+  end
+
   def work_unit(label=nil)
     ContainerWorkUnit.new(self, label)
   end
diff --git a/apps/workbench/app/views/projects/_show_jobs_and_pipelines.html.erb b/apps/workbench/app/views/projects/_show_jobs_and_pipelines.html.erb
deleted file mode 100644 (file)
index 3637ef4..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-<%= render_pane 'tab_contents', to_string: true, locals: {
-        limit: 50,
-           filters: [['uuid', 'is_a', ["arvados#job", "arvados#pipelineInstance"]]],
-           sortable_columns: { 'name' => 'jobs.script, pipeline_instances.name', 'description' => 'jobs.description, pipeline_instances.description' }
-    }.merge(local_assigns) %>
diff --git a/apps/workbench/app/views/projects/_show_pipelines_and_processes.html.erb b/apps/workbench/app/views/projects/_show_pipelines_and_processes.html.erb
new file mode 100644 (file)
index 0000000..1ee3070
--- /dev/null
@@ -0,0 +1,5 @@
+<%= render_pane 'tab_contents', to_string: true, locals: {
+      limit: 50,
+      filters: [['uuid', 'is_a', ["arvados#containerRequest", "arvados#pipelineInstance"]]],
+      sortable_columns: { 'name' => 'container_requests.name, pipeline_instances.name', 'description' => 'container_requests.description, pipeline_instances.description' }
+    }.merge(local_assigns) %>
index 58914a84ac87b5b0949f07d634a826226a2b64af..c0519bcedfd6457ed3aca4608cc6e14289a9c473 100644 (file)
@@ -421,7 +421,7 @@ class ProjectsControllerTest < ActionController::TestCase
 
   [
     ["active", 5, ["aproject", "asubproject"], "anonymously_accessible_project"],
-    ["user1_with_load", 2, ["project_with_10_collections"], "project_with_2_pipelines_and_60_jobs"],
+    ["user1_with_load", 2, ["project_with_10_collections"], "project_with_2_pipelines_and_60_crs"],
     ["admin", 5, ["anonymously_accessible_project", "subproject_in_anonymous_accessible_project"], "aproject"],
   ].each do |user, page_size, tree_segment, unexpected|
     test "build my projects tree for #{user} user and verify #{unexpected} is omitted" do
index d58a0315ee54595c2e3d4d10e09c4a822d2e93ae..6e28e4efb4525363fdf3fb1184348b08d3a19647 100644 (file)
@@ -68,7 +68,7 @@ class AnonymousAccessTest < ActionDispatch::IntegrationTest
 
     assert_selector 'a', text: 'Description'
     assert_selector 'a', text: 'Data collections'
-    assert_selector 'a', text: 'Jobs and pipelines'
+    assert_selector 'a', text: 'Pipelines and processes'
     assert_selector 'a', text: 'Pipeline templates'
     assert_selector 'a', text: 'Subprojects'
     assert_selector 'a', text: 'Advanced'
@@ -123,39 +123,35 @@ class AnonymousAccessTest < ActionDispatch::IntegrationTest
   end
 
   [
-    'running_job',
-    'completed_job',
+    'running anonymously accessible cr',
     'pipelineInstance'
-  ].each do |type|
-    test "anonymous user accesses jobs and pipelines tab in shared project and clicks on #{type}" do
+  ].each do |proc|
+    test "anonymous user accesses pipelines and processes tab in shared project and clicks on '#{proc}'" do
       visit PUBLIC_PROJECT
       click_link 'Data collections'
       assert_text 'GNU General Public License'
 
-      click_link 'Jobs and pipelines'
+      click_link 'Pipelines and processes'
       assert_text 'Pipeline in publicly accessible project'
 
-      # click on the specified job
-      if type.include? 'job'
-        verify_job_row type
-      else
+      if proc.include? 'pipeline'
         verify_pipeline_instance_row
+      else
+        verify_container_request_row proc
       end
     end
   end
 
-  def verify_job_row look_for
+  def verify_container_request_row look_for
     within first('tr', text: look_for) do
       click_link 'Show'
     end
     assert_text 'Public Projects Unrestricted public data'
-    assert_text 'script_version'
+    assert_text 'command'
 
     assert_text 'zzzzz-tpzed-xurymjxw79nv3jz' # modified by user
     assert_no_selector 'a', text: 'zzzzz-tpzed-xurymjxw79nv3jz'
-    assert_no_selector 'a', text: 'Move job'
     assert_no_selector 'button', text: 'Cancel'
-    assert_no_selector 'button', text: 'Re-run job'
   end
 
   def verify_pipeline_instance_row
index 2ab8beb294ab8f2ae99e1c6866d2ad7efbcb0822..3d8cbf0b630ee9ddcd7db17ccc4398c645db2b0c 100644 (file)
@@ -82,7 +82,7 @@ class PipelineInstancesTest < ActionDispatch::IntegrationTest
       wait_for_ajax
     end
 
-    click_link 'Jobs and pipelines'
+    click_link 'Pipelines and processes'
     find('tr[data-kind="arvados#pipelineInstance"]', text: '(none)').
       find('a', text: 'Show').
       click
index 01e84b1c0219d19551122356006f7081b0d42629..1c18a436fdbb3fcbaab3de74e9a350ce3e87bbab 100644 (file)
@@ -514,23 +514,23 @@ class ProjectsTest < ActionDispatch::IntegrationTest
 
   [
     ['project_with_10_pipelines', 10, 0],
-    ['project_with_2_pipelines_and_60_jobs', 2, 60],
+    ['project_with_2_pipelines_and_60_crs', 2, 60],
     ['project_with_25_pipelines', 25, 0],
-  ].each do |project_name, num_pipelines, num_jobs|
-    test "scroll pipeline instances tab for #{project_name} with #{num_pipelines} pipelines and #{num_jobs} jobs" do
-      item_list_parameter = "Jobs_and_pipelines"
+  ].each do |project_name, num_pipelines, num_crs|
+    test "scroll pipeline instances tab for #{project_name} with #{num_pipelines} pipelines and #{num_crs} container requests" do
+      item_list_parameter = "Pipelines_and_processes"
       scroll_setup project_name,
-                   num_pipelines + num_jobs,
+                   num_pipelines + num_crs,
                    item_list_parameter
       # check the general scrolling and the pipelines
       scroll_items_check num_pipelines,
                          "pipeline_",
                          item_list_parameter,
                          'tr[data-kind="arvados#pipelineInstance"]'
-      # Check job count separately
-      jobs_found = page.all('tr[data-kind="arvados#job"]')
-      found_job_count = jobs_found.count
-      assert_equal num_jobs, found_job_count, 'Did not find expected number of jobs'
+      # Check container request count separately
+      crs_found = page.all('tr[data-kind="arvados#containerRequest"]')
+      found_cr_count = crs_found.count
+      assert_equal num_crs, found_cr_count, 'Did not find expected number of container requests'
     end
   end
 
@@ -618,8 +618,8 @@ class ProjectsTest < ActionDispatch::IntegrationTest
       assert_no_selector 'li.disabled', text: 'Copy selected'
     end
 
-    # Go to Jobs and pipelines tab and assert none selected
-    click_link 'Jobs and pipelines'
+    # Go to Pipelines and processes tab and assert none selected
+    click_link 'Pipelines and processes'
     wait_for_ajax
 
     # Since this is the first visit to this tab, all selection options should be disabled
index 9f20a88a9519d09eb5d7fe040c93706379bc089d..cd9633db427aa1807d4a600f6533225f543e4b34 100644 (file)
@@ -29,6 +29,8 @@ table(table table-bordered table-condensed).
 
 Note: Because adding access tokens to manifests can be computationally expensive, the @manifest_text@ field is not included in listed collections.  If you need it, request a "list of collections":{{site.baseurl}}/api/methods/collections.html with the filter @["owner_uuid", "=", GROUP_UUID]@, and @"manifest_text"@ listed in the select parameter.
 
+Note: Use filters with the attribute format @<item type>.<field name>@ to filter items of a specific type. For example: @["pipeline_instances.state", "=", "Complete"]@ to filter @pipeline_instances@ where @state@ is @Complete@. All other types of items owned by this group will be unimpacted by this filter and will still be included.
+
 h2. create
 
 Create a new Group.
index eae6dca8c0332ae820fbedbb3965f3112453dfb9..a1bfb8bc5ec6620a27d9e8da2cf87a9d885ee049 100644 (file)
@@ -61,10 +61,21 @@ class Arvados::V1::GroupsController < ApplicationController
     request_orders = @orders.clone
     @orders = []
 
-    [Group,
-     Job, PipelineInstance, PipelineTemplate,
+    request_filters = @filters
+
+    klasses = [Group,
+     Job, PipelineInstance, PipelineTemplate, ContainerRequest,
      Collection,
-     Human, Specimen, Trait].each do |klass|
+     Human, Specimen, Trait]
+
+    table_names = klasses.map(&:table_name)
+    request_filters.each do |col, op, val|
+      if col.index('.') && !table_names.include?(col.split('.', 2)[0])
+        raise ArgumentError.new("Invalid attribute '#{col}' in filter")
+      end
+    end
+
+    klasses.each do |klass|
       # If the currently requested orders specifically match the
       # table_name for the current klass, apply that order.
       # Otherwise, order by recency.
@@ -81,6 +92,16 @@ class Arvados::V1::GroupsController < ApplicationController
         where_conds[:group_class] = "project"
       end
 
+      @filters = request_filters.map do |col, op, val|
+        if !col.index('.')
+          [col, op, val]
+        elsif (col = col.split('.', 2))[0] == klass.table_name
+          [col[1], op, val]
+        else
+          nil
+        end
+      end.compact
+
       @objects = klass.readable_by(*@read_users).
         order(request_order).where(where_conds)
       @limit = limit_all - all_objects.count
index 1e3d773550579b03a188d2ea129928cd457cf291..04746d3abb9bcb281707b3a88fa948458a60f938 100644 (file)
@@ -110,3 +110,36 @@ cr_for_requester2:
   output_path: test
   command: ["echo", "hello"]
   requesting_container_uuid: zzzzz-dz642-requestercntnr1
+
+running_anonymous_accessible:
+  uuid: zzzzz-xvhdp-runninganonaccs
+  owner_uuid: zzzzz-j7d0g-zhxawtyetzwc5f0
+  name: running anonymously accessible cr
+  state: Committed
+  priority: 1
+  created_at: 2016-01-11 11:11:11.111111111 Z
+  updated_at: 2016-01-11 11:11:11.111111111 Z
+  modified_at: 2016-01-11 11:11:11.111111111 Z
+  modified_by_user_uuid: zzzzz-tpzed-xurymjxw79nv3jz
+  container_image: test
+  cwd: test
+  output_path: test
+  command: ["echo", "hello"]
+  container_uuid: zzzzz-dz642-runningcontain2
+
+# Test Helper trims the rest of the file
+
+# Do not add your fixtures below this line as the rest of this file will be trimmed by test_helper
+
+# container requests in project_with_2_pipelines_and_60_crs
+<% for i in 1..60 do %>
+cr_<%=i%>_of_60:
+  uuid: zzzzz-xvhdp-oneof60crs<%= i.to_s.rjust(5, '0') %>
+  created_at: <%= ((i+5)/5).hour.ago.to_s(:db) %>
+  owner_uuid: zzzzz-j7d0g-nnncrspipelines
+  name: cr-<%= i.to_s %>
+  output_path: test
+  command: ["echo", "hello"]
+<% end %>
+
+# Do not add your fixtures below this line as the rest of this file will be trimmed by test_helper
index 4029846484d41a79acc2443246bae76a8c526fa3..b90a25ced816e2a19fdeb5d70e5b5fa6c4a2f7a7 100644 (file)
@@ -196,15 +196,15 @@ project_with_10_pipelines:
   description: project with 10 pipelines
   group_class: project
 
-project_with_2_pipelines_and_60_jobs:
-  uuid: zzzzz-j7d0g-nnjobspipelines
+project_with_2_pipelines_and_60_crs:
+  uuid: zzzzz-j7d0g-nnncrspipelines
   owner_uuid: zzzzz-tpzed-user1withloadab
   created_at: 2014-04-21 15:37:48 -0400
   modified_by_client_uuid: zzzzz-ozdt8-brczlopd8u8d0jr
   modified_by_user_uuid: zzzzz-tpzed-user1withloadab
   modified_at: 2014-04-21 15:37:48 -0400
   updated_at: 2014-04-21 15:37:48 -0400
-  name: project with 2 pipelines and 60 jobs
+  name: project with 2 pipelines and 60 crs
   description: This will result in two pages in the display
   group_class: project
 
index d0c22d305954a2e832d3e8c4dac43725a982db26..95cb967ffc1a9c71b418e2949b063ed9f419d4c1 100644 (file)
@@ -527,19 +527,3 @@ running_job_with_components:
   components:
     component1: zzzzz-8i9sb-jyq01m7in1jlofj
     component2: zzzzz-d1hrv-partdonepipelin
-
-# Test Helper trims the rest of the file
-
-# Do not add your fixtures below this line as the rest of this file will be trimmed by test_helper
-
-# jobs in project_with_2_pipelines_and_60_jobs
-<% for i in 1..60 do %>
-job_<%=i%>_of_60:
-  uuid: zzzzz-8i9sb-oneof100jobs<%= i.to_s.rjust(3, '0') %>
-  created_at: <%= ((i+5)/5).minute.ago.to_s(:db) %>
-  owner_uuid: zzzzz-j7d0g-nnjobspipelines
-  script_version: 7def43a4d3f20789dda4700f703b5514cc3ed250
-  state: Complete
-<% end %>
-
-# Do not add your fixtures below this line as the rest of this file will be trimmed by test_helper
index 04a200ddb08d38304926d8babeafe181f7d1752e..34dbe9603bcc9c53ec6fd15f7c78a4a082643dfc 100644 (file)
@@ -445,13 +445,13 @@ pipeline_<%=i%>_of_10:
           title: foo instance input
 <% end %>
 
-# pipelines in project_with_2_pipelines_and_100_jobs
+# pipelines in project_with_2_pipelines_and_60_crs
 <% for i in 1..2 do %>
-pipeline_<%=i%>_of_2_pipelines_and_100_jobs:
+pipeline_<%=i%>_of_2_pipelines_and_60_crs:
   name: pipeline_<%= i %>
   state: New
   uuid: zzzzz-d1hrv-abcgneyn6brx<%= i.to_s.rjust(3, '0') %>
-  owner_uuid: zzzzz-j7d0g-nnjobspipelines
+  owner_uuid: zzzzz-j7d0g-nnncrspipelines
   created_at: <%= i.minute.ago.to_s(:db) %>
   components:
     foo:
index 00846795b4d7f7501964d0b888ba87739ce6c9d7..10534a70610a8188d35863992f2810ac29195937 100644 (file)
@@ -423,4 +423,29 @@ class Arvados::V1::GroupsControllerTest < ActionController::TestCase
     end
     assert_equal true, found_projects.include?(groups(:starred_and_shared_active_user_project).uuid)
   end
+
+  [
+    [['owner_uuid', '!=', 'zzzzz-tpzed-xurymjxw79nv3jz'], 200,
+        'zzzzz-d1hrv-subprojpipeline', 'zzzzz-d1hrv-1xfj6xkicf2muk2'],
+    [["pipeline_instances.state", "not in", ["Complete", "Failed"]], 200,
+        'zzzzz-d1hrv-1xfj6xkicf2muk2', 'zzzzz-d1hrv-i3e77t9z5y8j9cc'],
+    [['container_requests.requesting_container_uuid', '=', nil], 200,
+        'zzzzz-xvhdp-cr4queuedcontnr', 'zzzzz-xvhdp-cr4requestercn2'],
+    [['container_requests.no_such_column', '=', nil], 422],
+    [['container_requests.', '=', nil], 422],
+    [['.requesting_container_uuid', '=', nil], 422],
+    [['no_such_table.uuid', '!=', 'zzzzz-tpzed-xurymjxw79nv3jz'], 422],
+  ].each do |filter, expect_code, expect_uuid, not_expect_uuid|
+    test "get contents with '#{filter}' filter" do
+      authorize_with :active
+      get :contents, filters: [filter], format: :json
+      assert_response expect_code
+      if expect_code == 200
+        assert_not_empty json_response['items']
+        item_uuids = json_response['items'].collect {|item| item['uuid']}
+        assert_includes(item_uuids, expect_uuid)
+        assert_not_includes(item_uuids, not_expect_uuid)
+      end
+    end
+  end
 end