Skip to content

Commit fa860f2

Browse files
ianballouadamruzicka
authored andcommitted
Refs #38991 - chain() now accepts Task objects
1 parent ca5711e commit fa860f2

File tree

3 files changed

+58
-15
lines changed

3 files changed

+58
-15
lines changed

lib/foreman_tasks.rb

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,14 +62,26 @@ def self.delay(action, delay_options, *args)
6262
ForemanTasks::Task::DynflowTask.where(:external_id => result.id).first!
6363
end
6464

65-
# Chain a task to wait for prerequisite task(s) to finish before executing.
66-
# The chained task remains 'scheduled' until all prerequisites reach 'stopped' state.
65+
# Chain a task to wait for dependency task(s) to finish before executing.
66+
# The chained task remains 'scheduled' until all dependencies reach 'stopped' state.
6767
#
68-
# @param plan_uuids [String, Array<String>] UUID(s) of prerequisite execution plan(s)
68+
# @param dependencies [ForemanTasks::Task, Array<ForemanTasks::Task>, ActiveRecord::Relation]
69+
# Dependency ForemanTasks task object(s) or an ActiveRecord relation of tasks.
6970
# @param action [Class] Action class to execute
7071
# @param args Arguments to pass to the action
7172
# @return [ForemanTasks::Task::DynflowTask] The chained task
72-
def self.chain(plan_uuids, action, *args)
73+
def self.chain(dependencies, action, *args)
74+
plan_uuids =
75+
if dependencies.is_a?(ActiveRecord::Relation)
76+
dependencies.pluck(:external_id)
77+
else
78+
Array(dependencies).map(&:external_id)
79+
end
80+
81+
if plan_uuids.any?(&:blank?)
82+
raise ArgumentError, 'All dependency tasks must have external_id set'
83+
end
84+
7385
result = dynflow.world.chain(plan_uuids, action, *args)
7486
ForemanTasks::Task::DynflowTask.where(:external_id => result.id).first!
7587
end

lib/foreman_tasks/triggers.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,9 @@ def sync_task(action, *args, &block)
2525
def delay(action, delay_options, *args)
2626
foreman_tasks.delay(action, delay_options, *args)
2727
end
28+
29+
def chain(dependencies, action, *args)
30+
foreman_tasks.chain(dependencies, action, *args)
31+
end
2832
end
2933
end

test/unit/chaining_test.rb

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,28 +8,55 @@ class ChainingTest < ActiveSupport::TestCase
88
User.current = User.where(:login => 'apiadmin').first
99
end
1010

11-
it 'creates a scheduled task chained to a prerequisite execution plan' do
12-
prerequisite_plan = ForemanTasks.dynflow.world.plan(Support::DummyDynflowAction)
11+
it 'creates a scheduled task chained to a dependency task' do
12+
triggered = ForemanTasks.trigger(Support::DummyDynflowAction)
13+
triggered.finished.wait(30)
14+
dependency_task = ForemanTasks::Task::DynflowTask.find_by!(:external_id => triggered.id)
1315

14-
task = ForemanTasks.chain(prerequisite_plan.id, Support::DummyDynflowAction)
16+
task = ForemanTasks.chain(dependency_task, Support::DummyDynflowAction)
1517

1618
assert_kind_of ForemanTasks::Task::DynflowTask, task
1719
assert_predicate task, :scheduled?
1820

1921
dependencies = ForemanTasks.dynflow.world.persistence.find_execution_plan_dependencies(task.execution_plan.id)
20-
assert_includes dependencies, prerequisite_plan.id
22+
assert_includes dependencies, dependency_task.external_id
2123
end
2224

23-
it 'accepts multiple prerequisite execution plans' do
24-
prerequisite_plan_1 = ForemanTasks.dynflow.world.plan(Support::DummyDynflowAction)
25-
prerequisite_plan_2 = ForemanTasks.dynflow.world.plan(Support::DummyDynflowAction)
25+
it 'accepts multiple dependency tasks' do
26+
triggered_1 = ForemanTasks.trigger(Support::DummyDynflowAction)
27+
triggered_2 = ForemanTasks.trigger(Support::DummyDynflowAction)
28+
triggered_1.finished.wait(30)
29+
triggered_2.finished.wait(30)
30+
dependency_task_1 = ForemanTasks::Task::DynflowTask.find_by!(:external_id => triggered_1.id)
31+
dependency_task_2 = ForemanTasks::Task::DynflowTask.find_by!(:external_id => triggered_2.id)
2632

27-
task = ForemanTasks.chain([prerequisite_plan_1.id, prerequisite_plan_2.id], Support::DummyDynflowAction)
33+
task = ForemanTasks.chain([dependency_task_1, dependency_task_2], Support::DummyDynflowAction)
2834

2935
dependencies = ForemanTasks.dynflow.world.persistence.find_execution_plan_dependencies(task.execution_plan.id)
30-
assert_includes dependencies, prerequisite_plan_1.id
31-
assert_includes dependencies, prerequisite_plan_2.id
36+
assert_includes dependencies, dependency_task_1.external_id
37+
assert_includes dependencies, dependency_task_2.external_id
38+
end
39+
40+
it 'accepts dependency task objects' do
41+
triggered = ForemanTasks.trigger(Support::DummyDynflowAction)
42+
triggered.finished.wait(30)
43+
dependency_task = ForemanTasks::Task::DynflowTask.find_by!(:external_id => triggered.id)
44+
45+
task = ForemanTasks.chain(dependency_task, Support::DummyDynflowAction)
46+
47+
dependencies = ForemanTasks.dynflow.world.persistence.find_execution_plan_dependencies(task.execution_plan.id)
48+
assert_includes dependencies, dependency_task.external_id
49+
end
50+
51+
it 'accepts dependency tasks as a relation' do
52+
triggered = ForemanTasks.trigger(Support::DummyDynflowAction)
53+
triggered.finished.wait(30)
54+
dependency_task = ForemanTasks::Task::DynflowTask.find_by!(:external_id => triggered.id)
55+
56+
task = ForemanTasks.chain(ForemanTasks::Task::DynflowTask.where(:id => dependency_task.id), Support::DummyDynflowAction)
57+
58+
dependencies = ForemanTasks.dynflow.world.persistence.find_execution_plan_dependencies(task.execution_plan.id)
59+
assert_includes dependencies, dependency_task.external_id
3260
end
3361
end
3462
end
35-

0 commit comments

Comments
 (0)