foreman-tasks 9.1.0 → 9.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/ruby_tests.yml +2 -0
- data/.rubocop.yml +6 -35
- data/.rubocop_todo.yml +216 -24
- data/Gemfile +2 -17
- data/app/controllers/foreman_tasks/tasks_controller.rb +8 -9
- data/app/models/foreman_tasks/remote_task.rb +3 -0
- data/app/models/foreman_tasks/task/dynflow_task.rb +4 -0
- data/foreman-tasks.gemspec +1 -1
- data/lib/foreman_tasks/tasks/export_tasks.rake +2 -2
- data/lib/foreman_tasks/version.rb +1 -1
- data/test/controllers/api/tasks_controller_test.rb +17 -17
- data/test/controllers/tasks_controller_test.rb +6 -6
- data/test/helpers/foreman_tasks/foreman_tasks_helper_test.rb +7 -7
- data/test/helpers/foreman_tasks/tasks_helper_test.rb +3 -3
- data/test/lib/actions/middleware/keep_current_request_id_test.rb +3 -3
- data/test/lib/concerns/polling_action_extensions_test.rb +4 -4
- data/test/tasks/generate_task_actions_test.rb +1 -1
- data/test/unit/actions/action_with_sub_plans_test.rb +4 -4
- data/test/unit/actions/bulk_action_test.rb +9 -9
- data/test/unit/actions/proxy_action_test.rb +20 -20
- data/test/unit/actions/recurring_action_test.rb +15 -15
- data/test/unit/actions/trigger_proxy_batch_test.rb +4 -4
- data/test/unit/cleaner_test.rb +24 -24
- data/test/unit/locking_test.rb +8 -8
- data/test/unit/proxy_selector_test.rb +9 -9
- data/test/unit/recurring_logic_test.rb +31 -32
- data/test/unit/remote_task_test.rb +4 -4
- data/test/unit/task_groups_test.rb +4 -4
- data/test/unit/task_test.rb +51 -51
- data/test/unit/triggering_test.rb +11 -11
- data/test/unit/troubleshooting_help_generator_test.rb +6 -6
- data/test/unit/ui_notifications_test.rb +20 -21
- metadata +4 -4
@@ -10,9 +10,9 @@ module ForemanTasks
|
|
10
10
|
it 'prepares items for index correctly' do
|
11
11
|
stubs(:action_name).returns('index')
|
12
12
|
items = breadcrumb_items
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
assert_equal 1, items.count
|
14
|
+
assert_equal 'Tasks', items.first[:caption]
|
15
|
+
assert_nil items.first[:url]
|
16
16
|
end
|
17
17
|
|
18
18
|
it 'prepares items for show correctly' do
|
@@ -20,8 +20,8 @@ module ForemanTasks
|
|
20
20
|
@task.action = 'A task'
|
21
21
|
stubs(:action_name).returns('show')
|
22
22
|
items = breadcrumb_items
|
23
|
-
|
24
|
-
|
23
|
+
assert_equal(['Tasks', 'A task'], items.map { |i| i[:caption] })
|
24
|
+
assert_nil items.last[:url]
|
25
25
|
end
|
26
26
|
|
27
27
|
it 'prepares items for sub tasks correctly' do
|
@@ -31,8 +31,8 @@ module ForemanTasks
|
|
31
31
|
@task.action = 'A task'
|
32
32
|
stubs(:action_name).returns('sub_tasks')
|
33
33
|
items = breadcrumb_items
|
34
|
-
|
35
|
-
|
34
|
+
assert_equal(['Tasks', 'A task', 'Sub tasks'], items.map { |i| i[:caption] })
|
35
|
+
assert_nil items.last[:url]
|
36
36
|
end
|
37
37
|
end
|
38
38
|
end
|
@@ -12,11 +12,11 @@ module ForemanTasks
|
|
12
12
|
end
|
13
13
|
|
14
14
|
it 'formats the task input properly' do
|
15
|
-
|
15
|
+
assert_equal "Create user 'Anonymous Admin'", format_task_input(@task)
|
16
16
|
end
|
17
17
|
|
18
18
|
it 'displays the dash if task is nil' do
|
19
|
-
|
19
|
+
assert_equal '-', format_task_input(nil)
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
@@ -37,7 +37,7 @@ module ForemanTasks
|
|
37
37
|
|
38
38
|
it 'formats the task input properly' do
|
39
39
|
response = "product 'product-2'; organization 'test-0'"
|
40
|
-
|
40
|
+
assert_equal("Create #{response}", format_task_input(@task))
|
41
41
|
end
|
42
42
|
end
|
43
43
|
end
|
@@ -29,21 +29,21 @@ module ForemanTasks
|
|
29
29
|
it 'stores the id on planning' do
|
30
30
|
::Logging.mdc['request'] = expected_id
|
31
31
|
action = create_and_plan_action(DummyAction)
|
32
|
-
|
32
|
+
assert_equal expected_id, action.input[:current_request_id]
|
33
33
|
end
|
34
34
|
|
35
35
|
it 'restores the id for run' do
|
36
36
|
::Logging.mdc['request'] = expected_id
|
37
37
|
action = create_and_plan_action(DummyAction, true)
|
38
38
|
action = run_action action
|
39
|
-
|
39
|
+
assert_equal expected_id, action.output[:run_result]
|
40
40
|
end
|
41
41
|
|
42
42
|
it 'restores the id for finalize' do
|
43
43
|
::Logging.mdc['request'] = expected_id
|
44
44
|
action = create_and_plan_action(DummyAction, true)
|
45
45
|
action = finalize_action(run_action(action))
|
46
|
-
|
46
|
+
assert_equal expected_id, action.output[:finalize_result]
|
47
47
|
end
|
48
48
|
end
|
49
49
|
end
|
@@ -11,22 +11,22 @@ module ForemanTasks
|
|
11
11
|
let(:default_intervals) { [0.5, 1, 2, 4, 8, 16] }
|
12
12
|
|
13
13
|
it 'is extends the polling action module' do
|
14
|
-
|
14
|
+
assert_equal ForemanTasks::Concerns::PollingActionExtensions, ::Dynflow::Action::Polling.ancestors.first
|
15
15
|
end
|
16
16
|
|
17
17
|
it 'does not modify polling intervals by default' do
|
18
|
-
|
18
|
+
assert_equal default_intervals, Action.allocate.poll_intervals
|
19
19
|
end
|
20
20
|
|
21
21
|
it 'cannot make intervals shorter than 0.5 seconds' do
|
22
22
|
Setting.expects(:[]).with(:foreman_tasks_polling_multiplier).returns 0
|
23
|
-
|
23
|
+
assert_equal default_intervals.map { 0.5 }, Action.allocate.poll_intervals
|
24
24
|
end
|
25
25
|
|
26
26
|
it 'can be used to make the intervals longer' do
|
27
27
|
value = 5
|
28
28
|
Setting.expects(:[]).with(:foreman_tasks_polling_multiplier).returns value
|
29
|
-
|
29
|
+
assert_equal default_intervals.map { |i| i * value }, Action.allocate.poll_intervals
|
30
30
|
end
|
31
31
|
end
|
32
32
|
end
|
@@ -26,7 +26,7 @@ class GenerateTaskActionsTest < ActiveSupport::TestCase
|
|
26
26
|
end
|
27
27
|
|
28
28
|
assert_match(%r{Generating action for #{tasks.count} tasks}, stdout)
|
29
|
-
|
29
|
+
assert_equal tasks.count, ForemanTasks::Task.where(:action => label).count
|
30
30
|
assert_match(%r{Processed #{tasks.count}/#{tasks.count} tasks}, stdout)
|
31
31
|
end
|
32
32
|
|
@@ -48,15 +48,15 @@ module ForemanTasks
|
|
48
48
|
end
|
49
49
|
|
50
50
|
specify 'the sub-plan stores the information about its parent' do
|
51
|
-
|
52
|
-
|
51
|
+
assert_equal 1, task.sub_tasks.size
|
52
|
+
assert_equal ChildAction.name, task.sub_tasks.first.label
|
53
53
|
end
|
54
54
|
|
55
55
|
specify "the locks of the sub-plan don't colide with the locks of its parent" do
|
56
56
|
child_task = task.sub_tasks.first
|
57
|
-
assert_not
|
57
|
+
assert_not child_task.locks.any?, "the lock is ensured by the parent"
|
58
58
|
found = ForemanTasks::Link.for_resource(user).where(:task_id => child_task.id).any?
|
59
|
-
assert
|
59
|
+
assert found, "the action is linked properly"
|
60
60
|
end
|
61
61
|
end
|
62
62
|
end
|
@@ -37,20 +37,20 @@ module ForemanTasks
|
|
37
37
|
Target.expects(:unscoped).returns(Target)
|
38
38
|
Target.expects(:where).with(:id => targets.map(&:id)).returns(targets)
|
39
39
|
|
40
|
-
|
40
|
+
assert_equal targets.count, task.sub_tasks.count
|
41
41
|
success, failed = task.sub_tasks.partition { |sub_task| sub_task.result == 'success' }
|
42
|
-
|
43
|
-
|
42
|
+
assert_empty failed
|
43
|
+
assert_equal 5, success.count
|
44
44
|
end
|
45
45
|
|
46
46
|
specify 'it plans a task for each target even if target cannot be found' do
|
47
47
|
Target.expects(:unscoped).returns(Target)
|
48
48
|
Target.expects(:where).with(:id => targets.map(&:id)).returns(targets.take(4))
|
49
49
|
|
50
|
-
|
50
|
+
assert_equal targets.count, task.sub_tasks.count
|
51
51
|
success, failed = task.sub_tasks.partition { |sub_task| sub_task.result == 'success' }
|
52
|
-
|
53
|
-
|
52
|
+
assert_equal 4, success.count
|
53
|
+
assert_equal 1, failed.count
|
54
54
|
end
|
55
55
|
|
56
56
|
specify "it handles keyword arguments as indifferent hashes when they're being flattened" do
|
@@ -61,8 +61,8 @@ module ForemanTasks
|
|
61
61
|
task = ForemanTasks::Task.where(:external_id => triggered.id).first
|
62
62
|
wait_for { task.reload.state == 'stopped' }
|
63
63
|
task = task.sub_tasks.first
|
64
|
-
|
65
|
-
|
64
|
+
assert_equal 7, task.input[:kw_string]
|
65
|
+
assert_equal 7, task.input[:kw_symbol]
|
66
66
|
end
|
67
67
|
|
68
68
|
specify 'it allows setting concurrency limit' do
|
@@ -71,7 +71,7 @@ module ForemanTasks
|
|
71
71
|
|
72
72
|
triggered = ForemanTasks.trigger(ParentAction, ChildAction, targets, concurrency_limit: 25)
|
73
73
|
task = ForemanTasks::Task.where(:external_id => triggered.id).first
|
74
|
-
|
74
|
+
assert_equal 25, task.execution_plan.entry_action.concurrency_limit
|
75
75
|
end
|
76
76
|
end
|
77
77
|
end
|
@@ -46,17 +46,17 @@ module ForemanTasks
|
|
46
46
|
'proxy_action_name' => 'Proxy::DummyAction',
|
47
47
|
'callback' => { 'task_id' => Support::DummyProxyAction.proxy.uuid, 'step_id' => @run_step_id } } }
|
48
48
|
expected_call = ['support', { @action.execution_plan_id => action_input }]
|
49
|
-
|
49
|
+
assert_equal expected_call, proxy_call
|
50
50
|
end
|
51
51
|
|
52
52
|
describe 'with batch triggering' do
|
53
53
|
let(:batch_triggering) { true }
|
54
54
|
it 'create remote tasks for batch triggering' do
|
55
55
|
task = RemoteTask.first
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
56
|
+
assert_equal 'new', task.state
|
57
|
+
assert_equal @action.execution_plan_id, task.execution_plan_id
|
58
|
+
assert_equal 'support', task.operation
|
59
|
+
assert_nil task.remote_task_id
|
60
60
|
end
|
61
61
|
end
|
62
62
|
end
|
@@ -65,22 +65,22 @@ module ForemanTasks
|
|
65
65
|
it "doesn't trigger the corresponding action again on the proxy" do
|
66
66
|
action = run_action(@action)
|
67
67
|
|
68
|
-
|
68
|
+
assert_equal :suspended, action.state
|
69
69
|
|
70
|
-
|
70
|
+
assert_equal 1, Support::DummyProxyAction.proxy.log[:trigger_task].size
|
71
71
|
end
|
72
72
|
end
|
73
73
|
|
74
74
|
it 'supports skipping' do
|
75
75
|
action = run_action(@action, ::Dynflow::Action::Skip)
|
76
|
-
|
76
|
+
assert_equal :success, action.state
|
77
77
|
end
|
78
78
|
|
79
79
|
describe 'cancel' do
|
80
80
|
it 'sends the cancel event to the proxy when the cancel event is sent for the first time' do
|
81
81
|
action = run_action(@action, ::Dynflow::Action::Cancellable::Cancel)
|
82
|
-
|
83
|
-
|
82
|
+
assert_equal [action.execution_plan_id], Support::DummyProxyAction.proxy.log[:cancel_task].first
|
83
|
+
assert_equal :suspended, action.state
|
84
84
|
end
|
85
85
|
|
86
86
|
it 'cancels the action immediatelly when cancel event is sent for the second time' do
|
@@ -91,14 +91,14 @@ module ForemanTasks
|
|
91
91
|
e
|
92
92
|
end
|
93
93
|
|
94
|
-
|
95
|
-
|
94
|
+
assert_equal 1, Support::DummyProxyAction.proxy.log[:cancel_task].size
|
95
|
+
assert_match 'Cancel enforced', error.message
|
96
96
|
end
|
97
97
|
end
|
98
98
|
|
99
99
|
it 'saves the data comming from the proxy to the output and finishes' do
|
100
100
|
action = run_action(@action, ::Actions::ProxyAction::CallbackData.new('result' => 'success'))
|
101
|
-
|
101
|
+
assert_equal({ 'result' => 'success' }, action.output[:proxy_output])
|
102
102
|
end
|
103
103
|
|
104
104
|
it 'handles connection errors' do
|
@@ -112,12 +112,12 @@ module ForemanTasks
|
|
112
112
|
end
|
113
113
|
end
|
114
114
|
action = run_stubbed_action.call action
|
115
|
-
|
116
|
-
|
117
|
-
|
115
|
+
assert_equal :suspended, action.state
|
116
|
+
assert_equal 1, action.world.clock.pending_pings.length
|
117
|
+
assert_equal 1, action.output[:metadata][:failed_proxy_tasks].length
|
118
118
|
2.times { action.output[:metadata][:failed_proxy_tasks] << {} }
|
119
|
-
|
120
|
-
|
119
|
+
assert_raises(Errno::ECONNREFUSED) { run_stubbed_action.call action }
|
120
|
+
assert_equal :error, action.state
|
121
121
|
end
|
122
122
|
|
123
123
|
it 'hides secrets' do
|
@@ -127,12 +127,12 @@ module ForemanTasks
|
|
127
127
|
'foo' => 'bar',
|
128
128
|
'secrets' => secrets)
|
129
129
|
task = ForemanTasks::Task.where(:external_id => triggered.id).first
|
130
|
-
|
130
|
+
assert_equal 'Secrets hidden', task.input[:secrets]
|
131
131
|
triggered.future.wait # Wait for the task to get triggered before leaving the test
|
132
132
|
end
|
133
133
|
|
134
134
|
it 'wipes secrets' do
|
135
|
-
|
135
|
+
assert_equal secrets, @action.input[:secrets]
|
136
136
|
action = run_action(@action, ::Actions::ProxyAction::CallbackData.new('result' => 'success'))
|
137
137
|
|
138
138
|
# #wipe_secrets! gets called as a hook, hooks are not triggered when using action testing helpers
|
@@ -50,45 +50,45 @@ module ForemanTasks
|
|
50
50
|
end
|
51
51
|
|
52
52
|
specify 'it triggers the repeat when task is cancelled' do
|
53
|
-
|
54
|
-
|
53
|
+
assert_predicate recurring_task, :delayed?
|
54
|
+
assert_equal 1, recurring_logic.tasks.count
|
55
55
|
cancelled_events = recurring_task.execution_plan.cancel
|
56
56
|
cancelled_events.each(&:wait!)
|
57
57
|
recurring_logic.reload
|
58
|
-
|
58
|
+
assert_equal 2, recurring_logic.tasks.count
|
59
59
|
new_task = recurring_logic.tasks.find { |task| task.id != recurring_task.id }
|
60
|
-
|
61
|
-
|
60
|
+
assert_equal args, new_task.execution_plan.delay_record.args
|
61
|
+
assert_equal recurring_task.start_at + 1.year, new_task.start_at
|
62
62
|
end
|
63
63
|
|
64
64
|
specify 'it triggers the repeat when the task goes into planned state' do
|
65
65
|
delay_options = recurring_logic.generate_delay_options
|
66
66
|
task = ForemanTasks.delay HookedAction, delay_options, *args
|
67
|
-
|
67
|
+
assert_equal 1, recurring_logic.tasks.count
|
68
68
|
|
69
69
|
# Perform planning of the delayed plan
|
70
70
|
task.execution_plan.delay_record.plan
|
71
71
|
|
72
72
|
# Check a repetition was planned
|
73
|
-
|
73
|
+
assert_equal 2, recurring_logic.tasks.count
|
74
74
|
end
|
75
75
|
|
76
76
|
specify 'it does not trigger repeat when failing in run' do
|
77
77
|
delay_options = recurring_logic.generate_delay_options
|
78
78
|
task = ForemanTasks.delay HookedAction, delay_options, true, args.last
|
79
|
-
|
79
|
+
assert_equal 1, recurring_logic.tasks.count
|
80
80
|
|
81
81
|
# Perform the planning (trigger repeat)
|
82
82
|
task.execution_plan.delay_record.plan
|
83
|
-
|
83
|
+
assert_equal 2, recurring_logic.tasks.count
|
84
84
|
|
85
85
|
# Let it fail
|
86
86
|
task.execution_plan.delay_record.execute.finished.wait
|
87
87
|
task.reload
|
88
|
-
|
88
|
+
assert_equal 'error', task.result
|
89
89
|
|
90
90
|
# Check no new repetitions were planned
|
91
|
-
|
91
|
+
assert_equal 2, recurring_logic.tasks.count
|
92
92
|
end
|
93
93
|
|
94
94
|
specify 'it resets the request id on repetition' do
|
@@ -99,13 +99,13 @@ module ForemanTasks
|
|
99
99
|
|
100
100
|
delay_options = recurring_logic.generate_delay_options
|
101
101
|
task = ForemanTasks.delay HookedAction, delay_options, true, args.last
|
102
|
-
|
102
|
+
assert_equal expected_id, task.input[:current_request_id]
|
103
103
|
|
104
104
|
SecureRandom.stubs(:uuid).returns(new_id)
|
105
105
|
# Perform the planning (trigger repeat)
|
106
106
|
task.execution_plan.delay_record.plan
|
107
107
|
repetition = recurring_logic.tasks.find { |t| t.id != task.id }
|
108
|
-
|
108
|
+
assert_equal new_id, repetition.input[:current_request_id]
|
109
109
|
ensure
|
110
110
|
::Logging.mdc['request'] = old_id
|
111
111
|
end
|
@@ -114,11 +114,11 @@ module ForemanTasks
|
|
114
114
|
delay_options = past_recurring_logic.generate_delay_options
|
115
115
|
delay_options[:start_at] = Time.zone.now - 1.week
|
116
116
|
task = ForemanTasks.delay HookedAction, delay_options, *args
|
117
|
-
|
117
|
+
assert_equal 1, past_recurring_logic.tasks.count
|
118
118
|
|
119
119
|
task.execution_plan.delay_record.plan
|
120
120
|
# Post planning, a new task should be scheduled
|
121
|
-
|
121
|
+
assert_equal 2, past_recurring_logic.tasks.count
|
122
122
|
# The scheduled task should have the start date according to cron in future.
|
123
123
|
assert_equal (Time.zone.now + 1.minute).change(:sec => 0), past_recurring_logic.tasks.where(:state => "scheduled").first.start_at
|
124
124
|
end
|
@@ -13,8 +13,8 @@ module ForemanTasks
|
|
13
13
|
describe 'triggering' do
|
14
14
|
it 'doesnt run anything on trigger' do
|
15
15
|
Actions::TriggerProxyBatch.any_instance.expects(:trigger_remote_tasks_batch).never
|
16
|
-
|
17
|
-
|
16
|
+
assert_equal :suspended, triggered.state
|
17
|
+
assert_equal 0, triggered.output[:planned_count]
|
18
18
|
end
|
19
19
|
|
20
20
|
it 'triggers remote tasks on TriggerNextBatch' do
|
@@ -37,7 +37,7 @@ module ForemanTasks
|
|
37
37
|
Actions::TriggerProxyBatch.any_instance.expects(:trigger_remote_tasks_batch).once
|
38
38
|
triggered.output[:planned_count] = 0
|
39
39
|
action = run_action(triggered, Actions::TriggerProxyBatch::TriggerLastBatch)
|
40
|
-
|
40
|
+
assert_equal :success, action.state
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
@@ -57,7 +57,7 @@ module ForemanTasks
|
|
57
57
|
ForemanTasks::RemoteTask.expects(:batch_trigger).with(proxy_operation_name, grouped_remote_batch)
|
58
58
|
|
59
59
|
triggered.trigger_remote_tasks_batch
|
60
|
-
|
60
|
+
assert_equal batch_size, triggered.output[:planned_count]
|
61
61
|
end
|
62
62
|
end
|
63
63
|
end
|
data/test/unit/cleaner_test.rb
CHANGED
@@ -22,14 +22,14 @@ class TasksTest < ActiveSupport::TestCase
|
|
22
22
|
FactoryBot.create(:dynflow_task, :product_create_task)]
|
23
23
|
cleaner.expects(:tasks_to_csv)
|
24
24
|
cleaner.delete
|
25
|
-
|
26
|
-
|
25
|
+
assert_empty ForemanTasks::Task.where(id: tasks_to_delete)
|
26
|
+
assert_equal tasks_to_keep.map(&:id).sort, ForemanTasks::Task.where(id: tasks_to_keep).order(:id).map(&:id)
|
27
27
|
|
28
|
-
|
29
|
-
|
28
|
+
assert_equal 0, ForemanTasks.dynflow.world.persistence
|
29
|
+
.find_execution_plans(filters: { 'uuid' => tasks_to_delete.map(&:external_id) }).size
|
30
30
|
|
31
|
-
|
32
|
-
|
31
|
+
assert_equal tasks_to_keep.size, ForemanTasks.dynflow.world.persistence
|
32
|
+
.find_execution_plans(filters: { 'uuid' => tasks_to_keep.map(&:external_id) }).size
|
33
33
|
end
|
34
34
|
|
35
35
|
describe "#orphaned_dynflow_tasks" do
|
@@ -67,11 +67,11 @@ class TasksTest < ActiveSupport::TestCase
|
|
67
67
|
|
68
68
|
cleaner.expects(:tasks_to_csv)
|
69
69
|
cleaner.delete
|
70
|
-
|
71
|
-
|
70
|
+
assert_empty ForemanTasks::Task.where(id: tasks_to_delete)
|
71
|
+
assert_equal tasks_to_keep, ForemanTasks::Task.where(id: tasks_to_keep)
|
72
72
|
|
73
|
-
|
74
|
-
|
73
|
+
assert_nil ForemanTasks::Link.find_by(id: link_to_delete.id)
|
74
|
+
assert_not_nil ForemanTasks::Link.find_by(id: link_to_keep.id)
|
75
75
|
end
|
76
76
|
|
77
77
|
it 'supports passing empty filter (just delete all)' do
|
@@ -85,8 +85,8 @@ class TasksTest < ActiveSupport::TestCase
|
|
85
85
|
end]
|
86
86
|
cleaner.expects(:tasks_to_csv)
|
87
87
|
cleaner.delete
|
88
|
-
|
89
|
-
|
88
|
+
assert_empty ForemanTasks::Task.where(id: tasks_to_delete)
|
89
|
+
assert_equal tasks_to_keep, ForemanTasks::Task.where(id: tasks_to_keep)
|
90
90
|
end
|
91
91
|
|
92
92
|
it 'matches tasks with compound filters properly' do
|
@@ -100,8 +100,8 @@ class TasksTest < ActiveSupport::TestCase
|
|
100
100
|
task_to_keep.update!(:result => 'pending', :state => 'planned')
|
101
101
|
cleaner.expects(:tasks_to_csv)
|
102
102
|
cleaner.delete
|
103
|
-
|
104
|
-
|
103
|
+
assert_empty ForemanTasks::Task.where(id: tasks_to_delete)
|
104
|
+
assert_equal [task_to_keep], ForemanTasks::Task.where(id: task_to_keep)
|
105
105
|
end
|
106
106
|
|
107
107
|
it 'backs tasks up before deleting' do
|
@@ -117,11 +117,11 @@ class TasksTest < ActiveSupport::TestCase
|
|
117
117
|
cleaner.delete
|
118
118
|
w.close
|
119
119
|
header, *data = r.readlines.map(&:chomp)
|
120
|
-
|
120
|
+
assert_equal ForemanTasks::Task.attribute_names.join(','), header
|
121
121
|
expected_lines = tasks_to_delete.map { |task| task.attributes.values.to_csv.chomp }
|
122
|
-
|
123
|
-
expected_lines.each { |line|
|
124
|
-
|
122
|
+
assert_equal expected_lines.count, data.count
|
123
|
+
expected_lines.each { |line| assert_includes data, line }
|
124
|
+
assert_empty ForemanTasks::Task.where(id: tasks_to_delete)
|
125
125
|
end
|
126
126
|
|
127
127
|
class ActionWithCleanup < Actions::Base
|
@@ -135,7 +135,7 @@ class TasksTest < ActiveSupport::TestCase
|
|
135
135
|
ForemanTasks::Cleaner.stubs(:cleanup_settings => {})
|
136
136
|
actions = ForemanTasks::Cleaner.actions_with_default_cleanup
|
137
137
|
example = actions.find { |rule| rule.klass == ActionWithCleanup }
|
138
|
-
|
138
|
+
assert_equal '15d', example.after
|
139
139
|
end
|
140
140
|
|
141
141
|
it 'searches for the actions that have the cleanup_after defined' do
|
@@ -143,7 +143,7 @@ class TasksTest < ActiveSupport::TestCase
|
|
143
143
|
{ :actions => [{ :name => ActionWithCleanup.name, :after => '5d' }] })
|
144
144
|
actions = ForemanTasks::Cleaner.actions_with_default_cleanup
|
145
145
|
example = actions.find { |rule| rule.klass == ActionWithCleanup }
|
146
|
-
|
146
|
+
assert_equal '5d', example.after
|
147
147
|
end
|
148
148
|
|
149
149
|
it 'generates filters from rules properly' do
|
@@ -157,10 +157,10 @@ class TasksTest < ActiveSupport::TestCase
|
|
157
157
|
:override_actions => true, :states => 'all' }]
|
158
158
|
ForemanTasks::Cleaner.stubs(:cleanup_settings).returns(:rules => rules)
|
159
159
|
r1, r2 = ForemanTasks::Cleaner.actions_by_rules actions_with_default
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
160
|
+
assert_equal '(NOT ((label ^ (action1, action2)))) AND (label = something)', r1[:filter]
|
161
|
+
assert_equal %w[stopped paused], r1[:states]
|
162
|
+
assert_equal '(label = something_else)', r2[:filter]
|
163
|
+
assert_equal [], r2[:states]
|
164
164
|
end
|
165
165
|
end
|
166
166
|
end
|
data/test/unit/locking_test.rb
CHANGED
@@ -32,14 +32,14 @@ module ForemanTasks
|
|
32
32
|
|
33
33
|
it 'can lock a resource for a single task only once' do
|
34
34
|
Lock.lock!(resource, task1)
|
35
|
-
|
35
|
+
assert_equal 1, Lock.for_resource(resource).count
|
36
36
|
Lock.lock!(resource, task1)
|
37
|
-
|
37
|
+
assert_equal 1, Lock.for_resource(resource).count
|
38
38
|
end
|
39
39
|
|
40
40
|
it 'cannot lock a resource for multiple tasks' do
|
41
41
|
lock = Lock.lock!(resource, task1)
|
42
|
-
|
42
|
+
assert_equal [lock], Lock.colliding_locks(resource, task2)
|
43
43
|
assert_raises Lock::LockConflict do
|
44
44
|
Lock.lock!(resource, task2)
|
45
45
|
end
|
@@ -52,13 +52,13 @@ module ForemanTasks
|
|
52
52
|
exception = assert_raises Lock::LockConflict do
|
53
53
|
Lock.lock!(resource, task2)
|
54
54
|
end
|
55
|
-
|
55
|
+
assert_match(/#{lock.task_id}/, exception.message)
|
56
56
|
end
|
57
57
|
|
58
58
|
it 'creates a link when creating a lock for a resource' do
|
59
59
|
Lock.lock!(resource, task1)
|
60
60
|
link = Link.for_resource(resource).first
|
61
|
-
|
61
|
+
assert_equal task1.id, link.task_id
|
62
62
|
end
|
63
63
|
end
|
64
64
|
|
@@ -69,15 +69,15 @@ module ForemanTasks
|
|
69
69
|
|
70
70
|
it 'can link a resource for a single task only once' do
|
71
71
|
Link.link!(resource, task1)
|
72
|
-
|
72
|
+
assert_equal 1, Link.for_resource(resource).count
|
73
73
|
Link.link!(resource, task1)
|
74
|
-
|
74
|
+
assert_equal 1, Link.for_resource(resource).count
|
75
75
|
end
|
76
76
|
|
77
77
|
it 'can link a resource to multiple tasks' do
|
78
78
|
Link.link!(resource, task1)
|
79
79
|
Link.link!(resource, task2)
|
80
|
-
|
80
|
+
assert_equal 2, Link.for_resource(resource).count
|
81
81
|
end
|
82
82
|
end
|
83
83
|
end
|
@@ -18,22 +18,22 @@ describe ForemanTasks::ProxySelector do
|
|
18
18
|
found << proxy_selector.select_by_jobs_count(proxies)
|
19
19
|
end
|
20
20
|
|
21
|
-
|
22
|
-
|
23
|
-
|
21
|
+
assert_equal count, available.count
|
22
|
+
assert_equal count - 1, available.uniq.count
|
23
|
+
assert_equal 1, proxy_selector.offline.count
|
24
24
|
end
|
25
25
|
|
26
26
|
it 'returns nil for if no proxy is available' do
|
27
|
-
|
27
|
+
assert_nil proxy_selector.select_by_jobs_count([])
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
31
31
|
describe '#determine_proxy' do
|
32
32
|
it 'returns :not_defined when avialable proxies returns empty hash' do
|
33
33
|
proxy_selector.stubs(:available_proxies => [])
|
34
|
-
|
34
|
+
assert_equal :not_defined, proxy_selector.determine_proxy
|
35
35
|
proxy_selector.stubs(:available_proxies => { :global => [] })
|
36
|
-
|
36
|
+
assert_equal :not_defined, proxy_selector.determine_proxy
|
37
37
|
end
|
38
38
|
|
39
39
|
it 'returns :not_available when proxies are set but offline' do
|
@@ -41,7 +41,7 @@ describe ForemanTasks::ProxySelector do
|
|
41
41
|
ProxyAPI::ForemanDynflow::DynflowProxy.any_instance.expects(:tasks_count).times(count).raises
|
42
42
|
proxy_selector.stubs(:available_proxies =>
|
43
43
|
{ :global => FactoryBot.create_list(:smart_proxy, count) })
|
44
|
-
|
44
|
+
assert_equal :not_available, proxy_selector.determine_proxy
|
45
45
|
end
|
46
46
|
|
47
47
|
it 'returns first available proxy, prioritizing by strategy' do
|
@@ -51,9 +51,9 @@ describe ForemanTasks::ProxySelector do
|
|
51
51
|
ForemanTasks::ProxySelector.any_instance.stubs(:available_proxies =>
|
52
52
|
{ :fallback => [fallback_proxy],
|
53
53
|
:global => [global_proxy] })
|
54
|
-
|
54
|
+
assert_equal fallback_proxy, ForemanTasks::ProxySelector.new.determine_proxy
|
55
55
|
ProxyAPI::ForemanDynflow::DynflowProxy.any_instance.expects(:tasks_count).raises.then.returns(0)
|
56
|
-
|
56
|
+
assert_equal global_proxy, ForemanTasks::ProxySelector.new.determine_proxy
|
57
57
|
end
|
58
58
|
end
|
59
59
|
end
|