X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/e33cb63676097f15842cefe8c3a750965daca751..24bcfa0b87b87e4510fffe8a961a5d4a9fd34948:/services/api/test/unit/container_test.rb diff --git a/services/api/test/unit/container_test.rb b/services/api/test/unit/container_test.rb index 5ea0927cb1..8894ed9d4c 100644 --- a/services/api/test/unit/container_test.rb +++ b/services/api/test/unit/container_test.rb @@ -122,7 +122,7 @@ class ContainerTest < ActiveSupport::TestCase state: Container::Complete, exit_code: 0, log: 'ea10d51bcf88862dbcc36eb292017dfd+45', - output: 'zzzzz-4zz18-znfnqtbbv4spc3w' + output: '1f4b0bc7583c2a7f9102c395f4ffc5e3+45' } c_older, _ = minimal_new(common_attrs) @@ -139,10 +139,35 @@ class ContainerTest < ActiveSupport::TestCase reused = Container.find_reusable(common_attrs) assert_not_nil reused - assert_equal reused.uuid, c_recent.uuid + assert_equal reused.uuid, c_older.uuid end - test "find_reusable method should select running container most likely to finish sooner" do + test "find_reusable method should not select completed container when inconsistent outputs exist" do + set_user_from_auth :active + common_attrs = REUSABLE_COMMON_ATTRS.merge({environment: {"var" => "complete"}}) + completed_attrs = { + state: Container::Complete, + exit_code: 0, + log: 'ea10d51bcf88862dbcc36eb292017dfd+45', + } + + c_output1, _ = minimal_new(common_attrs) + c_output2, _ = minimal_new(common_attrs) + + set_user_from_auth :dispatch1 + c_output1.update_attributes!({state: Container::Locked}) + c_output1.update_attributes!({state: Container::Running}) + c_output1.update_attributes!(completed_attrs.merge({output: '1f4b0bc7583c2a7f9102c395f4ffc5e3+45'})) + + c_output2.update_attributes!({state: Container::Locked}) + c_output2.update_attributes!({state: Container::Running}) + c_output2.update_attributes!(completed_attrs.merge({output: 'fa7aeb5140e2848d39b416daeef4ffc5+45'})) + + reused = Container.find_reusable(common_attrs) + assert_nil reused + end + + test "find_reusable method should select running container by start date" do set_user_from_auth :active common_attrs = REUSABLE_COMMON_ATTRS.merge({environment: {"var" => "running"}}) c_slower, _ = minimal_new(common_attrs) @@ -151,18 +176,41 @@ class ContainerTest < ActiveSupport::TestCase set_user_from_auth :dispatch1 c_slower.update_attributes!({state: Container::Locked}) c_slower.update_attributes!({state: Container::Running, - progress: 10.0}) + progress: 0.1}) c_faster_started_first.update_attributes!({state: Container::Locked}) c_faster_started_first.update_attributes!({state: Container::Running, - progress: 15.0}) + progress: 0.15}) c_faster_started_second.update_attributes!({state: Container::Locked}) c_faster_started_second.update_attributes!({state: Container::Running, - progress: 15.0}) + progress: 0.15}) reused = Container.find_reusable(common_attrs) assert_not_nil reused + # Selected container is the one that started first assert_equal reused.uuid, c_faster_started_first.uuid end + test "find_reusable method should select running container by progress" do + set_user_from_auth :active + common_attrs = REUSABLE_COMMON_ATTRS.merge({environment: {"var" => "running2"}}) + c_slower, _ = minimal_new(common_attrs) + c_faster_started_first, _ = minimal_new(common_attrs) + c_faster_started_second, _ = minimal_new(common_attrs) + set_user_from_auth :dispatch1 + c_slower.update_attributes!({state: Container::Locked}) + c_slower.update_attributes!({state: Container::Running, + progress: 0.1}) + c_faster_started_first.update_attributes!({state: Container::Locked}) + c_faster_started_first.update_attributes!({state: Container::Running, + progress: 0.15}) + c_faster_started_second.update_attributes!({state: Container::Locked}) + c_faster_started_second.update_attributes!({state: Container::Running, + progress: 0.2}) + reused = Container.find_reusable(common_attrs) + assert_not_nil reused + # Selected container is the one with most progress done + assert_equal reused.uuid, c_faster_started_second.uuid + end + test "find_reusable method should select locked container most likely to start sooner" do set_user_from_auth :active common_attrs = REUSABLE_COMMON_ATTRS.merge({environment: {"var" => "locked"}}) @@ -181,6 +229,26 @@ class ContainerTest < ActiveSupport::TestCase assert_equal reused.uuid, c_high_priority_older.uuid end + test "find_reusable method should select running over failed container" do + set_user_from_auth :active + common_attrs = REUSABLE_COMMON_ATTRS.merge({environment: {"var" => "failed_vs_running"}}) + c_failed, _ = minimal_new(common_attrs) + c_running, _ = minimal_new(common_attrs) + set_user_from_auth :dispatch1 + c_failed.update_attributes!({state: Container::Locked}) + c_failed.update_attributes!({state: Container::Running}) + c_failed.update_attributes!({state: Container::Complete, + exit_code: 42, + log: 'ea10d51bcf88862dbcc36eb292017dfd+45', + output: 'ea10d51bcf88862dbcc36eb292017dfd+45'}) + c_running.update_attributes!({state: Container::Locked}) + c_running.update_attributes!({state: Container::Running, + progress: 0.15}) + reused = Container.find_reusable(common_attrs) + assert_not_nil reused + assert_equal reused.uuid, c_running.uuid + end + test "find_reusable method should select complete over running container" do set_user_from_auth :active common_attrs = REUSABLE_COMMON_ATTRS.merge({environment: {"var" => "completed_vs_running"}}) @@ -191,14 +259,14 @@ class ContainerTest < ActiveSupport::TestCase c_completed.update_attributes!({state: Container::Running}) c_completed.update_attributes!({state: Container::Complete, exit_code: 0, - log: "ea10d51bcf88862dbcc36eb292017dfd+45", - output: "zzzzz-4zz18-znfnqtbbv4spc3w"}) + log: 'ea10d51bcf88862dbcc36eb292017dfd+45', + output: '1f4b0bc7583c2a7f9102c395f4ffc5e3+45'}) c_running.update_attributes!({state: Container::Locked}) c_running.update_attributes!({state: Container::Running, - progress: 1.5}) + progress: 0.15}) reused = Container.find_reusable(common_attrs) assert_not_nil reused - assert_equal reused.uuid, c_completed.uuid + assert_equal c_completed.uuid, reused.uuid end test "find_reusable method should select running over locked container" do @@ -210,7 +278,7 @@ class ContainerTest < ActiveSupport::TestCase c_locked.update_attributes!({state: Container::Locked}) c_running.update_attributes!({state: Container::Locked}) c_running.update_attributes!({state: Container::Running, - progress: 1.5}) + progress: 0.15}) reused = Container.find_reusable(common_attrs) assert_not_nil reused assert_equal reused.uuid, c_running.uuid @@ -248,7 +316,7 @@ class ContainerTest < ActiveSupport::TestCase check_illegal_updates c, [{state: Container::Running}, {state: Container::Complete}] - c.update_attributes! state: Container::Locked + c.lock c.update_attributes! state: Container::Running check_illegal_modify c @@ -266,7 +334,7 @@ class ContainerTest < ActiveSupport::TestCase set_user_from_auth :dispatch1 assert_equal Container::Queued, c.state - refute c.update_attributes(state: Container::Locked), "no priority" + assert_raise(ActiveRecord::RecordInvalid) {c.lock} # "no priority" c.reload assert cr.update_attributes priority: 1 @@ -275,11 +343,14 @@ class ContainerTest < ActiveSupport::TestCase refute c.update_attributes(state: Container::Complete), "not locked" c.reload - assert c.update_attributes(state: Container::Locked), show_errors(c) + assert c.lock, show_errors(c) assert c.locked_by_uuid assert c.auth_uuid - assert c.update_attributes(state: Container::Queued), show_errors(c) + assert_raise(ArvadosModel::AlreadyLockedError) {c.lock} + c.reload + + assert c.unlock, show_errors(c) refute c.locked_by_uuid refute c.auth_uuid @@ -288,16 +359,16 @@ class ContainerTest < ActiveSupport::TestCase refute c.locked_by_uuid refute c.auth_uuid - assert c.update_attributes(state: Container::Locked), show_errors(c) + assert c.lock, show_errors(c) assert c.update_attributes(state: Container::Running), show_errors(c) assert c.locked_by_uuid assert c.auth_uuid auth_uuid_was = c.auth_uuid - refute c.update_attributes(state: Container::Locked), "already running" + assert_raise(ActiveRecord::RecordInvalid) {c.lock} # Running to Locked is not allowed c.reload - refute c.update_attributes(state: Container::Queued), "already running" + assert_raise(ActiveRecord::RecordInvalid) {c.unlock} # Running to Queued is not allowed c.reload assert c.update_attributes(state: Container::Complete), show_errors(c) @@ -318,7 +389,7 @@ class ContainerTest < ActiveSupport::TestCase test "Container locked cancel" do c, _ = minimal_new set_user_from_auth :dispatch1 - assert c.update_attributes(state: Container::Locked), show_errors(c) + assert c.lock, show_errors(c) assert c.update_attributes(state: Container::Cancelled), show_errors(c) check_no_change_from_cancelled c end @@ -326,8 +397,7 @@ class ContainerTest < ActiveSupport::TestCase test "Container running cancel" do c, _ = minimal_new set_user_from_auth :dispatch1 - c.update_attributes! state: Container::Queued - c.update_attributes! state: Container::Locked + c.lock c.update_attributes! state: Container::Running c.update_attributes! state: Container::Cancelled check_no_change_from_cancelled c @@ -349,7 +419,7 @@ class ContainerTest < ActiveSupport::TestCase test "Container only set exit code on complete" do c, _ = minimal_new set_user_from_auth :dispatch1 - c.update_attributes! state: Container::Locked + c.lock c.update_attributes! state: Container::Running check_illegal_updates c, [{exit_code: 1},