Merge branch '8567-docker-migrator' refs #8567
[arvados.git] / services / api / test / unit / container_request_test.rb
index c4d1efec30802d75025c9c4560457815fea7f80b..af1d4b25fdeed5b26d55b17affeb3c552ab01646 100644 (file)
@@ -1,6 +1,9 @@
 require 'test_helper'
+require 'helpers/docker_migration_helper'
 
 class ContainerRequestTest < ActiveSupport::TestCase
+  include DockerMigrationHelper
+
   def create_minimal_req! attrs={}
     defaults = {
       command: ["echo", "foo"],
@@ -392,7 +395,8 @@ class ContainerRequestTest < ActiveSupport::TestCase
 
   test "container_image_for_container(pdh)" do
     set_user_from_auth :active
-    [:docker_image, :docker_image_1_12].each do |coll|
+    [[:docker_image, 'v1'], [:docker_image_1_12, 'v2']].each do |coll, ver|
+      Rails.configuration.docker_image_formats = [ver]
       pdh = collections(coll).portable_data_hash
       cr = ContainerRequest.new(container_image: pdh)
       resolved = cr.send :container_image_for_container
@@ -413,6 +417,73 @@ class ContainerRequestTest < ActiveSupport::TestCase
     end
   end
 
+  test "migrated docker image" do
+    Rails.configuration.docker_image_formats = ['v2']
+    add_docker19_migration_link
+
+    # Test that it returns only v2 images even though request is for v1 image.
+
+    set_user_from_auth :active
+    cr = create_minimal_req!(command: ["true", "1"],
+                             container_image: collections(:docker_image).portable_data_hash)
+    assert_equal(cr.send(:container_image_for_container),
+                 collections(:docker_image_1_12).portable_data_hash)
+
+    cr = create_minimal_req!(command: ["true", "2"],
+                             container_image: links(:docker_image_collection_tag).name)
+    assert_equal(cr.send(:container_image_for_container),
+                 collections(:docker_image_1_12).portable_data_hash)
+  end
+
+  test "use unmigrated docker image" do
+    Rails.configuration.docker_image_formats = ['v1']
+    add_docker19_migration_link
+
+    # Test that it returns only supported v1 images even though there is a
+    # migration link.
+
+    set_user_from_auth :active
+    cr = create_minimal_req!(command: ["true", "1"],
+                             container_image: collections(:docker_image).portable_data_hash)
+    assert_equal(cr.send(:container_image_for_container),
+                 collections(:docker_image).portable_data_hash)
+
+    cr = create_minimal_req!(command: ["true", "2"],
+                             container_image: links(:docker_image_collection_tag).name)
+    assert_equal(cr.send(:container_image_for_container),
+                 collections(:docker_image).portable_data_hash)
+  end
+
+  test "incompatible docker image v1" do
+    Rails.configuration.docker_image_formats = ['v1']
+    add_docker19_migration_link
+
+    # Don't return unsupported v2 image even if we ask for it directly.
+    set_user_from_auth :active
+    cr = create_minimal_req!(command: ["true", "1"],
+                             container_image: collections(:docker_image_1_12).portable_data_hash)
+    assert_raises(ArvadosModel::UnresolvableContainerError) do
+      cr.send(:container_image_for_container)
+    end
+  end
+
+  test "incompatible docker image v2" do
+    Rails.configuration.docker_image_formats = ['v2']
+    # No migration link, don't return unsupported v1 image,
+
+    set_user_from_auth :active
+    cr = create_minimal_req!(command: ["true", "1"],
+                             container_image: collections(:docker_image).portable_data_hash)
+    assert_raises(ArvadosModel::UnresolvableContainerError) do
+      cr.send(:container_image_for_container)
+    end
+    cr = create_minimal_req!(command: ["true", "2"],
+                             container_image: links(:docker_image_collection_tag).name)
+    assert_raises(ArvadosModel::UnresolvableContainerError) do
+      cr.send(:container_image_for_container)
+    end
+  end
+
   test "requestor can retrieve container owned by dispatch" do
     assert_not_empty Container.readable_by(users(:admin)).where(uuid: containers(:running).uuid)
     assert_not_empty Container.readable_by(users(:active)).where(uuid: containers(:running).uuid)
@@ -471,6 +542,7 @@ class ContainerRequestTest < ActiveSupport::TestCase
   test "Retry on container cancelled" do
     set_user_from_auth :active
     cr = create_minimal_req!(priority: 1, state: "Committed", container_count_max: 2)
+    cr2 = create_minimal_req!(priority: 1, state: "Committed", container_count_max: 2, command: ["echo", "baz"])
     prev_container_uuid = cr.container_uuid
 
     c = act_as_system_user do
@@ -481,8 +553,10 @@ class ContainerRequestTest < ActiveSupport::TestCase
     end
 
     cr.reload
+    cr2.reload
     assert_equal "Committed", cr.state
     assert_equal prev_container_uuid, cr.container_uuid
+    assert_not_equal cr2.container_uuid, cr.container_uuid
     prev_container_uuid = cr.container_uuid
 
     act_as_system_user do
@@ -490,8 +564,10 @@ class ContainerRequestTest < ActiveSupport::TestCase
     end
 
     cr.reload
+    cr2.reload
     assert_equal "Committed", cr.state
     assert_not_equal prev_container_uuid, cr.container_uuid
+    assert_not_equal cr2.container_uuid, cr.container_uuid
     prev_container_uuid = cr.container_uuid
 
     c = act_as_system_user do
@@ -501,8 +577,39 @@ class ContainerRequestTest < ActiveSupport::TestCase
     end
 
     cr.reload
+    cr2.reload
     assert_equal "Final", cr.state
     assert_equal prev_container_uuid, cr.container_uuid
+    assert_not_equal cr2.container_uuid, cr.container_uuid
+  end
+
+  test "Output collection name setting using output_name with name collision resolution" do
+    set_user_from_auth :active
+    output_name = collections(:foo_file).name
+
+    cr = create_minimal_req!(priority: 1,
+                             state: ContainerRequest::Committed,
+                             output_name: output_name)
+    act_as_system_user do
+      c = Container.find_by_uuid(cr.container_uuid)
+      c.update_attributes!(state: Container::Locked)
+      c.update_attributes!(state: Container::Running)
+      c.update_attributes!(state: Container::Complete,
+                           exit_code: 0,
+                           output: '1f4b0bc7583c2a7f9102c395f4ffc5e3+45',
+                           log: 'fa7aeb5140e2848d39b416daeef4ffc5+45')
+    end
+    cr.save
+    assert_equal ContainerRequest::Final, cr.state
+    output_coll = Collection.find_by_uuid(cr.output_uuid)
+    # Make sure the resulting output collection name include the original name
+    # plus the date
+    assert_not_equal output_name, output_coll.name,
+                     "It shouldn't exist more than one collection with the same owner and name '${output_name}'"
+    assert output_coll.name.include?(output_name),
+           "New name should include original name"
+    assert_match /\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z/, output_coll.name,
+                 "New name should include ISO8601 date"
   end
 
   test "Finalize committed request when reusing a finished container" do