Merge branch '21535-multi-wf-delete'
[arvados.git] / services / api / test / functional / arvados / v1 / containers_controller_test.rb
index 208c1ccfdc0c0b1bfae719791205af90f738a10f..07fa5c3211c3b74f3ba5ccfa0756ecf57566322f 100644 (file)
@@ -1,9 +1,13 @@
+# Copyright (C) The Arvados Authors. All rights reserved.
+#
+# SPDX-License-Identifier: AGPL-3.0
+
 require 'test_helper'
 
 class Arvados::V1::ContainersControllerTest < ActionController::TestCase
   test 'create' do
     authorize_with :system_user
-    post :create, {
+    post :create, params: {
       container: {
         command: ['echo', 'hello'],
         container_image: 'test',
@@ -16,7 +20,7 @@ class Arvados::V1::ContainersControllerTest < ActionController::TestCase
   [Container::Queued, Container::Complete].each do |state|
     test "cannot get auth in #{state} state" do
       authorize_with :dispatch1
-      get :auth, id: containers(:queued).uuid
+      get :auth, params: {id: containers(:queued).uuid}
       assert_response 403
     end
   end
@@ -24,100 +28,165 @@ class Arvados::V1::ContainersControllerTest < ActionController::TestCase
   test 'cannot get auth with wrong token' do
     authorize_with :dispatch1
     c = containers(:queued)
-    assert c.update_attributes(state: Container::Locked), show_errors(c)
+    assert c.lock, show_errors(c)
 
     authorize_with :system_user
-    get :auth, id: c.uuid
+    get :auth, params: {id: c.uuid}
     assert_response 403
   end
 
   test 'get auth' do
     authorize_with :dispatch1
     c = containers(:queued)
-    assert c.update_attributes(state: Container::Locked), show_errors(c)
-    get :auth, id: c.uuid
+    assert c.lock, show_errors(c)
+    get :auth, params: {id: c.uuid}
     assert_response :success
     assert_operator 32, :<, json_response['api_token'].length
     assert_equal 'arvados#apiClientAuthorization', json_response['kind']
   end
 
-  test 'no auth in container response' do
+  test 'no auth or secret_mounts in container response' do
     authorize_with :dispatch1
     c = containers(:queued)
-    assert c.update_attributes(state: Container::Locked), show_errors(c)
-    get :show, id: c.uuid
+    assert c.lock, show_errors(c)
+    get :show, params: {id: c.uuid}
     assert_response :success
     assert_nil json_response['auth']
+    assert_nil json_response['secret_mounts']
   end
 
-  test "lock and unlock container" do
-    # lock container
+  test "lock container" do
     authorize_with :dispatch1
-    post :lock, {id: containers(:queued).uuid}
+    uuid = containers(:queued).uuid
+    post :lock, params: {id: uuid}
     assert_response :success
-    container = Container.where(uuid: containers(:queued).uuid).first
+    assert_nil json_response['mounts']
+    assert_nil json_response['command']
+    assert_not_nil json_response['auth_uuid']
+    assert_not_nil json_response['locked_by_uuid']
+    assert_equal containers(:queued).uuid, json_response['uuid']
+    assert_equal 'Locked', json_response['state']
+    assert_equal containers(:queued).priority, json_response['priority']
+
+    container = Container.where(uuid: uuid).first
     assert_equal 'Locked', container.state
     assert_not_nil container.locked_by_uuid
     assert_not_nil container.auth_uuid
+  end
 
-    # unlock container
-    @test_counter = 0  # Reset executed action counter
-    @controller = Arvados::V1::ContainersController.new
+  test "unlock container" do
     authorize_with :dispatch1
-    post :unlock, {id: container.uuid}
+    uuid = containers(:locked).uuid
+    post :unlock, params: {id: uuid}
     assert_response :success
-    container = Container.where(uuid: container.uuid).first
+    assert_nil json_response['mounts']
+    assert_nil json_response['command']
+    assert_nil json_response['auth_uuid']
+    assert_nil json_response['locked_by_uuid']
+    assert_equal containers(:locked).uuid, json_response['uuid']
+    assert_equal 'Queued', json_response['state']
+    assert_equal containers(:locked).priority, json_response['priority']
+
+    container = Container.where(uuid: uuid).first
     assert_equal 'Queued', container.state
     assert_nil container.locked_by_uuid
     assert_nil container.auth_uuid
   end
 
-  def create_new_container attrs={}
-    attrs = {
-      command: ['echo', 'foo'],
-      container_image: 'img',
-      output_path: '/tmp',
-      priority: 1,
-      runtime_constraints: {"vcpus" => 1, "ram" => 1},
-    }
-    c = Container.new attrs.merge(attrs)
-    c.save!
-    cr = ContainerRequest.new attrs.merge(attrs)
-    cr.save!
-    assert cr.update_attributes(container_uuid: c.uuid,
-                                state: ContainerRequest::Committed,
-                               ), show_errors(cr)
-    return c
+  test "unlock container locked by different dispatcher" do
+    authorize_with :dispatch2
+    uuid = containers(:locked).uuid
+    post :unlock, params: {id: uuid}
+    assert_response 403
   end
 
   [
-    [['Queued', :success], ['Locked', :success]],
-    [['Locked', :success], ['Locked', 422]],
-    [['Locked', :success], ['Queued', :success]],
-    [['Locked', :success], ['Running', :success], ['Queued', 422]],
-  ].each do |transitions|
-    test "lock and unlock state transitions #{transitions}" do
+    [:queued, :lock, :success, 'Locked'],
+    [:queued, :unlock, 422, 'Queued'],
+    [:locked, :lock, 422, 'Locked'],
+    [:running, :lock, 422, 'Running'],
+    [:running, :unlock, 422, 'Running'],
+  ].each do |fixture, action, response, state|
+    test "state transitions from #{fixture} to #{action}" do
       authorize_with :dispatch1
+      uuid = containers(fixture).uuid
+      post action, params: {id: uuid}
+      assert_response response
+      assert_equal state, Container.where(uuid: uuid).first.state
+    end
+  end
 
-      container = create_new_container()
+  test 'get current container for token' do
+    authorize_with :running_container_auth
+    get :current
+    assert_response :success
+    assert_equal containers(:running).uuid, json_response['uuid']
+  end
 
-      transitions.each do |state, status|
-        @test_counter = 0  # Reset executed action counter
-        @controller = Arvados::V1::ContainersController.new
-        authorize_with :dispatch1
+  test 'no container associated with token' do
+    authorize_with :dispatch1
+    get :current
+    assert_response 404
+  end
 
-        if state == 'Locked'
-          post :lock, {id: container.uuid}
-        elsif state == 'Queued'
-          post :unlock, {id: container.uuid}
-        else
-          container.update_attributes!(state: state)
-        end
-        assert_response status
+  test 'try get current container, no token' do
+    get :current
+    assert_response 401
+  end
 
-        container = Container.where(uuid: container['uuid']).first
-        assert_equal state, container.state if status == :success
+  [
+    [true, :running_container_auth],
+    [false, :dispatch2],
+    [false, :admin],
+    [false, :active],
+  ].each do |expect_success, auth|
+    test "get secret_mounts with #{auth} token" do
+      authorize_with auth
+      get :secret_mounts, params: {id: containers(:running).uuid}
+      if expect_success
+        assert_response :success
+        assert_equal "42\n", json_response["secret_mounts"]["/secret/6x9"]["content"]
+      else
+        assert_response 403
       end
     end
   end
+
+  test 'get runtime_token auth' do
+    authorize_with :dispatch2
+    c = containers(:runtime_token)
+    get :auth, params: {id: c.uuid}
+    assert_response :success
+    assert_equal "v2/#{json_response['uuid']}/#{json_response['api_token']}", api_client_authorizations(:container_runtime_token).token
+    assert_equal 'arvados#apiClientAuthorization', json_response['kind']
+  end
+
+  test 'update_priority' do
+    ActiveRecord::Base.connection.execute "update containers set priority=0 where uuid='#{containers(:running).uuid}'"
+    authorize_with :admin
+    post :update_priority, params: {id: containers(:running).uuid}
+    assert_response :success
+    assert_not_equal 0, Container.find_by_uuid(containers(:running).uuid).priority
+  end
+
+  test 'update runtime_status, runtime_status is toplevel key' do
+    authorize_with :dispatch1
+    c = containers(:running)
+    patch :update, params: {id: containers(:running).uuid, runtime_status: {activity: "foo", activityDetail: "bar"}}
+    assert_response :success
+  end
+
+  test 'update runtime_status, container is toplevel key' do
+    authorize_with :dispatch1
+    c = containers(:running)
+    patch :update, params: {id: containers(:running).uuid, container: {runtime_status: {activity: "foo", activityDetail: "bar"}}}
+    assert_response :success
+  end
+
+  test 'update state, state is toplevel key' do
+    authorize_with :dispatch1
+    c = containers(:running)
+    patch :update, params: {id: containers(:running).uuid, state: "Complete", runtime_status: {activity: "finishing"}}
+    assert_response :success
+  end
 end