[ARVADOS] updated: 01ea0e9faa0b29ef747699f7f4b728d4e888ef83

Git user git at public.curoverse.com
Mon Jun 27 15:10:56 EDT 2016


Summary of changes:
 services/api/app/models/container_request.rb     |  72 +++-
 services/api/test/unit/container_request_test.rb | 409 +++++++++++------------
 2 files changed, 254 insertions(+), 227 deletions(-)

       via  01ea0e9faa0b29ef747699f7f4b728d4e888ef83 (commit)
       via  fdda56c99dbf581d7a09cebd28a16dceee2f8f02 (commit)
       via  53e5b13980ce3bfc1b898482696310e4ed8a9c54 (commit)
       via  5bcb3cee7d38123480cccc84a22a451ea17f2ae9 (commit)
       via  ce5abd0b4f93b2dfded9d02f8e01ea0505ae5128 (commit)
      from  9e5d7b0dc43a85fc03740b39611545f470a63eb8 (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 01ea0e9faa0b29ef747699f7f4b728d4e888ef83
Merge: 9e5d7b0 fdda56c
Author: Tom Clegg <tom at curoverse.com>
Date:   Mon Jun 27 15:10:31 2016 -0400

    Merge branch '8470-resolve-container-req'
    
    closes #8470


commit fdda56c99dbf581d7a09cebd28a16dceee2f8f02
Author: Tom Clegg <tom at curoverse.com>
Date:   Fri Jun 24 13:55:08 2016 -0400

    8470: Resolve docker image hash or tag to collection PDH when creating a Container.

diff --git a/services/api/app/models/container_request.rb b/services/api/app/models/container_request.rb
index 15418f2..e84026a 100644
--- a/services/api/app/models/container_request.rb
+++ b/services/api/app/models/container_request.rb
@@ -82,16 +82,16 @@ class ContainerRequest < ArvadosModel
   # Create a new container (or find an existing one) to satisfy this
   # request.
   def resolve
-    # TODO: resolve container_image to a content address.
     c_mounts = mounts_for_container
     c_runtime_constraints = runtime_constraints_for_container
+    c_container_image = container_image_for_container
     c = act_as_system_user do
       Container.create!(command: self.command,
-                        container_image: self.container_image,
                         cwd: self.cwd,
                         environment: self.environment,
-                        mounts: c_mounts,
                         output_path: self.output_path,
+                        container_image: c_container_image,
+                        mounts: c_mounts,
                         runtime_constraints: c_runtime_constraints)
     end
     self.container_uuid = c.uuid
@@ -149,6 +149,15 @@ class ContainerRequest < ArvadosModel
     return c_mounts
   end
 
+  # Return a container_image PDH suitable for a Container.
+  def container_image_for_container
+    coll = Collection.for_latest_docker_image(container_image)
+    if !coll
+      raise ActiveRecord::RecordNotFound.new "docker image #{container_image.inspect} not found"
+    end
+    return coll.portable_data_hash
+  end
+
   def set_container
     if (container_uuid_changed? and
         not current_user.andand.is_admin and
diff --git a/services/api/test/unit/container_request_test.rb b/services/api/test/unit/container_request_test.rb
index d8aed76..8621daa 100644
--- a/services/api/test/unit/container_request_test.rb
+++ b/services/api/test/unit/container_request_test.rb
@@ -4,7 +4,7 @@ class ContainerRequestTest < ActiveSupport::TestCase
   def create_minimal_req! attrs={}
     defaults = {
       command: ["echo", "foo"],
-      container_image: "img",
+      container_image: links(:docker_image_collection_tag).name,
       cwd: "/tmp",
       environment: {},
       mounts: {"/out" => {"kind" => "tmp", "capacity" => 1000000}},
@@ -79,7 +79,7 @@ class ContainerRequestTest < ActiveSupport::TestCase
     c = Container.find_by_uuid cr.container_uuid
     assert_not_nil c
     assert_equal ["echo", "foo"], c.command
-    assert_equal "img", c.container_image
+    assert_equal collections(:docker_image).portable_data_hash, c.container_image
     assert_equal "/tmp", c.cwd
     assert_equal({}, c.environment)
     assert_equal({"/out" => {"kind"=>"tmp", "capacity"=>1000000}}, c.mounts)
@@ -311,4 +311,37 @@ class ContainerRequestTest < ActiveSupport::TestCase
       cr.send :mounts_for_container
     end
   end
+
+  ['arvados/apitestfixture:latest',
+   'arvados/apitestfixture',
+   'd8309758b8fe2c81034ffc8a10c36460b77db7bc5e7b448c4e5b684f9d95a678',
+  ].each do |tag|
+    test "container_image_for_container(#{tag.inspect})" do
+      set_user_from_auth :active
+      cr = ContainerRequest.new(container_image: tag)
+      resolved = cr.send :container_image_for_container
+      assert_equal resolved, collections(:docker_image).portable_data_hash
+    end
+  end
+
+  test "container_image_for_container(pdh)" do
+    set_user_from_auth :active
+    pdh = collections(:docker_image).portable_data_hash
+    cr = ContainerRequest.new(container_image: pdh)
+    resolved = cr.send :container_image_for_container
+    assert_equal resolved, pdh
+  end
+
+  ['acbd18db4cc2f85cedef654fccc4a4d8+3',
+   'ENOEXIST',
+   'arvados/apitestfixture:ENOEXIST',
+  ].each do |img|
+    test "container_image_for_container(#{img.inspect}) => 404" do
+      set_user_from_auth :active
+      cr = ContainerRequest.new(container_image: img)
+      assert_raises(ActiveRecord::RecordNotFound) do
+        cr.send :container_image_for_container
+      end
+    end
+  end
 end

commit 53e5b13980ce3bfc1b898482696310e4ed8a9c54
Author: Tom Clegg <tom at curoverse.com>
Date:   Thu Jun 23 22:28:50 2016 -0400

    8470: Clean up ContainerRequest tests.

diff --git a/services/api/test/unit/container_request_test.rb b/services/api/test/unit/container_request_test.rb
index 46f564e..d8aed76 100644
--- a/services/api/test/unit/container_request_test.rb
+++ b/services/api/test/unit/container_request_test.rb
@@ -9,7 +9,6 @@ class ContainerRequestTest < ActiveSupport::TestCase
       environment: {},
       mounts: {"/out" => {"kind" => "tmp", "capacity" => 1000000}},
       output_path: "/out",
-      priority: 1,
       runtime_constraints: {},
       name: "foo",
       description: "bar",
@@ -19,97 +18,26 @@ class ContainerRequestTest < ActiveSupport::TestCase
     return cr
   end
 
-  def check_illegal_modify c
+  def check_bogus_states cr
+    [nil, "Flubber"].each do |state|
       assert_raises(ActiveRecord::RecordInvalid) do
-        c.reload
-        c.command = ["echo", "bar"]
-        c.save!
-      end
-
-      assert_raises(ActiveRecord::RecordInvalid) do
-        c.reload
-        c.container_image = "img2"
-        c.save!
-      end
-
-      assert_raises(ActiveRecord::RecordInvalid) do
-        c.reload
-        c.cwd = "/tmp2"
-        c.save!
-      end
-
-      assert_raises(ActiveRecord::RecordInvalid) do
-        c.reload
-        c.environment = {"FOO" => "BAR"}
-        c.save!
-      end
-
-      assert_raises(ActiveRecord::RecordInvalid) do
-        c.reload
-        c.mounts = {"FOO" => "BAR"}
-        c.save!
-      end
-
-      assert_raises(ActiveRecord::RecordInvalid) do
-        c.reload
-        c.output_path = "/tmp3"
-        c.save!
-      end
-
-      assert_raises(ActiveRecord::RecordInvalid) do
-        c.reload
-        c.runtime_constraints = {"FOO" => "BAR"}
-        c.save!
-      end
-
-      assert_raises(ActiveRecord::RecordInvalid) do
-        c.reload
-        c.name = "baz"
-        c.save!
-      end
-
-      assert_raises(ActiveRecord::RecordInvalid) do
-        c.reload
-        c.description = "baz"
-        c.save!
-      end
-
-  end
-
-  def check_bogus_states c
-      assert_raises(ActiveRecord::RecordInvalid) do
-        c.reload
-        c.state = nil
-        c.save!
-      end
-
-      assert_raises(ActiveRecord::RecordInvalid) do
-        c.reload
-        c.state = "Flubber"
-        c.save!
+        cr.state = state
+        cr.save!
       end
+      cr.reload
+    end
   end
 
   test "Container request create" do
-    set_user_from_auth :active_trustedclient
-    cr = ContainerRequest.new
-    cr.command = ["echo", "foo"]
-    cr.container_image = "img"
-    cr.cwd = "/tmp"
-    cr.environment = {}
-    cr.mounts = {"BAR" => "FOO"}
-    cr.output_path = "/tmpout"
-    cr.runtime_constraints = {}
-    cr.name = "foo"
-    cr.description = "bar"
-    cr.save!
+    set_user_from_auth :active
+    cr = create_minimal_req!
 
     assert_nil cr.container_uuid
     assert_nil cr.priority
 
     check_bogus_states cr
 
-    cr.reload
+    # Ensure we can modify all attributes
     cr.command = ["echo", "foo3"]
     cr.container_image = "img3"
     cr.cwd = "/tmp3"
@@ -117,7 +45,7 @@ class ContainerRequestTest < ActiveSupport::TestCase
     cr.mounts = {"BAR" => "BAZ"}
     cr.output_path = "/tmp4"
     cr.priority = 2
-    cr.runtime_constraints = {"X" => "Y"}
+    cr.runtime_constraints = {"vcpus" => 4}
     cr.name = "foo3"
     cr.description = "bar3"
     cr.save!
@@ -142,6 +70,7 @@ class ContainerRequestTest < ActiveSupport::TestCase
 
     cr.reload
     cr.state = "Committed"
+    cr.priority = 1
     cr.save!
 
     cr.reload
@@ -170,181 +99,105 @@ class ContainerRequestTest < ActiveSupport::TestCase
     c.reload
     assert_equal 0, cr.priority
     assert_equal 0, c.priority
-
   end
 
 
   test "Container request max priority" do
-    set_user_from_auth :active_trustedclient
-    cr = ContainerRequest.new
-    cr.state = "Committed"
-    cr.container_image = "img"
-    cr.command = ["foo", "bar"]
-    cr.output_path = "/tmp"
-    cr.cwd = "/tmp"
-    cr.priority = 5
-    cr.save!
+    set_user_from_auth :active
+    cr = create_minimal_req!(priority: 5, state: "Committed")
 
     c = Container.find_by_uuid cr.container_uuid
     assert_equal 5, c.priority
 
-    cr2 = ContainerRequest.new
-    cr2.container_image = "img"
-    cr2.command = ["foo", "bar"]
-    cr2.output_path = "/tmp"
-    cr2.cwd = "/tmp"
+    cr2 = create_minimal_req!
     cr2.priority = 10
-    cr2.save!
-
+    cr2.state = "Committed"
+    cr2.container_uuid = cr.container_uuid
     act_as_system_user do
-      cr2.state = "Committed"
-      cr2.container_uuid = cr.container_uuid
       cr2.save!
     end
 
+    # cr and cr2 have priority 5 and 10, and are being satisfied by
+    # the same container c, so c's priority should be
+    # max(priority)=10.
     c.reload
     assert_equal 10, c.priority
 
-    cr2.reload
-    cr2.priority = 0
-    cr2.save!
+    cr2.update_attributes!(priority: 0)
 
     c.reload
     assert_equal 5, c.priority
 
-    cr.reload
-    cr.priority = 0
-    cr.save!
+    cr.update_attributes!(priority: 0)
 
     c.reload
     assert_equal 0, c.priority
-
   end
 
 
   test "Independent container requests" do
-    set_user_from_auth :active_trustedclient
-    cr = ContainerRequest.new
-    cr.state = "Committed"
-    cr.container_image = "img"
-    cr.command = ["foo", "bar"]
-    cr.output_path = "/tmp"
-    cr.cwd = "/tmp"
-    cr.priority = 5
-    cr.save!
-
-    cr2 = ContainerRequest.new
-    cr2.state = "Committed"
-    cr2.container_image = "img"
-    cr2.command = ["foo", "bar"]
-    cr2.output_path = "/tmp"
-    cr2.cwd = "/tmp"
-    cr2.priority = 10
-    cr2.save!
+    set_user_from_auth :active
+    cr1 = create_minimal_req!(command: ["foo", "1"], priority: 5, state: "Committed")
+    cr2 = create_minimal_req!(command: ["foo", "2"], priority: 10, state: "Committed")
 
-    c = Container.find_by_uuid cr.container_uuid
-    assert_equal 5, c.priority
+    c1 = Container.find_by_uuid cr1.container_uuid
+    assert_equal 5, c1.priority
 
     c2 = Container.find_by_uuid cr2.container_uuid
     assert_equal 10, c2.priority
 
-    cr.priority = 0
-    cr.save!
+    cr1.update_attributes!(priority: 0)
 
-    c.reload
-    assert_equal 0, c.priority
+    c1.reload
+    assert_equal 0, c1.priority
 
     c2.reload
     assert_equal 10, c2.priority
   end
 
-
-  test "Container cancelled finalizes request" do
-    set_user_from_auth :active_trustedclient
-    cr = ContainerRequest.new
-    cr.state = "Committed"
-    cr.container_image = "img"
-    cr.command = ["foo", "bar"]
-    cr.output_path = "/tmp"
-    cr.cwd = "/tmp"
-    cr.priority = 5
-    cr.save!
-
-    cr.reload
-    assert_equal "Committed", cr.state
-
-    c = Container.find_by_uuid cr.container_uuid
-    assert_equal "Queued", c.state
+  test "Request is finalized when its container is cancelled" do
+    set_user_from_auth :active
+    cr = create_minimal_req!(priority: 1, state: "Committed")
 
     act_as_system_user do
-      c.state = "Cancelled"
-      c.save!
+      Container.find_by_uuid(cr.container_uuid).
+        update_attributes!(state: Container::Cancelled)
     end
 
     cr.reload
     assert_equal "Final", cr.state
-
   end
 
+  test "Request is finalized when its container is completed" do
+    set_user_from_auth :active
+    cr = create_minimal_req!(priority: 1, state: "Committed")
 
-  test "Container complete finalizes request" do
-    set_user_from_auth :active_trustedclient
-    cr = ContainerRequest.new
-    cr.state = "Committed"
-    cr.container_image = "img"
-    cr.command = ["foo", "bar"]
-    cr.output_path = "/tmp"
-    cr.cwd = "/tmp"
-    cr.priority = 5
-    cr.save!
-
-    cr.reload
-    assert_equal "Committed", cr.state
-
-    c = Container.find_by_uuid cr.container_uuid
-    assert_equal Container::Queued, c.state
-
-    act_as_system_user do
-      c.update_attributes! state: Container::Locked
-      c.update_attributes! state: Container::Running
+    c = 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
     end
 
     cr.reload
     assert_equal "Committed", cr.state
 
     act_as_system_user do
-      c.update_attributes! state: Container::Complete
-      c.save!
+      c.update_attributes!(state: Container::Complete)
     end
 
     cr.reload
     assert_equal "Final", cr.state
-
   end
 
   test "Container makes container request, then is cancelled" do
-    set_user_from_auth :active_trustedclient
-    cr = ContainerRequest.new
-    cr.state = "Committed"
-    cr.container_image = "img"
-    cr.command = ["foo", "bar"]
-    cr.output_path = "/tmp"
-    cr.cwd = "/tmp"
-    cr.priority = 5
-    cr.save!
+    set_user_from_auth :active
+    cr = create_minimal_req!(priority: 5, state: "Committed")
 
     c = Container.find_by_uuid cr.container_uuid
     assert_equal 5, c.priority
 
-    cr2 = ContainerRequest.new
-    cr2.state = "Committed"
-    cr2.container_image = "img"
-    cr2.command = ["foo", "bar"]
-    cr2.output_path = "/tmp"
-    cr2.cwd = "/tmp"
-    cr2.priority = 10
-    cr2.requesting_container_uuid = c.uuid
-    cr2.save!
+    cr2 = create_minimal_req!(priority: 10, state: "Committed", requesting_container_uuid: c.uuid)
 
     c2 = Container.find_by_uuid cr2.container_uuid
     assert_equal 10, c2.priority

commit 5bcb3cee7d38123480cccc84a22a451ea17f2ae9
Author: Tom Clegg <tom at curoverse.com>
Date:   Thu Jun 23 21:42:51 2016 -0400

    8470: Resolve mounts to PDH.

diff --git a/services/api/app/models/container_request.rb b/services/api/app/models/container_request.rb
index 221da0d..15418f2 100644
--- a/services/api/app/models/container_request.rb
+++ b/services/api/app/models/container_request.rb
@@ -82,15 +82,17 @@ class ContainerRequest < ArvadosModel
   # Create a new container (or find an existing one) to satisfy this
   # request.
   def resolve
-    # TODO: resolve mounts and container_image to content addresses.
+    # TODO: resolve container_image to a content address.
+    c_mounts = mounts_for_container
+    c_runtime_constraints = runtime_constraints_for_container
     c = act_as_system_user do
       Container.create!(command: self.command,
                         container_image: self.container_image,
                         cwd: self.cwd,
                         environment: self.environment,
-                        mounts: self.mounts,
+                        mounts: c_mounts,
                         output_path: self.output_path,
-                        runtime_constraints: runtime_constraints_for_container)
+                        runtime_constraints: c_runtime_constraints)
     end
     self.container_uuid = c.uuid
   end
@@ -116,6 +118,37 @@ class ContainerRequest < ArvadosModel
     rc
   end
 
+  # Return a mounts hash suitable for a Container, i.e., with every
+  # readonly collection UUID resolved to a PDH.
+  def mounts_for_container
+    c_mounts = {}
+    mounts.each do |k, mount|
+      mount = mount.dup
+      c_mounts[k] = mount
+      if mount['kind'] != 'collection'
+        next
+      end
+      if (uuid = mount.delete 'uuid')
+        c = Collection.
+          readable_by(current_user).
+          where(uuid: uuid).
+          select(:portable_data_hash).
+          first
+        if !c
+          raise ActiveRecord::RecordNotFound.new "cannot mount collection #{uuid.inspect}: not found"
+        end
+        if mount['portable_data_hash'].nil?
+          # PDH not supplied by client
+          mount['portable_data_hash'] = c.portable_data_hash
+        elsif mount['portable_data_hash'] != c.portable_data_hash
+          # UUID and PDH supplied by client, but they don't agree
+          raise ArgumentError.new "cannot mount collection #{uuid.inspect}: current portable_data_hash #{c.portable_data_hash.inspect} does not match #{c['portable_data_hash'].inspect} in request"
+        end
+      end
+    end
+    return c_mounts
+  end
+
   def set_container
     if (container_uuid_changed? and
         not current_user.andand.is_admin and
diff --git a/services/api/test/unit/container_request_test.rb b/services/api/test/unit/container_request_test.rb
index f510f25..46f564e 100644
--- a/services/api/test/unit/container_request_test.rb
+++ b/services/api/test/unit/container_request_test.rb
@@ -126,20 +126,8 @@ class ContainerRequestTest < ActiveSupport::TestCase
   end
 
   test "Container request priority must be non-nil" do
-    set_user_from_auth :active_trustedclient
-    cr = ContainerRequest.new
-    cr.command = ["echo", "foo"]
-    cr.container_image = "img"
-    cr.cwd = "/tmp"
-    cr.environment = {}
-    cr.mounts = {"BAR" => "FOO"}
-    cr.output_path = "/tmpout"
-    cr.runtime_constraints = {}
-    cr.name = "foo"
-    cr.description = "bar"
-    cr.save!
-
-    cr.reload
+    set_user_from_auth :active
+    cr = create_minimal_req!(priority: nil)
     cr.state = "Committed"
     assert_raises(ActiveRecord::RecordInvalid) do
       cr.save!
@@ -406,4 +394,68 @@ class ContainerRequestTest < ActiveSupport::TestCase
              "container runtime_constraints was #{resolved.inspect}")
     end
   end
+
+  [[{"/out" => {
+        "kind" => "collection",
+        "uuid" => "zzzzz-4zz18-znfnqtbbv4spc3w",
+        "path" => "/foo"}},
+    lambda do |resolved|
+      resolved["/out"] == {
+        "portable_data_hash" => "1f4b0bc7583c2a7f9102c395f4ffc5e3+45",
+        "kind" => "collection",
+        "path" => "/foo",
+      }
+    end],
+   [{"/out" => {
+        "kind" => "collection",
+        "uuid" => "zzzzz-4zz18-znfnqtbbv4spc3w",
+        "portable_data_hash" => "1f4b0bc7583c2a7f9102c395f4ffc5e3+45",
+        "path" => "/foo"}},
+    lambda do |resolved|
+      resolved["/out"] == {
+        "portable_data_hash" => "1f4b0bc7583c2a7f9102c395f4ffc5e3+45",
+        "kind" => "collection",
+        "path" => "/foo",
+      }
+    end],
+  ].each do |mounts, okfunc|
+    test "resolve mounts #{mounts.inspect} to values" do
+      set_user_from_auth :active
+      cr = ContainerRequest.new(mounts: mounts)
+      resolved = cr.send :mounts_for_container
+      assert(okfunc.call(resolved),
+             "mounts_for_container returned #{resolved.inspect}")
+    end
+  end
+
+  test 'mount unreadable collection' do
+    set_user_from_auth :spectator
+    m = {
+      "/foo" => {
+        "kind" => "collection",
+        "uuid" => "zzzzz-4zz18-znfnqtbbv4spc3w",
+        "path" => "/foo",
+      },
+    }
+    cr = ContainerRequest.new(mounts: m)
+    assert_raises(ActiveRecord::RecordNotFound) do
+      cr.send :mounts_for_container
+    end
+  end
+
+  test 'mount collection with mismatched UUID and PDH' do
+    set_user_from_auth :active
+    m = {
+      "/foo" => {
+        "kind" => "collection",
+        "uuid" => "zzzzz-4zz18-znfnqtbbv4spc3w",
+        "portable_data_hash" => "fa7aeb5140e2848d39b416daeef4ffc5+45",
+        "path" => "/foo",
+      },
+    }
+    cr = ContainerRequest.new(mounts: m)
+    assert_raises(ArgumentError) do
+      cr.send :mounts_for_container
+    end
+  end
 end

commit ce5abd0b4f93b2dfded9d02f8e01ea0505ae5128
Author: Tom Clegg <tom at curoverse.com>
Date:   Thu Jun 23 14:16:45 2016 -0400

    8470: Resolve runtime_constraints ranges to numbers when satisfying a Container Request.

diff --git a/services/api/app/models/container_request.rb b/services/api/app/models/container_request.rb
index 496a6b1..221da0d 100644
--- a/services/api/app/models/container_request.rb
+++ b/services/api/app/models/container_request.rb
@@ -82,8 +82,7 @@ class ContainerRequest < ArvadosModel
   # Create a new container (or find an existing one) to satisfy this
   # request.
   def resolve
-    # TODO: resolve symbolic git and keep references to content
-    # addresses.
+    # TODO: resolve mounts and container_image to content addresses.
     c = act_as_system_user do
       Container.create!(command: self.command,
                         container_image: self.container_image,
@@ -91,11 +90,32 @@ class ContainerRequest < ArvadosModel
                         environment: self.environment,
                         mounts: self.mounts,
                         output_path: self.output_path,
-                        runtime_constraints: self.runtime_constraints)
+                        runtime_constraints: runtime_constraints_for_container)
     end
     self.container_uuid = c.uuid
   end
 
+  # Return a runtime_constraints hash that complies with
+  # self.runtime_constraints but is suitable for saving in a container
+  # record, i.e., has specific values instead of ranges.
+  #
+  # Doing this as a step separate from other resolutions, like "git
+  # revision range to commit hash", makes sense only when there is no
+  # opportunity to reuse an existing container (e.g., container reuse
+  # is not implemented yet, or we have already found that no existing
+  # containers are suitable).
+  def runtime_constraints_for_container
+    rc = {}
+    runtime_constraints.each do |k, v|
+      if v.is_a? Array
+        rc[k] = v[0]
+      else
+        rc[k] = v
+      end
+    end
+    rc
+  end
+
   def set_container
     if (container_uuid_changed? and
         not current_user.andand.is_admin and
diff --git a/services/api/test/unit/container_request_test.rb b/services/api/test/unit/container_request_test.rb
index df89b93..f510f25 100644
--- a/services/api/test/unit/container_request_test.rb
+++ b/services/api/test/unit/container_request_test.rb
@@ -1,6 +1,24 @@
 require 'test_helper'
 
 class ContainerRequestTest < ActiveSupport::TestCase
+  def create_minimal_req! attrs={}
+    defaults = {
+      command: ["echo", "foo"],
+      container_image: "img",
+      cwd: "/tmp",
+      environment: {},
+      mounts: {"/out" => {"kind" => "tmp", "capacity" => 1000000}},
+      output_path: "/out",
+      priority: 1,
+      runtime_constraints: {},
+      name: "foo",
+      description: "bar",
+    }
+    cr = ContainerRequest.create!(defaults.merge(attrs))
+    cr.reload
+    return cr
+  end
+
   def check_illegal_modify c
       assert_raises(ActiveRecord::RecordInvalid) do
         c.reload
@@ -129,21 +147,9 @@ class ContainerRequestTest < ActiveSupport::TestCase
   end
 
   test "Container request commit" do
-    set_user_from_auth :active_trustedclient
-    cr = ContainerRequest.new
-    cr.command = ["echo", "foo"]
-    cr.container_image = "img"
-    cr.cwd = "/tmp"
-    cr.environment = {}
-    cr.mounts = {"BAR" => "FOO"}
-    cr.output_path = "/tmpout"
-    cr.priority = 1
-    cr.runtime_constraints = {}
-    cr.name = "foo"
-    cr.description = "bar"
-    cr.save!
+    set_user_from_auth :active
+    cr = create_minimal_req!(runtime_constraints: {"vcpus" => [2,3]})
 
-    cr.reload
     assert_nil cr.container_uuid
 
     cr.reload
@@ -152,14 +158,16 @@ class ContainerRequestTest < ActiveSupport::TestCase
 
     cr.reload
 
+    assert_not_nil cr.container_uuid
     c = Container.find_by_uuid cr.container_uuid
+    assert_not_nil c
     assert_equal ["echo", "foo"], c.command
     assert_equal "img", c.container_image
     assert_equal "/tmp", c.cwd
     assert_equal({}, c.environment)
-    assert_equal({"BAR" => "FOO"}, c.mounts)
-    assert_equal "/tmpout", c.output_path
-    assert_equal({}, c.runtime_constraints)
+    assert_equal({"/out" => {"kind"=>"tmp", "capacity"=>1000000}}, c.mounts)
+    assert_equal "/out", c.output_path
+    assert_equal({"vcpus" => 2}, c.runtime_constraints)
     assert_equal 1, c.priority
 
     assert_raises(ActiveRecord::RecordInvalid) do
@@ -379,4 +387,23 @@ class ContainerRequestTest < ActiveSupport::TestCase
       assert_equal expected, cr.requesting_container_uuid
     end
   end
+
+  [[{"vcpus" => [2, nil]},
+    lambda { |resolved| resolved["vcpus"] == 2 }],
+   [{"vcpus" => [3, 7]},
+    lambda { |resolved| resolved["vcpus"] == 3 }],
+   [{"vcpus" => 4},
+    lambda { |resolved| resolved["vcpus"] == 4 }],
+   [{"ram" => [1000000000, 2000000000]},
+    lambda { |resolved| resolved["ram"] == 1000000000 }],
+   [{"ram" => [1234234234]},
+    lambda { |resolved| resolved["ram"] == 1234234234 }],
+  ].each do |rc, okfunc|
+    test "resolve runtime constraint range #{rc} to values" do
+      cr = ContainerRequest.new(runtime_constraints: rc)
+      resolved = cr.send :runtime_constraints_for_container
+      assert(okfunc.call(resolved),
+             "container runtime_constraints was #{resolved.inspect}")
+    end
+  end
 end

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


hooks/post-receive
-- 




More information about the arvados-commits mailing list