Merge branch 'master' into 2596-refactor-pipeline-create
authorTom Clegg <tom@curoverse.com>
Tue, 15 Apr 2014 17:47:52 +0000 (13:47 -0400)
committerTom Clegg <tom@curoverse.com>
Tue, 15 Apr 2014 17:47:52 +0000 (13:47 -0400)
Conflicts:
apps/workbench/test/functional/users_controller_test.rb
services/api/app/controllers/arvados/v1/jobs_controller.rb
services/api/test/functional/arvados/v1/links_controller_test.rb

1  2 
apps/workbench/app/models/arvados_base.rb
services/api/app/controllers/arvados/v1/jobs_controller.rb
services/api/app/controllers/arvados/v1/nodes_controller.rb
services/api/app/controllers/arvados/v1/users_controller.rb
services/api/app/models/arvados_model.rb
services/api/test/fixtures/links.yml
services/api/test/functional/arvados/v1/links_controller_test.rb
services/api/test/unit/user_notifier_test.rb

index 0a4e308c7700479234dfb2c13a7584f8e6fb9a73,3a9f62406e1738439b81370b19ed716855cd45b1..336877bb98fa1853d1ccc8ac33ce49947846f2f3
@@@ -28,25 -27,18 +28,24 @@@ class Arvados::V1::JobsController < App
                                            script_version: r).
          each do |j|
          if j.nondeterministic != true and
-             j.success != false and
-             !j.cancelled_at and
+             ((j.success == true and j.output != nil) or j.running == true) and
              j.script_parameters == resource_attrs[:script_parameters]
-           if j.success.nil?
 -          # Record the first job in the list
 -          if !@object
 -            @object = j
 -          end
 -          # Ensure that all candidate jobs actually did produce the same output
 -          if @object.output != j.output
 -            @object = nil
 -            break
++          if j.running
 +            # We'll use this if we don't find a job that has completed
 +            @incomplete_job ||= j
 +          else
 +            # Record the first job in the list
 +            if !@object
 +              @object = j
 +            end
 +            # Ensure that all candidate jobs actually did produce the same output
 +            if @object.output != j.output
 +              @object = nil
 +              break
 +            end
            end
          end
 +        @object ||= @incomplete_job
          if @object
            return show
          end
index 1461eeccaa1481fc568eb2a0a8d91a8be8b18562,4415a511631df1b4646b974c7595816b9f9db71d..eda8b0748ca01b87934255e1f5d807849472b8d6
@@@ -13,18 -13,21 +13,21 @@@ class Arvados::V1::NodesController < Ap
    def self._ping_requires_parameters
      { ping_secret: true }
    end
    def ping
-     @object = Node.where(uuid: (params[:id] || params[:uuid])).first
-     if !@object
-       return render_not_found
-     end
-     @object.ping({ ip: params[:local_ipv4] || request.env['REMOTE_ADDR'],
-                    ping_secret: params[:ping_secret],
-                    ec2_instance_id: params[:instance_id] })
-     if @object.info[:ping_secret] == params[:ping_secret]
-       render json: @object.as_api_response(:superuser)
-     else
-       raise "Invalid ping_secret after ping"
 -    act_as_system_user do 
++    act_as_system_user do
+       @object = Node.where(uuid: (params[:id] || params[:uuid])).first
+       if !@object
+         return render_not_found
+       end
+       @object.ping({ ip: params[:local_ipv4] || request.env['REMOTE_ADDR'],
+                      ping_secret: params[:ping_secret],
+                      ec2_instance_id: params[:instance_id] })
+       if @object.info[:ping_secret] == params[:ping_secret]
+         render json: @object.as_api_response(:superuser)
+       else
+         raise "Invalid ping_secret after ping"
+       end
      end
    end
  
index 58661a0e9a3c970712eccc054b8d2e9060dc249e,08368cb5ef110d6181dcdd0f4f696adacba48eee..f5255bc350dbc6c8fdd574f9ad8d5f67453d164d
@@@ -141,4 -145,12 +145,12 @@@ class Arvados::V1::UsersController < Ap
      show
    end
  
 -  def self._setup_requires_parameters 
+   protected
 -    }  
++  def self._setup_requires_parameters
+     {
+       send_notification_email: { type: 'boolean', required: true },
++    }
+   end
  end
index a04f74e28797fdb929bb4699ab5a2ed927831e82,e3f6e2bcfbec47578d33601b83c775bc3e74de8b..fc3f23d3da94506b995ae830af53b0775defe8a3
@@@ -313,19 -275,5 +275,17 @@@ testusergroup_can_manage_active_user
    tail_uuid: zzzzz-j7d0g-48foin4vonvc2at
    link_class: permission
    name: can_manage
-   head_kind: arvados#user
    head_uuid: zzzzz-tpzed-xurymjxw79nv3jz
    properties: {}
 +
 +test_timestamps:
 +  uuid: zzzzz-o0j2j-4abnk2w5t86x4uc
 +  owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz
 +  created_at: 2014-04-15 13:17:14 -0400
 +  modified_by_client_uuid: zzzzz-ozdt8-brczlopd8u8d0jr
 +  modified_by_user_uuid: zzzzz-tpzed-xurymjxw79nv3jz
 +  modified_at: 2014-04-15 13:17:14 -0400
 +  updated_at: 2014-04-15 13:17:14 -0400
 +  link_class: test
 +  name: test
 +  properties: {}
index 13877fcf8d1a82ba74f249b9987acedcd5c2a07c,f4d65c19921e4f4434c94257620fce6a0b974752..4726e0119a7c8a5e0f43d11f30857d5e613a1a7d
@@@ -22,40 -20,187 +20,224 @@@ class Arvados::V1::LinksControllerTest 
      end
    end
  
 +  %w(created_at updated_at modified_at).each do |attr|
 +    {nil: nil, bogus: 2.days.ago}.each do |bogustype, bogusvalue|
 +      test "cannot set #{bogustype} #{attr} in create" do
 +        authorize_with :active
 +        post :create, {
 +          link: {
 +            properties: {},
 +            link_class: 'test',
 +            name: 'test',
 +          }.merge(attr => bogusvalue)
 +        }
 +        assert_response :success
 +        resp = JSON.parse @response.body
 +        assert_in_delta Time.now, Time.parse(resp[attr]), 3.0
 +      end
 +      test "cannot set #{bogustype} #{attr} in update" do
 +        really_created_at = links(:test_timestamps).created_at
 +        authorize_with :active
 +        put :update, {
 +          id: links(:test_timestamps).uuid,
 +          link: {
 +            :properties => {test: 'test'},
 +            attr => bogusvalue
 +          }
 +        }
 +        assert_response :success
 +        resp = JSON.parse @response.body
 +        case attr
 +        when 'created_at'
 +          assert_in_delta really_created_at, Time.parse(resp[attr]), 0.001
 +        else
 +          assert_in_delta Time.now, Time.parse(resp[attr]), 3.0
 +        end
 +      end
 +    end
 +  end
++
+   test "head must exist" do
+     link = {
+       link_class: 'test',
+       name: 'stuff',
+       tail_uuid: users(:active).uuid,
+       head_uuid: 'zzzzz-tpzed-xyzxyzxerrrorxx'
+     }
+     authorize_with :admin
+     post :create, link: link
+     assert_response 422
+   end
+   test "tail must exist" do
+     link = {
+       link_class: 'test',
+       name: 'stuff',
+       head_uuid: users(:active).uuid,
+       tail_uuid: 'zzzzz-tpzed-xyzxyzxerrrorxx'
+     }
+     authorize_with :admin
+     post :create, link: link
+     assert_response 422
+   end
+   test "head and tail exist, head_kind and tail_kind are returned" do
+     link = {
+       link_class: 'test',
+       name: 'stuff',
+       head_uuid: users(:active).uuid,
+       tail_uuid: users(:spectator).uuid,
+     }
+     authorize_with :admin
+     post :create, link: link
+     assert_response :success
+     l = JSON.parse(@response.body)
+     assert 'arvados#user', l['head_kind']
+     assert 'arvados#user', l['tail_kind']
+   end
+   test "can supply head_kind and tail_kind without error" do
+     link = {
+       link_class: 'test',
+       name: 'stuff',
+       head_uuid: users(:active).uuid,
+       tail_uuid: users(:spectator).uuid,
+       head_kind: "arvados#user",
+       tail_kind: "arvados#user",
+     }
+     authorize_with :admin
+     post :create, link: link
+     assert_response :success
+     l = JSON.parse(@response.body)
+     assert 'arvados#user', l['head_kind']
+     assert 'arvados#user', l['tail_kind']
+   end
+   test "tail must be visible by user" do
+     link = {
+       link_class: 'test',
+       name: 'stuff',
+       head_uuid: users(:active).uuid,
+       tail_uuid: virtual_machines(:testvm).uuid
+     }
+     authorize_with :active
+     post :create, link: link
+     assert_response 422
+   end
+   test "filter links with 'is_a' operator" do
+     authorize_with :admin
+     get :index, {
+       filters: [ ['tail_uuid', 'is_a', 'arvados#user'] ]
+     }
+     assert_response :success
+     found = assigns(:objects)
+     assert_not_equal 0, found.count
+     assert_equal found.count, (found.select { |f| f.tail_uuid.match /[a-z0-9]{5}-tpzed-[a-z0-9]{15}/}).count
+   end
+   test "filter links with 'is_a' operator with more than one" do
+     authorize_with :admin
+     get :index, {
+       filters: [ ['tail_uuid', 'is_a', ['arvados#user', 'arvados#group'] ] ],
+     }
+     assert_response :success
+     found = assigns(:objects)
+     assert_not_equal 0, found.count
+     assert_equal found.count, (found.select { |f| f.tail_uuid.match /[a-z0-9]{5}-(tpzed|j7d0g)-[a-z0-9]{15}/}).count
+   end
+   test "filter links with 'is_a' operator with bogus type" do
+     authorize_with :admin
+     get :index, {
+       filters: [ ['tail_uuid', 'is_a', ['arvados#bogus'] ] ],
+     }
+     assert_response :success
+     found = assigns(:objects)
+     assert_equal 0, found.count
+   end
+   test "filter links with 'is_a' operator with collection" do
+     authorize_with :admin
+     get :index, {
+       filters: [ ['head_uuid', 'is_a', ['arvados#collection'] ] ],
+     }
+     assert_response :success
+     found = assigns(:objects)
+     assert_not_equal 0, found.count
+     assert_equal found.count, (found.select { |f| f.head_uuid.match /[a-f0-9]{32}\+\d+/}).count
+   end
+   test "test can still use where tail_kind" do
+     authorize_with :admin
+     get :index, {
+       where: { tail_kind: 'arvados#user' }
+     }
+     assert_response :success
+     found = assigns(:objects)
+     assert_not_equal 0, found.count
+     assert_equal found.count, (found.select { |f| f.tail_uuid.match /[a-z0-9]{5}-tpzed-[a-z0-9]{15}/}).count
+   end
+   test "test can still use where head_kind" do
+     authorize_with :admin
+     get :index, {
+       where: { head_kind: 'arvados#user' }
+     }
+     assert_response :success
+     found = assigns(:objects)
+     assert_not_equal 0, found.count
+     assert_equal found.count, (found.select { |f| f.head_uuid.match /[a-z0-9]{5}-tpzed-[a-z0-9]{15}/}).count
+   end
+   test "test can still use filter tail_kind" do
+     authorize_with :admin
+     get :index, {
+       filters: [ ['tail_kind', '=', 'arvados#user'] ]
+     }
+     assert_response :success
+     found = assigns(:objects)
+     assert_not_equal 0, found.count
+     assert_equal found.count, (found.select { |f| f.tail_uuid.match /[a-z0-9]{5}-tpzed-[a-z0-9]{15}/}).count
+   end
+   test "test can still use filter head_kind" do
+     authorize_with :admin
+     get :index, {
+       filters: [ ['head_kind', '=', 'arvados#user'] ]
+     }
+     assert_response :success
+     found = assigns(:objects)
+     assert_not_equal 0, found.count
+     assert_equal found.count, (found.select { |f| f.head_uuid.match /[a-z0-9]{5}-tpzed-[a-z0-9]{15}/}).count
+   end
+   test "head_kind matches head_uuid" do
+     link = {
+       link_class: 'test',
+       name: 'stuff',
+       head_uuid: groups(:public).uuid,
+       head_kind: "arvados#user",
+       tail_uuid: users(:spectator).uuid,
+       tail_kind: "arvados#user",
+     }
+     authorize_with :admin
+     post :create, link: link
+     assert_response 422
+   end
+   test "tail_kind matches tail_uuid" do
+     link = {
+       link_class: 'test',
+       name: 'stuff',
+       head_uuid: users(:active).uuid,
+       head_kind: "arvados#user",
+       tail_uuid: groups(:public).uuid,
+       tail_kind: "arvados#user",
+     }
+     authorize_with :admin
+     post :create, link: link
+     assert_response 422
+   end
  end
index 0000000000000000000000000000000000000000,89d10c52acc36cdaf3aaf6c36e06e3a5add1aec0..b280ae7f08c24ff322b57c347f0a4f7f8843d89f
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,24 +1,24 @@@
 - 
+ require 'test_helper'
 - 
++
+ class UserNotifierTest < ActionMailer::TestCase
+   # Send the email, then test that it got queued
+   test "account is setup" do
+     user = users :active
+     email = UserNotifier.account_is_setup user
+     assert_not_nil email
++
+     # Test the body of the sent email contains what we expect it to
+     assert_equal Rails.configuration.user_notifier_email_from, email.from.first
+     assert_equal user.email, email.to.first
+     assert_equal 'Welcome to Curoverse', email.subject
+     assert (email.body.to_s.include? 'Your Arvados account has been set up'),
+         'Expected Your Arvados account has been set up in email body'
+     assert (email.body.to_s.include? user.email),
+         'Expected user email in email body'
+     assert (email.body.to_s.include? Rails.configuration.workbench_address),
+         'Expected workbench url in email body'
+   end
+ end