[ARVADOS] updated: 1c9ae7e8c8d7920602250958333751b769fb3a72

git at public.curoverse.com git at public.curoverse.com
Thu May 1 18:08:47 EDT 2014


Summary of changes:
 .../app/assets/javascripts/application.js          |    7 +
 .../app/assets/javascripts/collections.js          |   59 ++
 .../app/assets/javascripts/collections.js.coffee   |    3 -
 .../app/assets/stylesheets/collections.css.scss    |   21 +-
 .../app/controllers/collections_controller.rb      |   34 ++-
 apps/workbench/app/controllers/users_controller.rb |   36 +-
 .../app/controllers/websocket_controller.rb        |   10 +
 apps/workbench/app/models/group.rb                 |    4 +-
 apps/workbench/app/models/user.rb                  |    9 -
 .../app/views/collections/_index_tbody.html.erb    |   10 +-
 .../app/views/collections/_show_files.html.erb     |   12 +
 .../app/views/collections/_show_recent.html.erb    |    8 +-
 .../app/views/collections/_toggle_persist.html.erb |    3 +
 apps/workbench/app/views/users/_tables.html.erb    |  120 +++--
 apps/workbench/app/views/websocket/index.html.erb  |   34 ++
 apps/workbench/config/routes.rb                    |    5 +-
 .../workbench/test/integration/collections_test.rb |   42 ++
 apps/workbench/test/unit/group_test.rb             |   12 +-
 apps/workbench/test/unit/user_test.rb              |   12 -
 doc/api/methods/groups.html.textile.liquid         |   26 +-
 doc/api/methods/users.html.textile.liquid          |   12 -
 sdk/cli/bin/arv-run-pipeline-instance              |    4 +-
 sdk/ruby/lib/arvados.rb                            |   36 +-
 services/api/Gemfile                               |    5 +
 services/api/Gemfile.lock                          |   12 +
 .../api/app/controllers/application_controller.rb  |  300 +++--------
 .../v1/api_client_authorizations_controller.rb     |   32 +-
 .../arvados/v1/keep_disks_controller.rb            |    2 +-
 .../app/controllers/arvados/v1/nodes_controller.rb |    4 +-
 .../controllers/arvados/v1/schema_controller.rb    |   12 +-
 .../arvados/v1/virtual_machines_controller.rb      |   16 -
 services/api/app/controllers/static_controller.rb  |    2 +-
 .../app/controllers/user_sessions_controller.rb    |    2 +-
 services/api/app/middlewares/arvados_api_token.rb  |   61 +++
 services/api/app/middlewares/rack_socket.rb        |   86 +++
 .../api/app/models/api_client_authorization.rb     |   12 +
 services/api/app/models/arvados_model.rb           |   93 +++-
 services/api/app/models/blob.rb                    |   19 +-
 services/api/app/models/link.rb                    |   11 +
 services/api/app/models/log.rb                     |    8 +-
 services/api/app/models/node.rb                    |    2 +-
 services/api/config/application.yml.example        |    7 +
 services/api/config/initializers/authorization.rb  |    5 +
 services/api/config/initializers/eventbus.rb       |   18 +
 services/api/config/routes.rb                      |    3 +-
 .../20140421151939_rename_auth_keys_user_index.rb  |   11 +
 .../20140423132913_add_object_owner_to_logs.rb     |   27 +
 .../db/migrate/20140423133559_new_scope_format.rb  |   48 ++
 ...0140501165548_add_unique_name_index_to_links.rb |   13 +
 services/api/db/schema.rb                          |    9 +-
 services/api/lib/current_api_client.rb             |   10 -
 services/api/lib/eventbus.rb                       |  226 ++++++++
 services/api/lib/load_param.rb                     |   88 +++
 services/api/lib/record_filters.rb                 |   75 +++
 .../test/fixtures/api_client_authorizations.yml    |   52 ++
 services/api/test/fixtures/links.yml               |   32 +-
 services/api/test/fixtures/logs.yml                |   31 +-
 services/api/test/fixtures/repositories.yml        |    9 +-
 services/api/test/fixtures/specimens.yml           |   12 +-
 .../api_client_authorizations_controller_test.rb   |   30 +-
 .../arvados/v1/groups_controller_test.rb           |   78 +++-
 .../functional/arvados/v1/links_controller_test.rb |   13 +
 .../functional/arvados/v1/nodes_controller_test.rb |    9 +
 .../functional/arvados/v1/users_controller_test.rb |   76 ---
 .../api_client_authorizations_scopes_test.rb       |   85 +++
 .../api/test/integration/login_workflow_test.rb    |   25 +
 .../api/test/integration/reader_tokens_test.rb     |   85 +++
 services/api/test/integration/websocket_test.rb    |  570 ++++++++++++++++++++
 services/api/test/test_helper.rb                   |   29 +-
 services/api/test/unit/blob_test.rb                |   27 +
 services/api/test/unit/link_test.rb                |   47 ++-
 services/api/test/unit/log_test.rb                 |   21 +
 services/api/test/websocket_runner.rb              |   42 ++
 services/keep/src/keep/keep.go                     |  271 +++-------
 services/keep/src/keep/keep_test.go                |  162 +++---
 services/keep/src/keep/volume.go                   |  129 +++++
 services/keep/src/keep/volume_unix.go              |  295 ++++++++++
 services/keep/src/keep/volume_unix_test.go         |  245 +++++++++
 78 files changed, 3277 insertions(+), 836 deletions(-)
 create mode 100644 apps/workbench/app/assets/javascripts/collections.js
 delete mode 100644 apps/workbench/app/assets/javascripts/collections.js.coffee
 create mode 100644 apps/workbench/app/controllers/websocket_controller.rb
 create mode 100644 apps/workbench/app/views/collections/_toggle_persist.html.erb
 create mode 100644 apps/workbench/app/views/websocket/index.html.erb
 create mode 100644 apps/workbench/test/integration/collections_test.rb
 create mode 100644 services/api/app/middlewares/arvados_api_token.rb
 create mode 100644 services/api/app/middlewares/rack_socket.rb
 create mode 100644 services/api/config/initializers/authorization.rb
 create mode 100644 services/api/config/initializers/eventbus.rb
 create mode 100644 services/api/db/migrate/20140421151939_rename_auth_keys_user_index.rb
 create mode 100644 services/api/db/migrate/20140423132913_add_object_owner_to_logs.rb
 create mode 100644 services/api/db/migrate/20140423133559_new_scope_format.rb
 create mode 100644 services/api/db/migrate/20140501165548_add_unique_name_index_to_links.rb
 create mode 100644 services/api/lib/eventbus.rb
 create mode 100644 services/api/lib/load_param.rb
 create mode 100644 services/api/lib/record_filters.rb
 create mode 100644 services/api/test/integration/api_client_authorizations_scopes_test.rb
 create mode 100644 services/api/test/integration/login_workflow_test.rb
 create mode 100644 services/api/test/integration/reader_tokens_test.rb
 create mode 100644 services/api/test/integration/websocket_test.rb
 create mode 100644 services/api/test/websocket_runner.rb
 create mode 100644 services/keep/src/keep/volume.go
 create mode 100644 services/keep/src/keep/volume_unix.go
 create mode 100644 services/keep/src/keep/volume_unix_test.go

       via  1c9ae7e8c8d7920602250958333751b769fb3a72 (commit)
       via  b93c1cd880d8367d11bd3fd7574e55f4545a34c5 (commit)
       via  ccce5e8ad71ed2e50ecd57c0f73f1aaafc468539 (commit)
       via  70fddd1f7cacaa0db92b3b76a0baeeddf6f0d9b6 (commit)
       via  83dcc2c95eeb38c6b0f6f7509338aa729f14d762 (commit)
       via  3bd5f6c3f353059c15eeea51b16b2fdee694d504 (commit)
       via  7ce745d5645dc49c2833c1c617fd488bf3a62307 (commit)
       via  fb72864bb6f2ee3ca702b914c97d06a76e01ab0d (commit)
       via  cd08497d1c914cd75fd8be08f9f3ef3bc75485f2 (commit)
       via  6a53a3c5d97d33586567f8df082a725f7d229327 (commit)
       via  681496f40864418fc1ee46277941a40d3445107c (commit)
       via  c6068bbeea3ea9bfee45204c2990caef0d4ec1ae (commit)
       via  33b49fa0be7d8e0774c80ec315985dcdf8535962 (commit)
       via  83781a4f423a3671a5ec6d4b1cd6a0bbeacef3a6 (commit)
       via  73d73c7b799ddb60363ddf409d8d301b27c82c00 (commit)
       via  02377152d7e368b6b73b2a94ceb68c99f9d55959 (commit)
       via  a6439c7ddc3407193889386051f06df2a1e74ea9 (commit)
       via  da67c81ff6cc5fd540c0725de1c8208c2d8933be (commit)
       via  57b46f9b292e561739fde3ea098c366db8f4bc23 (commit)
       via  e8f81804c24307b6702b1897c80b4be832254454 (commit)
       via  1812950e91daaf7a1b02e3777c4e1d483b42d018 (commit)
       via  e87cfcde836ef572a722d645655c7a05fb3f473d (commit)
       via  4fb767326911e01898e5ae28a55a1491b9535b36 (commit)
       via  943feeec776bb75c685cbdee9466f8db3cdf5da7 (commit)
       via  1433693e08e2d4052cc94f6a5902523b08bbc1ac (commit)
       via  e20c9587ad703ae8e1f81251a6e209834a52d448 (commit)
       via  a4724fe92e651abb06acf8c5e75184561a55c854 (commit)
       via  208e172287aba3be7cb988a2c416e4281a2e5f60 (commit)
       via  b0c30631bceb2d1837b52d1d3475e52aee4c9c43 (commit)
       via  840e7d7f96f763ae139545dca5d6dfa5a54f6cc6 (commit)
       via  b421d5c4754315cdd8b70b6bbea5b5f23fb425de (commit)
       via  9cfbcdf804974812b1a4ec514f5dc7902fce6137 (commit)
       via  8adde5132926e8f9cc1b01d79f9307614cc6021e (commit)
       via  8eaad00b025167a7505ba11ad6a05b52a43c2399 (commit)
       via  30f834eef8916c0d613c098a4897ac932a2e0b37 (commit)
       via  c18bde8300e115b215e58d6930d0495b2c33b49f (commit)
       via  4e3ac7f8bafde72ae397f79bfc36409e682b13e5 (commit)
       via  7b9cff04eb463c666b8126ebc6c4dfcc00a536c0 (commit)
       via  f845c0645d9136a1e4ad993ecf34a156367e73b7 (commit)
       via  03e570095885982d23e234bce8e1c068314b63af (commit)
       via  5c2758ca38d01a905253f86e63be3a5fe03a3871 (commit)
       via  52c4f2b7fe631f3d7ad16105cb2f86cf6c004fc8 (commit)
       via  e54bdba73b65e31b03fd1d43bfe69d0f43bbd8d8 (commit)
       via  0eb59e3acf9f13e89bd010f7f65a4d31554183fc (commit)
       via  915de6c854cd559ebd029b24939149e37b18c8cf (commit)
       via  71b1b7b045419817d1c9dc62a3a296b746d9117c (commit)
       via  4ab25f3b39de88d6d2382bb91af9d67bd6de3bd3 (commit)
       via  2ea7a68942928d1d37166726be5114cb7fbdb75b (commit)
       via  f74cbd153b5cbe4e3678c9b86178019f593b553d (commit)
       via  f37f7c068b8d59934c7b0632d531c08470323123 (commit)
       via  e05f165ac12cb54faad707548b8b8f2005f2eef6 (commit)
       via  b860994fa83b9f11b7243220efb8f2fe9b2e2917 (commit)
       via  4fa5a3d3958eae7ecce681e0ea7a4ac8cc43e48d (commit)
       via  a28be6d77750a6cbded994612d95ee973cb4c01e (commit)
       via  58dd340f19c3e0225ad189e60a58872d3aa3f7c2 (commit)
       via  e537bd8dd1ac786164f192374e0d076bdc0327f3 (commit)
       via  995dd33ec5bc9ebb7cc4ff075a1f5e1a4e7db20c (commit)
       via  1c5176d87df0dbd25db6ff1fb2ab82ae17472145 (commit)
       via  5d356c84dcf8f3a2129cce0f4fbfc50f16a8a339 (commit)
       via  4eb42fd91dc5e50840e0d3db5d5201561602a508 (commit)
       via  7c12fc4d989dd2b4c47a174280a4f9526ecb0798 (commit)
       via  f6f07b1856fc0aa32cdf1f96d5bdeb12e9e314ef (commit)
       via  919cf4c2c9f803f0cdb80619bcbf5d23b7c02d25 (commit)
       via  6c0b68255c0c66d90c0473561461d9215860f018 (commit)
       via  9e97504e5f65c8a3a6f1f34da678ac7e1828e8e1 (commit)
       via  62db3393df8d6bc7c48a3c5101468361cb2f3cf3 (commit)
       via  e062efe37ddf066af1c5c762b126bb72766fee25 (commit)
       via  dbce533271fca5a106ab8a00ad2621177445131f (commit)
       via  20334fa95bb7d554c09225c02fae3d4e83c6c6c5 (commit)
       via  0a72fd5c9f764eba4fc295d8beb24ac3d01885c5 (commit)
       via  87f17f28080eef37ad940a039fd1623e72e3058e (commit)
       via  c72f1de32f688690d1161a1852e471e88919e057 (commit)
       via  f0ca76acaa3a4e3713f7aef6a6bb778e6e71e562 (commit)
       via  1f9df3c7140d4eacf58d4e19a7ddc81260296229 (commit)
       via  78b5bfcb1fa832e4460cfaa41f7815ce1d07a9a4 (commit)
       via  93db9aecb724964a37474104243a6d619b56769f (commit)
       via  da3e84a0984d60a2f4bec00672eb766e2e978859 (commit)
       via  aaa65e9d351284278ccb6d3e803fd3dd4f748c31 (commit)
       via  73cf2bb90245787fbbd7c18da51329524c40f6af (commit)
       via  da1614ac6d9b1b2aeba6267b304ce70c1726b608 (commit)
       via  7130989e6493555eba3491cfc9c8dddd1e1a545a (commit)
       via  923e2bd7d962f1a0feefc73ae4f4531c8235a591 (commit)
       via  eca0d3d0a6938e08dde6067c4565754c45f5ebb7 (commit)
       via  04cc77648cc62c73433801475c27ede4ceb76c8b (commit)
       via  fa257c28461627fe6700dd8fd2152e380f8725d4 (commit)
       via  cb52a672642bdec7c6a97868a68bbb9b8daa0efb (commit)
       via  d07a96a0f0c11b98ecc927f0b3e0b052f8ef99f7 (commit)
       via  b66ad0b212a80c117b5b344a715331962d0bfe2d (commit)
       via  e484a466d78c87114779b596d6ecd79f22088ee2 (commit)
       via  aa920f1659aa830861c196617fe664f35b5c12ef (commit)
       via  c283713dc8762c396407f68129fb276dc4a746fc (commit)
       via  4e047434f0c6958db039cf9ab55e3f7f44da44c9 (commit)
       via  7bc20af4935fee1caa566e86a074022f0b60d166 (commit)
       via  8202cb5f1682588e35dcf90519f53d74c06d4aa6 (commit)
      from  34350a8b802a8c48b534673a712614d36a5b97ac (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.


commit 1c9ae7e8c8d7920602250958333751b769fb3a72
Author: Tom Clegg <tom at curoverse.com>
Date:   Thu May 1 18:01:37 2014 -0400

    Add unique and valid name constraints.

diff --git a/services/api/app/models/link.rb b/services/api/app/models/link.rb
index 26e7183..37b4c89 100644
--- a/services/api/app/models/link.rb
+++ b/services/api/app/models/link.rb
@@ -9,6 +9,7 @@ class Link < ArvadosModel
   after_create :maybe_invalidate_permissions_cache
   after_destroy :maybe_invalidate_permissions_cache
   attr_accessor :head_kind, :tail_kind
+  validate :name_link_has_valid_name
 
   api_accessible :user, extend: :common do |t|
     t.add :tail_uuid
@@ -81,4 +82,14 @@ class Link < ArvadosModel
       User.invalidate_permissions_cache
     end
   end
+
+  def name_link_has_valid_name
+    if link_class == 'name'
+      unless name.is_a? String and !name.empty?
+        errors.add('name', 'must be a non-empty string')
+      end
+    else
+      true
+    end
+  end
 end
diff --git a/services/api/test/functional/arvados/v1/links_controller_test.rb b/services/api/test/functional/arvados/v1/links_controller_test.rb
index 804e1bd..dfce78b 100644
--- a/services/api/test/functional/arvados/v1/links_controller_test.rb
+++ b/services/api/test/functional/arvados/v1/links_controller_test.rb
@@ -270,4 +270,17 @@ class Arvados::V1::LinksControllerTest < ActionController::TestCase
     assert_response :success
   end
 
+  test "refuse duplicate name" do
+    the_name = links(:job_name_in_afolder).name
+    the_folder = links(:job_name_in_afolder).tail_uuid
+    authorize_with :active
+    post :create, link: {
+      tail_uuid: the_folder,
+      head_uuid: specimens(:owned_by_active_user).uuid,
+      link_class: 'name',
+      name: the_name,
+      properties: {this_s: "a duplicate name"}
+    }
+    assert_response 422
+  end
 end
diff --git a/services/api/test/unit/link_test.rb b/services/api/test/unit/link_test.rb
index 944bfce..72d6017 100644
--- a/services/api/test/unit/link_test.rb
+++ b/services/api/test/unit/link_test.rb
@@ -1,7 +1,48 @@
 require 'test_helper'
 
 class LinkTest < ActiveSupport::TestCase
-  # test "the truth" do
-  #   assert true
-  # end
+  fixtures :all
+
+  setup do
+    Thread.current[:user] = users(:active)
+  end
+
+  test 'name links with the same tail_uuid must be unique' do
+    a = Link.create!(tail_uuid: groups(:afolder).uuid,
+                     head_uuid: specimens(:owned_by_active_user).uuid,
+                     link_class: 'name',
+                     name: 'foo')
+    assert a.valid?, a.errors.to_s
+    assert_raises ActiveRecord::RecordNotUnique do
+      b = Link.create!(tail_uuid: groups(:afolder).uuid,
+                       head_uuid: specimens(:owned_by_active_user).uuid,
+                       link_class: 'name',
+                       name: 'foo')
+    end
+  end
+
+  test 'name links with different tail_uuid need not be unique' do
+    a = Link.create!(tail_uuid: groups(:afolder).uuid,
+                     head_uuid: specimens(:owned_by_active_user).uuid,
+                     link_class: 'name',
+                     name: 'foo')
+    assert a.valid?, a.errors.to_s
+    b = Link.create!(tail_uuid: groups(:asubfolder).uuid,
+                     head_uuid: specimens(:owned_by_active_user).uuid,
+                     link_class: 'name',
+                     name: 'foo')
+    assert b.valid?, b.errors.to_s
+    assert_not_equal(a.uuid, b.uuid,
+                     "created two links and got the same uuid back.")
+  end
+
+  [nil, '', false].each do |name|
+    test "name links cannot have name=#{name.inspect}" do
+      a = Link.create(tail_uuid: groups(:afolder).uuid,
+                      head_uuid: specimens(:owned_by_active_user).uuid,
+                      link_class: 'name',
+                      name: name)
+      assert a.invalid?, "invalid name was accepted as valid?"
+    end
+  end
 end

commit b93c1cd880d8367d11bd3fd7574e55f4545a34c5
Author: Tom Clegg <tom at curoverse.com>
Date:   Thu May 1 17:43:50 2014 -0400

    Fix wrong infixes in fixture uuids.

diff --git a/services/api/test/fixtures/links.yml b/services/api/test/fixtures/links.yml
index c58e273..87997df 100644
--- a/services/api/test/fixtures/links.yml
+++ b/services/api/test/fixtures/links.yml
@@ -233,7 +233,7 @@ foo_repository_readable_by_spectator:
   tail_uuid: zzzzz-tpzed-l1s2piq4t4mps8r
   link_class: permission
   name: can_read
-  head_uuid: zzzzz-2x53u-382brsig8rp3666
+  head_uuid: zzzzz-s0uqq-382brsig8rp3666
   properties: {}
 
 miniadmin_user_is_a_testusergroup_admin:
@@ -299,7 +299,7 @@ specimen_is_in_two_folders:
   modified_at: 2014-04-21 15:37:48 -0400
   updated_at: 2014-04-21 15:37:48 -0400
   tail_uuid: zzzzz-j7d0g-axqo7eu9pwvna1x
-  head_uuid: zzzzz-2x53u-5gid26432uujf79
+  head_uuid: zzzzz-j58dm-5gid26432uujf79
   link_class: name
   name: "I'm in a subfolder, too"
   properties: {}
diff --git a/services/api/test/fixtures/repositories.yml b/services/api/test/fixtures/repositories.yml
index 62a153d..1322240 100644
--- a/services/api/test/fixtures/repositories.yml
+++ b/services/api/test/fixtures/repositories.yml
@@ -1,9 +1,9 @@
 foo:
-  uuid: zzzzz-2x53u-382brsig8rp3666
+  uuid: zzzzz-s0uqq-382brsig8rp3666
   owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz # active user
   name: foo
 
 repository2:
-  uuid: zzzzz-2x53u-382brsig8rp3667
+  uuid: zzzzz-s0uqq-382brsig8rp3667
   owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz # active user
   name: foo2
diff --git a/services/api/test/fixtures/specimens.yml b/services/api/test/fixtures/specimens.yml
index 6ad7cfe..40f78c1 100644
--- a/services/api/test/fixtures/specimens.yml
+++ b/services/api/test/fixtures/specimens.yml
@@ -1,23 +1,23 @@
 owned_by_active_user:
-  uuid: zzzzz-2x53u-3zx463qyo0k4xrn
+  uuid: zzzzz-j58dm-3zx463qyo0k4xrn
   owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz
 
 owned_by_private_group:
-  uuid: zzzzz-2x53u-5m3qwg45g3nlpu6
+  uuid: zzzzz-j58dm-5m3qwg45g3nlpu6
   owner_uuid: zzzzz-j7d0g-rew6elm53kancon
 
 owned_by_spectator:
-  uuid: zzzzz-2x53u-3b0xxwzlbzxq5yr
+  uuid: zzzzz-j58dm-3b0xxwzlbzxq5yr
   owner_uuid: zzzzz-tpzed-l1s2piq4t4mps8r
 
 in_afolder:
-  uuid: zzzzz-2x53u-7r18rnd5nzhg5yk
+  uuid: zzzzz-j58dm-7r18rnd5nzhg5yk
   owner_uuid: zzzzz-j7d0g-v955i6s2oi1cbso
 
 in_asubfolder:
-  uuid: zzzzz-2x53u-c40lddwcqqr1ffs
+  uuid: zzzzz-j58dm-c40lddwcqqr1ffs
   owner_uuid: zzzzz-j7d0g-axqo7eu9pwvna1x
 
 in_afolder_linked_from_asubfolder:
-  uuid: zzzzz-2x53u-5gid26432uujf79
+  uuid: zzzzz-j58dm-5gid26432uujf79
   owner_uuid: zzzzz-j7d0g-v955i6s2oi1cbso

commit ccce5e8ad71ed2e50ecd57c0f73f1aaafc468539
Merge: 70fddd1 7ce745d
Author: Tom Clegg <tom at curoverse.com>
Date:   Thu May 1 17:41:29 2014 -0400

    Merge branch 'master' into 2640-folder-api


commit 70fddd1f7cacaa0db92b3b76a0baeeddf6f0d9b6
Author: Tom Clegg <tom at curoverse.com>
Date:   Thu May 1 14:38:46 2014 -0400

    Use partial unique index for name links.

diff --git a/services/api/Gemfile b/services/api/Gemfile
index 3b715d3..4357887 100644
--- a/services/api/Gemfile
+++ b/services/api/Gemfile
@@ -68,3 +68,6 @@ gem 'database_cleaner'
 gem 'themes_for_rails'
 
 gem 'arvados-cli', '>= 0.1.20140328152103'
+
+# pg_power lets us use partial indexes in schema.rb in Rails 3
+gem 'pg_power'
diff --git a/services/api/Gemfile.lock b/services/api/Gemfile.lock
index d00e681..a09f950 100644
--- a/services/api/Gemfile.lock
+++ b/services/api/Gemfile.lock
@@ -135,6 +135,9 @@ GEM
       rack
       rake (>= 0.8.1)
     pg (0.17.1)
+    pg_power (1.6.4)
+      pg
+      rails (~> 3.1)
     polyglot (0.3.4)
     rack (1.4.5)
     rack-cache (1.2)
@@ -218,6 +221,7 @@ DEPENDENCIES
   omniauth-oauth2 (= 1.1.1)
   passenger
   pg
+  pg_power
   rails (~> 3.2.0)
   redis
   rvm-capistrano
diff --git a/services/api/db/migrate/20140501165548_add_unique_name_index_to_links.rb b/services/api/db/migrate/20140501165548_add_unique_name_index_to_links.rb
index 0195cf0..444265a 100644
--- a/services/api/db/migrate/20140501165548_add_unique_name_index_to_links.rb
+++ b/services/api/db/migrate/20140501165548_add_unique_name_index_to_links.rb
@@ -1,6 +1,13 @@
 class AddUniqueNameIndexToLinks < ActiveRecord::Migration
   def change
-    # todo: add "check (link_class is not 'name' or name is not null)"
-    add_index :links, [:tail_uuid, :name], where: "link_class='name'", unique: true
+    # Make sure PgPower is here. Otherwise the "where" will be ignored
+    # and we'll end up with a far too restrictive unique
+    # constraint. (Rails4 should work without PgPower, but that isn't
+    # tested.)
+    if not PgPower then raise "No partial column support" end
+
+    add_index(:links, [:tail_uuid, :name], unique: true,
+              where: "link_class='name'",
+              name: 'links_tail_name_unique_if_link_class_name')
   end
 end
diff --git a/services/api/db/schema.rb b/services/api/db/schema.rb
index c4cef7c..0613cd3 100644
--- a/services/api/db/schema.rb
+++ b/services/api/db/schema.rb
@@ -11,7 +11,9 @@
 #
 # It's strongly recommended to check this file into your version control system.
 
-ActiveRecord::Schema.define(:version => 20140423133559) do
+ActiveRecord::Schema.define(:version => 20140501165548) do
+
+
 
   create_table "api_client_authorizations", :force => true do |t|
     t.string   "api_token",                                           :null => false
@@ -252,6 +254,7 @@ ActiveRecord::Schema.define(:version => 20140423133559) do
   add_index "links", ["created_at"], :name => "index_links_on_created_at"
   add_index "links", ["head_uuid"], :name => "index_links_on_head_uuid"
   add_index "links", ["modified_at"], :name => "index_links_on_modified_at"
+  add_index "links", ["tail_uuid", "name"], :name => "links_tail_name_unique_if_link_class_name", :unique => true, :where => "((link_class)::text = 'name'::text)"
   add_index "links", ["tail_uuid"], :name => "index_links_on_tail_uuid"
   add_index "links", ["uuid"], :name => "index_links_on_uuid", :unique => true
 
@@ -423,4 +426,5 @@ ActiveRecord::Schema.define(:version => 20140423133559) do
   add_index "virtual_machines", ["hostname"], :name => "index_virtual_machines_on_hostname"
   add_index "virtual_machines", ["uuid"], :name => "index_virtual_machines_on_uuid", :unique => true
 
+
 end

commit 83dcc2c95eeb38c6b0f6f7509338aa729f14d762
Author: Tom Clegg <tom at curoverse.com>
Date:   Thu May 1 14:38:15 2014 -0400

    Fix log permission case broken in merge.

diff --git a/services/api/app/models/arvados_model.rb b/services/api/app/models/arvados_model.rb
index 9c7fe2b..4f06f05 100644
--- a/services/api/app/models/arvados_model.rb
+++ b/services/api/app/models/arvados_model.rb
@@ -87,9 +87,11 @@ class ArvadosModel < ActiveRecord::Base
       # A permission link exists ('write' and 'manage' implicitly include
       # 'read') from a member of users_list, or a group readable by users_list,
       # to this row, or to the owner of this row (see join() below).
+      permitted_uuids = "(SELECT head_uuid FROM links WHERE link_class='permission' AND tail_uuid IN (#{sanitized_uuid_list}))"
+
       sql_conds += ["#{table_name}.owner_uuid in (?)",
                     "#{table_name}.uuid in (?)",
-                    "uuid IN (SELECT head_uuid FROM links WHERE link_class='permission' AND tail_uuid IN (#{sanitized_uuid_list}))"]
+                    "#{table_name}.uuid IN #{permitted_uuids}"]
       sql_params += [uuid_list, user_uuids]
 
       if self == Link and users_list.any?
@@ -102,7 +104,7 @@ class ArvadosModel < ActiveRecord::Base
 
       if self == Log and users_list.any?
         # Link head points to the object described by this row
-        or_object_uuid = ", #{table_name}.object_uuid"
+        sql_conds += ["#{table_name}.object_uuid IN #{permitted_uuids}"]
 
         # This object described by this row is owned by this user, or owned by a group readable by this user
         sql_conds += ["#{table_name}.object_owner_uuid in (?)"]

commit 3bd5f6c3f353059c15eeea51b16b2fdee694d504
Merge: 6a53a3c cd08497
Author: Tom Clegg <tom at curoverse.com>
Date:   Thu May 1 14:26:40 2014 -0400

    Merge branch 'master' into 2640-folder-api
    
    Conflicts:
    	services/api/app/controllers/application_controller.rb
    	services/api/app/models/arvados_model.rb

diff --cc services/api/app/controllers/application_controller.rb
index 140ee4e,4b5a27d..e93c2ab
--- a/services/api/app/controllers/application_controller.rb
+++ b/services/api/app/controllers/application_controller.rb
@@@ -7,21 -14,19 +14,19 @@@ class ApplicationController < ActionCon
  
    before_filter :respond_with_json_by_default
    before_filter :remote_ip
-   before_filter :require_auth_scope, :except => :render_not_found
-   before_filter :catch_redirect_hint
+   before_filter :load_read_auths
+   before_filter :require_auth_scope, except: ERROR_ACTIONS
  
-   before_filter :find_object_by_uuid, :except => [:index, :create,
-                                                   :render_error,
-                                                   :render_not_found]
+   before_filter :catch_redirect_hint
+   before_filter(:find_object_by_uuid,
+                 except: [:index, :create] + ERROR_ACTIONS)
 -  before_filter :load_limit_offset_order_params, only: [:index, :owned_items]
 -  before_filter :load_where_param, only: [:index, :owned_items]
 -  before_filter :load_filters_param, only: [:index, :owned_items]
 +  before_filter :load_limit_offset_order_params, only: [:index, :contents]
 +  before_filter :load_where_param, only: [:index, :contents]
 +  before_filter :load_filters_param, only: [:index, :contents]
    before_filter :find_objects_for_index, :only => :index
    before_filter :reload_object_before_update, :only => :update
-   before_filter :render_404_if_no_object, except: [:index, :create,
-                                                    :render_error,
-                                                    :render_not_found]
+   before_filter(:render_404_if_no_object,
+                 except: [:index, :create] + ERROR_ACTIONS)
  
    theme :select_theme
  
@@@ -89,10 -92,10 +92,10 @@@
          # disappointed: when Rails reloads model classes, we get two
          # distinct classes called Link which do not equal each
          # other. But we can still rely on klass.to_s to be "Link".
 -      when 'ApiClientAuthorization'
 +      when 'ApiClientAuthorization', 'UserAgreement'
          # Do not want.
        else
-         @objects = klass.readable_by(current_user)
+         @objects = klass.readable_by(*@read_users)
          cond_sql = "#{klass.table_name}.owner_uuid = ?"
          cond_params = [@object.uuid]
          if params[:include_linked]
diff --cc services/api/app/models/arvados_model.rb
index bacd163,1dcd9e2..9c7fe2b
--- a/services/api/app/models/arvados_model.rb
+++ b/services/api/app/models/arvados_model.rb
@@@ -59,31 -59,71 +59,67 @@@ class ArvadosModel < ActiveRecord::Bas
      self.columns.select { |col| col.name == attr.to_s }.first
    end
  
-   # def eager_load_associations
-   #   self.class.columns.each do |col|
-   #     re = col.name.match /^(.*)_kind$/
-   #     if (re and
-   #         self.respond_to? re[1].to_sym and
-   #         (auuid = self.send((re[1] + '_uuid').to_sym)) and
-   #         (aclass = self.class.kind_class(self.send(col.name.to_sym))) and
-   #         (aobject = aclass.where('uuid=?', auuid).first))
-   #       self.instance_variable_set('@'+re[1], aobject)
-   #     end
-   #   end
-   # end
- 
-   def self.readable_by user
-     uuid_list = [user.uuid, *user.groups_i_can(:read)]
-     sanitized_uuid_list = uuid_list.
-       collect { |uuid| sanitize(uuid) }.join(', ')
-     or_references_me = ''
-     if self == Link and user
-       or_references_me = "OR (#{table_name}.link_class in (#{sanitize 'permission'}, #{sanitize 'resources'}) AND #{sanitize user.uuid} IN (#{table_name}.head_uuid, #{table_name}.tail_uuid))"
+   # Return a query with read permissions restricted to the union of of the
+   # permissions of the members of users_list, i.e. if something is readable by
+   # any user in users_list, it will be readable in the query returned by this
+   # function.
+   def self.readable_by(*users_list)
+     # Get rid of troublesome nils
+     users_list.compact!
+ 
+     # Check if any of the users are admin.  If so, we're done.
+     if users_list.select { |u| u.is_admin }.empty?
+ 
+       # Collect the uuids for each user and any groups readable by each user.
+       user_uuids = users_list.map { |u| u.uuid }
+       uuid_list = user_uuids + users_list.flat_map { |u| u.groups_i_can(:read) }
+       sanitized_uuid_list = uuid_list.
+         collect { |uuid| sanitize(uuid) }.join(', ')
+       sql_conds = []
+       sql_params = []
+       or_object_uuid = ''
+ 
+       # This row is owned by a member of users_list, or owned by a group
+       # readable by a member of users_list
+       # or
+       # This row uuid is the uuid of a member of users_list
+       # or
+       # A permission link exists ('write' and 'manage' implicitly include
+       # 'read') from a member of users_list, or a group readable by users_list,
+       # to this row, or to the owner of this row (see join() below).
+       sql_conds += ["#{table_name}.owner_uuid in (?)",
+                     "#{table_name}.uuid in (?)",
 -                    "permissions.head_uuid IS NOT NULL"]
++                    "uuid IN (SELECT head_uuid FROM links WHERE link_class='permission' AND tail_uuid IN (#{sanitized_uuid_list}))"]
+       sql_params += [uuid_list, user_uuids]
+ 
+       if self == Link and users_list.any?
+         # This row is a 'permission' or 'resources' link class
+         # The uuid for a member of users_list is referenced in either the head
+         # or tail of the link
+         sql_conds += ["(#{table_name}.link_class in (#{sanitize 'permission'}, #{sanitize 'resources'}) AND (#{table_name}.head_uuid IN (?) OR #{table_name}.tail_uuid IN (?)))"]
+         sql_params += [user_uuids, user_uuids]
+       end
+ 
+       if self == Log and users_list.any?
+         # Link head points to the object described by this row
+         or_object_uuid = ", #{table_name}.object_uuid"
+ 
+         # This object described by this row is owned by this user, or owned by a group readable by this user
+         sql_conds += ["#{table_name}.object_owner_uuid in (?)"]
+         sql_params += [uuid_list]
+       end
+ 
+       # Link head points to this row, or to the owner of this row (the thing to be read)
+       #
+       # Link tail originates from this user, or a group that is readable by this
+       # user (the identity with authorization to read)
+       #
+       # Link class is 'permission' ('write' and 'manage' implicitly include 'read')
 -
 -      joins("LEFT JOIN links permissions ON permissions.head_uuid in (#{table_name}.owner_uuid, #{table_name}.uuid #{or_object_uuid}) AND permissions.tail_uuid in (#{sanitized_uuid_list}) AND permissions.link_class='permission'")
 -        .where(sql_conds.join(' OR '), *sql_params).uniq
 -
++      where(sql_conds.join(' OR '), *sql_params)
+     else
+       # At least one user is admin, so don't bother to apply any restrictions.
+       self
      end
-     where("?=? OR #{table_name}.owner_uuid in (?) OR #{table_name}.uuid=? OR #{table_name}.uuid IN (SELECT head_uuid FROM links WHERE link_class='permission' AND tail_uuid IN (#{sanitized_uuid_list})) #{or_references_me}",
-           true, user.is_admin,
-           uuid_list,
-           user.uuid)
 -
    end
  
    def logged_attributes

commit 6a53a3c5d97d33586567f8df082a725f7d229327
Author: Tom Clegg <tom at curoverse.com>
Date:   Thu May 1 13:11:22 2014 -0400

    Add partial unique index

diff --git a/services/api/db/migrate/20140501165548_add_unique_name_index_to_links.rb b/services/api/db/migrate/20140501165548_add_unique_name_index_to_links.rb
new file mode 100644
index 0000000..0195cf0
--- /dev/null
+++ b/services/api/db/migrate/20140501165548_add_unique_name_index_to_links.rb
@@ -0,0 +1,6 @@
+class AddUniqueNameIndexToLinks < ActiveRecord::Migration
+  def change
+    # todo: add "check (link_class is not 'name' or name is not null)"
+    add_index :links, [:tail_uuid, :name], where: "link_class='name'", unique: true
+  end
+end

commit da67c81ff6cc5fd540c0725de1c8208c2d8933be
Merge: 9cfbcdf 840e7d7
Author: Tom Clegg <tom at curoverse.com>
Date:   Wed Apr 30 14:14:15 2014 -0400

    Merge branch 'master' into 2640-folder-api


commit 9cfbcdf804974812b1a4ec514f5dc7902fce6137
Author: Tom Clegg <tom at curoverse.com>
Date:   Tue Apr 29 17:00:20 2014 -0400

    Rename owned_items to contents, remove user method, update docs.

diff --git a/apps/workbench/app/models/group.rb b/apps/workbench/app/models/group.rb
index 0004c88..c628b56 100644
--- a/apps/workbench/app/models/group.rb
+++ b/apps/workbench/app/models/group.rb
@@ -1,6 +1,6 @@
 class Group < ArvadosBase
-  def owned_items params={}
-    res = $arvados_api_client.api self.class, "/#{self.uuid}/owned_items", {
+  def contents params={}
+    res = $arvados_api_client.api self.class, "/#{self.uuid}/contents", {
       _method: 'GET'
     }.merge(params)
     ret = ArvadosResourceList.new
diff --git a/apps/workbench/app/models/user.rb b/apps/workbench/app/models/user.rb
index 58c1d3f..44d615b 100644
--- a/apps/workbench/app/models/user.rb
+++ b/apps/workbench/app/models/user.rb
@@ -17,15 +17,6 @@ class User < ArvadosBase
                              end
   end
 
-  def owned_items params={}
-    res = $arvados_api_client.api self.class, "/#{self.uuid}/owned_items", {
-      _method: 'GET'
-    }.merge(params)
-    ret = ArvadosResourceList.new
-    ret.results = $arvados_api_client.unpack_api_response(res)
-    ret
-  end
-
   def full_name
     (self.first_name || "") + " " + (self.last_name || "")
   end
diff --git a/apps/workbench/test/unit/group_test.rb b/apps/workbench/test/unit/group_test.rb
index 1e7d087..4a7144f 100644
--- a/apps/workbench/test/unit/group_test.rb
+++ b/apps/workbench/test/unit/group_test.rb
@@ -1,27 +1,27 @@
 require 'test_helper'
 
 class GroupTest < ActiveSupport::TestCase
-  test "get owned_items with names" do
+  test "get contents with names" do
     use_token :active
     oi = Group.
       find(api_fixture('groups')['asubfolder']['uuid']).
-      owned_items(include_linked: true)
+      contents(include_linked: true)
     assert_operator(0, :<, oi.count,
                     "Expected to find some items belonging to :active user")
     assert_operator(0, :<, oi.items_available,
-                    "Expected owned_items response to have items_available > 0")
+                    "Expected contents response to have items_available > 0")
     assert_operator(0, :<, oi.result_links.count,
-                    "Expected to receive name links with owned_items response")
+                    "Expected to receive name links with contents response")
     oi_uuids = oi.collect { |i| i['uuid'] }
 
     expect_uuid = api_fixture('specimens')['in_asubfolder']['uuid']
     assert_includes(oi_uuids, expect_uuid,
-                    "Expected '#{expect_uuid}' in asubfolder's owned_items")
+                    "Expected '#{expect_uuid}' in asubfolder's contents")
 
     expect_uuid = api_fixture('specimens')['in_afolder_linked_from_asubfolder']['uuid']
     expect_name = api_fixture('links')['specimen_is_in_two_folders']['name']
     assert_includes(oi_uuids, expect_uuid,
-                    "Expected '#{expect_uuid}' in asubfolder's owned_items")
+                    "Expected '#{expect_uuid}' in asubfolder's contents")
     assert_equal(expect_name, oi.name_for(expect_uuid),
                  "Expected name_for '#{expect_uuid}' to be '#{expect_name}'")
   end
diff --git a/apps/workbench/test/unit/user_test.rb b/apps/workbench/test/unit/user_test.rb
index d827651..20cde7e 100644
--- a/apps/workbench/test/unit/user_test.rb
+++ b/apps/workbench/test/unit/user_test.rb
@@ -1,16 +1,4 @@
 require 'test_helper'
 
 class UserTest < ActiveSupport::TestCase
-  test "get owned_items" do
-    use_token :active
-    oi = User.find(api_fixture('users')['active']['uuid']).owned_items
-    assert_operator(0, :<, oi.count,
-                    "Expected to find some items belonging to :active user")
-    assert_operator(0, :<, oi.items_available,
-                    "Expected owned_items response to have items_available > 0")
-    oi_uuids = oi.collect { |i| i['uuid'] }
-    expect = api_fixture('specimens')['owned_by_active_user']['uuid']
-    assert_includes(oi_uuids, expect,
-                    "Expected active user's owned_items to include #{expect}")
-  end
 end
diff --git a/doc/api/methods/groups.html.textile.liquid b/doc/api/methods/groups.html.textile.liquid
index 9394d76..478662e 100644
--- a/doc/api/methods/groups.html.textile.liquid
+++ b/doc/api/methods/groups.html.textile.liquid
@@ -14,6 +14,20 @@ API endpoint base: @https://{{ site.arvados_api_host }}/arvados/v1/groups@
 Required arguments are displayed in %{background:#ccffcc}green%.
 
 
+h2. contents
+
+Retrieve a list of items which are associated with the given group by ownership (i.e., the group owns the item) or a "name" link (i.e., a "name" link referencing the item).
+
+Arguments:
+
+table(table table-bordered table-condensed).
+|_. Argument |_. Type |_. Description |_. Location |_. Example |
+{background:#ccffcc}.|uuid|string|The UUID of the group in question.|path||
+|include_linked|boolean|If false, results will only include items whose @owner_uuid@ attribute is the specified group. If true, results will additionally include items for which a "name" link exists.|path|{white-space:nowrap}. @false@ (default)
+ at true@|
+
+If @include_linked@ is @true@, the @"links"@ field in the response will contain the "name" links referencing the objects in the @"items"@ field.
+
 h2. create
 
 Create a new Group.
@@ -56,18 +70,6 @@ table(table table-bordered table-condensed).
 |order|string|Order in which to return matching groups.|query||
 |filters|array|Conditions for filtering groups.|query||
 
-h2. owned_items
-
-Retrieve a list of items which are owned by the given group.
-
-Arguments:
-
-table(table table-bordered table-condensed).
-|_. Argument |_. Type |_. Description |_. Location |_. Example |
-{background:#ccffcc}.|uuid|string|The UUID of the group in question.|path||
-|include_linked|boolean|If true, results will also include items on which the given group has _can_manage_ permission, even if they are owned by different users/groups.|path|{white-space:nowrap}. @false@ (default)
- at true@|
-
 h2. show
 
 show groups
diff --git a/doc/api/methods/users.html.textile.liquid b/doc/api/methods/users.html.textile.liquid
index 65bd696..59fa856 100644
--- a/doc/api/methods/users.html.textile.liquid
+++ b/doc/api/methods/users.html.textile.liquid
@@ -74,18 +74,6 @@ table(table table-bordered table-condensed).
 |order|string|Order in which to return matching users.|query||
 |filters|array|Conditions for filtering users.|query||
 
-h2. owned_items
-
-Retrieve a list of items which are owned by the given user.
-
-Arguments:
-
-table(table table-bordered table-condensed).
-|_. Argument |_. Type |_. Description |_. Location |_. Example |
-{background:#ccffcc}.|uuid|string|The UUID of the user in question.|path||
-|include_linked|boolean|If true, results will also include items on which the given user has _can_manage_ permission, even if they are owned by different users/groups.|path|{white-space:nowrap}. @false@ (default)
- at true@|
-
 h2. show
 
 show users
diff --git a/services/api/app/controllers/application_controller.rb b/services/api/app/controllers/application_controller.rb
index d9f01f5..916e597 100644
--- a/services/api/app/controllers/application_controller.rb
+++ b/services/api/app/controllers/application_controller.rb
@@ -13,9 +13,9 @@ class ApplicationController < ActionController::Base
   before_filter :find_object_by_uuid, :except => [:index, :create,
                                                   :render_error,
                                                   :render_not_found]
-  before_filter :load_limit_offset_order_params, only: [:index, :owned_items]
-  before_filter :load_where_param, only: [:index, :owned_items]
-  before_filter :load_filters_param, only: [:index, :owned_items]
+  before_filter :load_limit_offset_order_params, only: [:index, :contents]
+  before_filter :load_where_param, only: [:index, :contents]
+  before_filter :load_filters_param, only: [:index, :contents]
   before_filter :find_objects_for_index, :only => :index
   before_filter :reload_object_before_update, :only => :update
   before_filter :render_404_if_no_object, except: [:index, :create,
@@ -59,7 +59,7 @@ class ApplicationController < ActionController::Base
     show
   end
 
-  def self._owned_items_requires_parameters
+  def self._contents_requires_parameters
     _index_requires_parameters.
       merge({
               include_linked: {
@@ -68,7 +68,7 @@ class ApplicationController < ActionController::Base
             })
   end
 
-  def owned_items
+  def contents
     all_objects = []
     all_available = 0
 
@@ -95,7 +95,7 @@ class ApplicationController < ActionController::Base
         cond_sql = "#{klass.table_name}.owner_uuid = ?"
         cond_params = [@object.uuid]
         if params[:include_linked]
-          cond_sql += " OR #{klass.table_name}.uuid IN (SELECT head_uuid FROM links WHERE link_class=#{klass.sanitize 'name'} AND links.owner_uuid=#{klass.sanitize @object.uuid} AND links.tail_uuid=#{klass.sanitize @object.uuid})"
+          cond_sql += " OR #{klass.table_name}.uuid IN (SELECT head_uuid FROM links WHERE link_class=#{klass.sanitize 'name'} AND links.tail_uuid=#{klass.sanitize @object.uuid})"
         end
         @objects = @objects.where(cond_sql, *cond_params).order("#{klass.table_name}.uuid")
         @limit = limit_all - all_objects.count
diff --git a/services/api/config/routes.rb b/services/api/config/routes.rb
index b229511..46f0e7b 100644
--- a/services/api/config/routes.rb
+++ b/services/api/config/routes.rb
@@ -15,7 +15,7 @@ Server::Application.routes.draw do
         get 'used_by', on: :member
       end
       resources :groups do
-        get 'owned_items', on: :member
+        get 'contents', on: :member
       end
       resources :humans
       resources :job_tasks
@@ -50,7 +50,6 @@ Server::Application.routes.draw do
         post 'activate', on: :member
         post 'setup', on: :collection
         post 'unsetup', on: :member
-        get 'owned_items', on: :member
       end
       resources :virtual_machines do
         get 'logins', on: :member
diff --git a/services/api/test/fixtures/links.yml b/services/api/test/fixtures/links.yml
index 60d822e..c58e273 100644
--- a/services/api/test/fixtures/links.yml
+++ b/services/api/test/fixtures/links.yml
@@ -304,6 +304,34 @@ specimen_is_in_two_folders:
   name: "I'm in a subfolder, too"
   properties: {}
 
+template_name_in_afolder:
+  uuid: zzzzz-o0j2j-4kpwf3d6rwkeqhl
+  owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz
+  created_at: 2014-04-29 16:47:26 -0400
+  modified_by_client_uuid: zzzzz-ozdt8-brczlopd8u8d0jr
+  modified_by_user_uuid: zzzzz-tpzed-xurymjxw79nv3jz
+  modified_at: 2014-04-29 16:47:26 -0400
+  updated_at: 2014-04-29 16:47:26 -0400
+  tail_uuid: zzzzz-j7d0g-v955i6s2oi1cbso
+  head_uuid: zzzzz-p5p6p-aox0k0ofxrystgw
+  link_class: name
+  name: "I'm a template in a folder"
+  properties: {}
+
+job_name_in_afolder:
+  uuid: zzzzz-o0j2j-1kt6dppqcxbl1yt
+  owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz
+  created_at: 2014-04-29 16:47:26 -0400
+  modified_by_client_uuid: zzzzz-ozdt8-brczlopd8u8d0jr
+  modified_by_user_uuid: zzzzz-tpzed-xurymjxw79nv3jz
+  modified_at: 2014-04-29 16:47:26 -0400
+  updated_at: 2014-04-29 16:47:26 -0400
+  tail_uuid: zzzzz-j7d0g-v955i6s2oi1cbso
+  head_uuid: zzzzz-8i9sb-pshmckwoma9plh7
+  link_class: name
+  name: "I'm a job in a folder"
+  properties: {}
+
 foo_collection_tag:
   uuid: zzzzz-o0j2j-eedahfaho8aphiv
   owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz
diff --git a/services/api/test/functional/arvados/v1/groups_controller_test.rb b/services/api/test/functional/arvados/v1/groups_controller_test.rb
index 4b041b6..e7f0371 100644
--- a/services/api/test/functional/arvados/v1/groups_controller_test.rb
+++ b/services/api/test/functional/arvados/v1/groups_controller_test.rb
@@ -56,18 +56,22 @@ class Arvados::V1::GroupsControllerTest < ActionController::TestCase
 
   test 'get group-owned objects' do
     authorize_with :active
-    get :owned_items, {
+    get :contents, {
       id: groups(:afolder).uuid,
       format: :json,
+      include_linked: true,
     }
     assert_response :success
     assert_operator 2, :<=, json_response['items_available']
     assert_operator 2, :<=, json_response['items'].count
+    kinds = json_response['items'].collect { |i| i['kind'] }.uniq
+    expect_kinds = %w'arvados#group arvados#specimen arvados#pipelineTemplate arvados#job'
+    assert_equal expect_kinds, (expect_kinds & kinds)
   end
 
   test 'get group-owned objects with limit' do
     authorize_with :active
-    get :owned_items, {
+    get :contents, {
       id: groups(:afolder).uuid,
       limit: 1,
       format: :json,
@@ -79,7 +83,7 @@ class Arvados::V1::GroupsControllerTest < ActionController::TestCase
 
   test 'get group-owned objects with limit and offset' do
     authorize_with :active
-    get :owned_items, {
+    get :contents, {
       id: groups(:afolder).uuid,
       limit: 1,
       offset: 12345,
@@ -92,7 +96,7 @@ class Arvados::V1::GroupsControllerTest < ActionController::TestCase
 
   test 'get group-owned objects with additional filter matching nothing' do
     authorize_with :active
-    get :owned_items, {
+    get :contents, {
       id: groups(:afolder).uuid,
       filters: [['uuid', 'in', ['foo_not_a_uuid','bar_not_a_uuid']]],
       format: :json,
@@ -105,7 +109,7 @@ class Arvados::V1::GroupsControllerTest < ActionController::TestCase
   test 'get group-owned objects without include_linked' do
     unexpected_uuid = specimens(:in_afolder_linked_from_asubfolder).uuid
     authorize_with :active
-    get :owned_items, {
+    get :contents, {
       id: groups(:asubfolder).uuid,
       format: :json,
     }
@@ -117,7 +121,7 @@ class Arvados::V1::GroupsControllerTest < ActionController::TestCase
   test 'get group-owned objects with include_linked' do
     expected_uuid = specimens(:in_afolder_linked_from_asubfolder).uuid
     authorize_with :active
-    get :owned_items, {
+    get :contents, {
       id: groups(:asubfolder).uuid,
       include_linked: true,
       format: :json,
@@ -140,4 +144,66 @@ class Arvados::V1::GroupsControllerTest < ActionController::TestCase
     assert(found_specimen_name,
            "Expected to find name '#{expected_name}' in response")
   end
+
+  [false, true].each do |inc_ind|
+    test "get all pages of group-owned #{'and -linked ' if inc_ind}objects" do
+      authorize_with :active
+      limit = 5
+      offset = 0
+      items_available = nil
+      uuid_received = {}
+      owner_received = {}
+      while true
+        # Behaving badly here, using the same controller multiple
+        # times within a test.
+        @json_response = nil
+        get :contents, {
+          id: groups(:afolder).uuid,
+          include_linked: inc_ind,
+          limit: limit,
+          offset: offset,
+          format: :json,
+        }
+        assert_response :success
+        assert_operator(0, :<, json_response['items'].count,
+                        "items_available=#{items_available} but received 0 "\
+                        "items with offset=#{offset}")
+        items_available ||= json_response['items_available']
+        assert_equal(items_available, json_response['items_available'],
+                     "items_available changed between page #{offset/limit} "\
+                     "and page #{1+offset/limit}")
+        json_response['items'].each do |item|
+          uuid = item['uuid']
+          assert_equal(nil, uuid_received[uuid],
+                       "Received '#{uuid}' again on page #{1+offset/limit}")
+          uuid_received[uuid] = true
+          owner_received[item['owner_uuid']] = true
+          offset += 1
+          if not inc_ind
+            assert_equal groups(:afolder).uuid, item['owner_uuid']
+          end
+        end
+        break if offset >= items_available
+      end
+      if inc_ind
+        assert_operator 0, :<, (json_response.keys - [users(:active).uuid]).count,
+        "Set include_linked=true but did not receive any non-owned items"
+      end
+    end
+  end
+
+  %w(offset limit).each do |arg|
+    ['foo', '', '1234five', '0x10', '-8'].each do |val|
+      test "Raise error on bogus #{arg} parameter #{val.inspect}" do
+        authorize_with :active
+        get :contents, {
+          :id => groups(:afolder).uuid,
+          :format => :json,
+          arg => val,
+        }
+        assert_response 422
+      end
+    end
+  end
+
 end
diff --git a/services/api/test/functional/arvados/v1/users_controller_test.rb b/services/api/test/functional/arvados/v1/users_controller_test.rb
index e1ebbb2..1fefcb6 100644
--- a/services/api/test/functional/arvados/v1/users_controller_test.rb
+++ b/services/api/test/functional/arvados/v1/users_controller_test.rb
@@ -908,80 +908,4 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase
                                tail_uuid: system_group_uuid,
                                head_uuid: user_uuid).count
   end
-
-  test 'get user-owned objects' do
-    authorize_with :active
-    get :owned_items, {
-      id: users(:active).uuid,
-      limit: 500,
-      format: :json,
-    }
-    assert_response :success
-    assert_operator 2, :<=, json_response['items_available']
-    assert_operator 2, :<=, json_response['items'].count
-    kinds = json_response['items'].collect { |i| i['kind'] }.uniq
-    expect_kinds = %w'arvados#group arvados#specimen arvados#pipelineTemplate arvados#job'
-    assert_equal expect_kinds, (expect_kinds & kinds)
-  end
-
-  [false, true].each do |inc_ind|
-    test "get all pages of user-owned #{'and -linked ' if inc_ind}objects" do
-      authorize_with :active
-      limit = 5
-      offset = 0
-      items_available = nil
-      uuid_received = {}
-      owner_received = {}
-      while true
-        # Behaving badly here, using the same controller multiple
-        # times within a test.
-        @json_response = nil
-        get :owned_items, {
-          id: users(:active).uuid,
-          include_linked: inc_ind,
-          limit: limit,
-          offset: offset,
-          format: :json,
-        }
-        assert_response :success
-        assert_operator(0, :<, json_response['items'].count,
-                        "items_available=#{items_available} but received 0 "\
-                        "items with offset=#{offset}")
-        items_available ||= json_response['items_available']
-        assert_equal(items_available, json_response['items_available'],
-                     "items_available changed between page #{offset/limit} "\
-                     "and page #{1+offset/limit}")
-        json_response['items'].each do |item|
-          uuid = item['uuid']
-          assert_equal(nil, uuid_received[uuid],
-                       "Received '#{uuid}' again on page #{1+offset/limit}")
-          uuid_received[uuid] = true
-          owner_received[item['owner_uuid']] = true
-          offset += 1
-          if not inc_ind
-            assert_equal users(:active).uuid, item['owner_uuid']
-          end
-        end
-        break if offset >= items_available
-      end
-      if inc_ind
-        assert_operator 0, :<, (json_response.keys - [users(:active).uuid]).count,
-        "Set include_linked=true but did not receive any non-owned items"
-      end
-    end
-  end
-
-  %w(offset limit).each do |arg|
-    ['foo', '', '1234five', '0x10', '-8'].each do |val|
-      test "Raise error on bogus #{arg} parameter #{val.inspect}" do
-        authorize_with :active
-        get :owned_items, {
-          :id => users(:active).uuid,
-          :format => :json,
-          arg => val,
-        }
-        assert_response 422
-      end
-    end
-  end
 end

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


hooks/post-receive
-- 




More information about the arvados-commits mailing list