foreman-tasks 4.1.5 → 5.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.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby_tests.yml +0 -1
  3. data/.rubocop.yml +0 -4
  4. data/.rubocop_todo.yml +0 -2
  5. data/README.md +8 -6
  6. data/app/assets/javascripts/foreman_tasks/trigger_form.js +7 -0
  7. data/app/controllers/foreman_tasks/api/tasks_controller.rb +2 -2
  8. data/app/controllers/foreman_tasks/tasks_controller.rb +2 -2
  9. data/app/graphql/mutations/recurring_logics/cancel.rb +27 -0
  10. data/app/graphql/types/recurring_logic.rb +21 -0
  11. data/app/graphql/types/task.rb +25 -0
  12. data/app/graphql/types/triggering.rb +16 -0
  13. data/app/helpers/foreman_tasks/foreman_tasks_helper.rb +4 -1
  14. data/app/lib/actions/helpers/with_continuous_output.rb +1 -1
  15. data/app/lib/actions/proxy_action.rb +2 -12
  16. data/app/lib/actions/trigger_proxy_batch.rb +79 -0
  17. data/app/models/foreman_tasks/recurring_logic.rb +10 -0
  18. data/app/models/foreman_tasks/remote_task.rb +3 -19
  19. data/app/models/foreman_tasks/task.rb +29 -0
  20. data/app/models/foreman_tasks/triggering.rb +14 -4
  21. data/app/views/foreman_tasks/api/tasks/show.json.rabl +1 -1
  22. data/app/views/foreman_tasks/layouts/react.html.erb +0 -1
  23. data/app/views/foreman_tasks/recurring_logics/index.html.erb +4 -2
  24. data/app/views/foreman_tasks/task_groups/recurring_logic_task_groups/_recurring_logic_task_group.html.erb +8 -0
  25. data/db/migrate/20210720115251_add_purpose_to_recurring_logic.rb +6 -0
  26. data/extra/foreman-tasks-cleanup.sh +127 -0
  27. data/extra/foreman-tasks-export.sh +121 -0
  28. data/foreman-tasks.gemspec +1 -4
  29. data/lib/foreman_tasks/continuous_output.rb +50 -0
  30. data/lib/foreman_tasks/engine.rb +8 -15
  31. data/lib/foreman_tasks/tasks/export_tasks.rake +29 -8
  32. data/lib/foreman_tasks/version.rb +1 -1
  33. data/lib/foreman_tasks.rb +2 -5
  34. data/locale/fr/LC_MESSAGES/foreman_tasks.mo +0 -0
  35. data/locale/ja/LC_MESSAGES/foreman_tasks.mo +0 -0
  36. data/locale/zh_CN/LC_MESSAGES/foreman_tasks.mo +0 -0
  37. data/package.json +7 -9
  38. data/test/controllers/api/tasks_controller_test.rb +19 -1
  39. data/test/controllers/tasks_controller_test.rb +19 -0
  40. data/test/factories/recurring_logic_factory.rb +7 -1
  41. data/test/graphql/mutations/recurring_logics/cancel_mutation_test.rb +66 -0
  42. data/test/graphql/queries/recurring_logic_test.rb +28 -0
  43. data/test/graphql/queries/recurring_logics_query_test.rb +30 -0
  44. data/test/graphql/queries/task_query_test.rb +33 -0
  45. data/test/graphql/queries/tasks_query_test.rb +31 -0
  46. data/test/support/dummy_proxy_action.rb +6 -0
  47. data/test/unit/actions/proxy_action_test.rb +11 -11
  48. data/test/unit/actions/trigger_proxy_batch_test.rb +59 -0
  49. data/test/unit/remote_task_test.rb +0 -8
  50. data/test/unit/task_test.rb +39 -8
  51. data/test/unit/triggering_test.rb +22 -0
  52. metadata +23 -26
  53. data/test/core/unit/dispatcher_test.rb +0 -43
  54. data/test/core/unit/runner_test.rb +0 -116
  55. data/test/core/unit/task_launcher_test.rb +0 -56
  56. data/test/foreman_tasks_core_test_helper.rb +0 -4
  57. data/test/unit/otp_manager_test.rb +0 -77
@@ -0,0 +1,28 @@
1
+ require 'foreman_tasks_test_helper'
2
+
3
+ module Queries
4
+ class RecurringLogicTest < GraphQLQueryTestCase
5
+ let(:query) do
6
+ <<-GRAPHQL
7
+ query($id: String!) {
8
+ recurringLogic(id: $id) {
9
+ id
10
+ cronLine
11
+ }
12
+ }
13
+ GRAPHQL
14
+ end
15
+
16
+ let(:cron_line) { '5 4 3 2 1' }
17
+ let(:recurring_logic) { FactoryBot.create(:recurring_logic, :cron_line => cron_line) }
18
+ let(:global_id) { Foreman::GlobalId.for(recurring_logic) }
19
+ let(:variables) { { id: global_id } }
20
+ let(:data) { result['data']['recurringLogic'] }
21
+
22
+ test "should fetch recurring logic" do
23
+ assert_empty result['errors']
24
+ assert_equal global_id, data['id']
25
+ assert_equal cron_line, data['cronLine']
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,30 @@
1
+ require 'foreman_tasks_test_helper'
2
+
3
+ module Queries
4
+ class RecurringLogicsTest < GraphQLQueryTestCase
5
+ let(:query) do
6
+ <<-GRAPHQL
7
+ query {
8
+ recurringLogics {
9
+ nodes {
10
+ id
11
+ cronLine
12
+ }
13
+ }
14
+ }
15
+ GRAPHQL
16
+ end
17
+
18
+ let(:data) { result['data']['recurringLogics'] }
19
+
20
+ setup do
21
+ FactoryBot.create_list(:recurring_logic, 2)
22
+ end
23
+
24
+ test "should fetch recurring logics" do
25
+ assert_empty result['errors']
26
+ expected_count = ::ForemanTasks::RecurringLogic.count
27
+ assert_not_equal 0, expected_count
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,33 @@
1
+ require 'foreman_tasks_test_helper'
2
+
3
+ module Queries
4
+ class TaskQueryTest < GraphQLQueryTestCase
5
+ let(:query) do
6
+ <<-GRAPHQL
7
+ query (
8
+ $id: String!
9
+ ) {
10
+ task(id: $id) {
11
+ id
12
+ action
13
+ result
14
+ }
15
+ }
16
+ GRAPHQL
17
+ end
18
+
19
+ let(:res) { 'inconclusive' }
20
+ let(:task) { FactoryBot.create(:some_task, :result => res) }
21
+
22
+ let(:global_id) { Foreman::GlobalId.for(task) }
23
+ let(:variables) { { id: global_id } }
24
+ let(:data) { result['data']['task'] }
25
+
26
+ test 'should fetch task data' do
27
+ assert_empty result['errors']
28
+
29
+ assert_equal global_id, data['id']
30
+ assert_equal task.result, data['result']
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,31 @@
1
+ require 'foreman_tasks_test_helper'
2
+
3
+ module Queries
4
+ class TasksQueryTest < GraphQLQueryTestCase
5
+ let(:query) do
6
+ <<-GRAPHQL
7
+ query {
8
+ tasks {
9
+ nodes {
10
+ id
11
+ action
12
+ result
13
+ }
14
+ }
15
+ }
16
+ GRAPHQL
17
+ end
18
+
19
+ let(:data) { result['data']['tasks'] }
20
+
21
+ setup do
22
+ FactoryBot.create_list(:some_task, 2)
23
+ end
24
+
25
+ test "should fetch recurring logics" do
26
+ assert_empty result['errors']
27
+ expected_count = ::ForemanTasks::Task.count
28
+ assert_not_equal 0, expected_count
29
+ end
30
+ end
31
+ end
@@ -36,6 +36,12 @@ module Support
36
36
  def statuses
37
37
  { version: DummyProxyVersion.new('1.21.0') }
38
38
  end
39
+
40
+ def launch_tasks(operation, args = {})
41
+ @log[:trigger_task] << [operation, args]
42
+ @task_triggered.fulfill(true)
43
+ { 'task_id' => @uuid, 'result' => 'success' }
44
+ end
39
45
  end
40
46
 
41
47
  class ProxySelector < ::ForemanTasks::ProxySelector
@@ -11,12 +11,11 @@ module ForemanTasks
11
11
  let(:batch_triggering) { false }
12
12
 
13
13
  before do
14
- Support::DummyProxyAction.any_instance.stubs(:with_batch_triggering?).returns(batch_triggering)
15
14
  Support::DummyProxyAction.reset
16
15
  RemoteTask.any_instance.stubs(:proxy).returns(Support::DummyProxyAction.proxy)
17
16
  Setting.stubs(:[]).with('foreman_tasks_proxy_action_retry_interval')
18
17
  Setting.stubs(:[]).with('foreman_tasks_proxy_action_retry_count')
19
- Setting.stubs(:[]).with('foreman_tasks_proxy_batch_trigger')
18
+ Setting.stubs(:[]).with('foreman_tasks_proxy_batch_trigger').returns(batch_triggering)
20
19
  @action = create_and_plan_action(Support::DummyProxyAction,
21
20
  Support::DummyProxyAction.proxy,
22
21
  'Proxy::DummyAction',
@@ -29,17 +28,18 @@ module ForemanTasks
29
28
  describe 'first run' do
30
29
  it 'triggers the corresponding action on the proxy' do
31
30
  proxy_call = Support::DummyProxyAction.proxy.log[:trigger_task].first
32
- expected_call = ['Proxy::DummyAction',
33
- { 'foo' => 'bar',
34
- 'secrets' => secrets,
35
- 'connection_options' =>
31
+ expected_call = ['single',
32
+ { :action_class => 'Proxy::DummyAction',
33
+ :action_input =>
34
+ { 'foo' => 'bar',
35
+ 'secrets' => secrets,
36
+ 'connection_options' =>
36
37
  { 'retry_interval' => 15, 'retry_count' => 4,
37
38
  'proxy_batch_triggering' => batch_triggering },
38
- 'use_batch_triggering' => batch_triggering,
39
- 'proxy_url' => 'proxy.example.com',
40
- 'proxy_action_name' => 'Proxy::DummyAction',
41
- "proxy_version" => { "major" => 1, "minor" => 21, "patch" => 0 },
42
- 'callback' => { 'task_id' => Support::DummyProxyAction.proxy.uuid, 'step_id' => @action.run_step_id } }]
39
+ 'use_batch_triggering' => batch_triggering,
40
+ 'proxy_url' => 'proxy.example.com',
41
+ 'proxy_action_name' => 'Proxy::DummyAction',
42
+ 'callback' => { 'task_id' => Support::DummyProxyAction.proxy.uuid, 'step_id' => @action.run_step_id } } }]
43
43
  _(proxy_call).must_equal(expected_call)
44
44
  end
45
45
 
@@ -0,0 +1,59 @@
1
+ require 'foreman_tasks_test_helper'
2
+
3
+ module ForemanTasks
4
+ class TriggerProxyBatchTest < ActiveSupport::TestCase
5
+ describe Actions::TriggerProxyBatch do
6
+ include ::Dynflow::Testing
7
+
8
+ let(:batch_size) { 20 }
9
+ let(:total_count) { 100 }
10
+ let(:action) { create_and_plan_action(Actions::TriggerProxyBatch, total_count: total_count, batch_size: batch_size) }
11
+ let(:triggered) { run_action(action) }
12
+
13
+ describe 'triggering' do
14
+ it 'doesnt run anything on trigger' do
15
+ Actions::TriggerProxyBatch.any_instance.expects(:trigger_remote_tasks_batch).never
16
+ _(triggered.state).must_equal :suspended
17
+ _(triggered.output[:planned_count]).must_equal 0
18
+ end
19
+
20
+ it 'triggers remote tasks on TriggerNextBatch' do
21
+ Actions::TriggerProxyBatch.any_instance.expects(:trigger_remote_tasks_batch).once
22
+ run_action(triggered, Actions::TriggerProxyBatch::TriggerNextBatch[1])
23
+ end
24
+
25
+ it 'triggers remote tasks on TriggerNextBatch defined number of times' do
26
+ Actions::TriggerProxyBatch.any_instance.expects(:trigger_remote_tasks_batch).twice
27
+ run_action(triggered, Actions::TriggerProxyBatch::TriggerNextBatch[2])
28
+ end
29
+
30
+ it 'triggers the last batch on resume' do
31
+ Actions::TriggerProxyBatch.any_instance.expects(:trigger_remote_tasks_batch).once
32
+ triggered.output[:planned_count] = ((total_count - 1) / batch_size) * batch_size
33
+ run_action(triggered)
34
+ end
35
+ end
36
+
37
+ describe '#trigger_remote_tasks_batch' do
38
+ let(:proxy_operation_name) { 'ansible_runner' }
39
+ let(:grouped_remote_batch) { Array.new(batch_size).map { |i| mock("RemoteTask#{i}") } }
40
+ let(:remote_tasks) do
41
+ m = mock('RemoteTaskARScope')
42
+ m.stubs(pending: m, order: m)
43
+ m.stubs(group_by: { proxy_operation_name => grouped_remote_batch })
44
+ m
45
+ end
46
+
47
+ it 'fetches batch_size of tasks and triggers them' do
48
+ remote_tasks.expects(:first).with(batch_size).returns(remote_tasks)
49
+ remote_tasks.expects(:size).returns(batch_size)
50
+ triggered.expects(:remote_tasks).returns(remote_tasks)
51
+ ForemanTasks::RemoteTask.expects(:batch_trigger).with(proxy_operation_name, grouped_remote_batch)
52
+
53
+ triggered.trigger_remote_tasks_batch
54
+ _(triggered.output[:planned_count]).must_equal(batch_size)
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -28,14 +28,6 @@ module ForemanTasks
28
28
  _(remote_task.remote_task_id).must_equal((remote_task.id + 5).to_s)
29
29
  end
30
30
  end
31
-
32
- it 'fallbacks to old way when batch trigger gets 404' do
33
- fake_proxy = mock
34
- fake_proxy.expects(:launch_tasks).raises(RestClient::NotFound.new)
35
- remote_tasks.first.expects(:proxy).returns(fake_proxy)
36
- remote_tasks.each { |task| task.expects(:trigger) }
37
- RemoteTask.batch_trigger('a_operation', remote_tasks)
38
- end
39
31
  end
40
32
  end
41
33
  end
@@ -296,12 +296,12 @@ class TasksTest < ActiveSupport::TestCase
296
296
  end
297
297
 
298
298
  describe 'search for resource_ids' do
299
- it 'finds tasks' do
300
- label = 'label1'
301
- resource_ids = [1, 2]
302
- resource_type = 'restype1'
299
+ label = 'label1'
300
+ resource_ids = [1, 2]
301
+ resource_type = 'restype1'
303
302
 
304
- task1_old = FactoryBot.create(
303
+ let(:task1_old) do
304
+ FactoryBot.create(
305
305
  :task_with_links,
306
306
  started_at: '2019-10-01 11:15:55',
307
307
  ended_at: '2019-10-01 11:15:57',
@@ -309,7 +309,9 @@ class TasksTest < ActiveSupport::TestCase
309
309
  label: label,
310
310
  resource_type: resource_type
311
311
  )
312
- task1_new = FactoryBot.create(
312
+ end
313
+ let(:task1_new) do
314
+ FactoryBot.create(
313
315
  :task_with_links,
314
316
  started_at: '2019-10-02 11:15:55',
315
317
  ended_at: '2019-10-02 11:15:57',
@@ -317,7 +319,9 @@ class TasksTest < ActiveSupport::TestCase
317
319
  label: label,
318
320
  resource_type: resource_type
319
321
  )
320
- task2 = FactoryBot.create(
322
+ end
323
+ let(:task2) do
324
+ FactoryBot.create(
321
325
  :task_with_links,
322
326
  started_at: '2019-10-03 11:15:55',
323
327
  ended_at: '2019-10-03 11:15:57',
@@ -325,7 +329,9 @@ class TasksTest < ActiveSupport::TestCase
325
329
  label: label,
326
330
  resource_type: resource_type
327
331
  )
328
- task3 = FactoryBot.create(
332
+ end
333
+ let(:task3) do
334
+ FactoryBot.create(
329
335
  :task_with_links,
330
336
  started_at: '2019-10-03 11:15:55',
331
337
  ended_at: '2019-10-03 11:15:57',
@@ -333,6 +339,13 @@ class TasksTest < ActiveSupport::TestCase
333
339
  label: label,
334
340
  resource_type: 'another_type'
335
341
  )
342
+ end
343
+
344
+ it 'finds tasks' do
345
+ task1_old
346
+ task1_new
347
+ task2
348
+ task3
336
349
 
337
350
  result = ForemanTasks::Task.search_for(
338
351
  "resource_id ^ (#{resource_ids.join(',')}) and resource_type = #{resource_type}"
@@ -343,5 +356,23 @@ class TasksTest < ActiveSupport::TestCase
343
356
  assert_includes result, task2
344
357
  assert_not_includes result, task3
345
358
  end
359
+
360
+ it 'finds latest task for each resource_id' do
361
+ task1_old
362
+ task1_new
363
+ task2
364
+ task3
365
+
366
+ result = ForemanTasks::Task.latest_tasks_by_resource_ids(
367
+ label,
368
+ resource_type,
369
+ resource_ids
370
+ )
371
+ assert_equal 2, result.length
372
+ assert_equal resource_ids, result.keys.sort
373
+ assert_equal task1_new, result[1]
374
+ assert_equal task2, result[2]
375
+ assert_not_includes result.values, task3
376
+ end
346
377
  end
347
378
  end
@@ -19,6 +19,28 @@ class TriggeringTest < ActiveSupport::TestCase
19
19
  triggering.recurring_logic.stubs(:valid?).returns(false)
20
20
  _(triggering).wont_be :valid?
21
21
  end
22
+
23
+ it 'is valid when recurring logic has purpose' do
24
+ logic = FactoryBot.build(:recurring_logic, :purpose => 'test', :state => 'active')
25
+ triggering = FactoryBot.build(:triggering, :recurring_logic => logic, :mode => :recurring, :input_type => :cronline, :cronline => '* * * * *')
26
+ _(triggering).must_be :valid?
27
+ end
28
+
29
+ it 'is invalid when recurring logic with given purpose exists' do
30
+ FactoryBot.create(:recurring_logic, :purpose => 'test', :state => 'active')
31
+ logic = FactoryBot.build(:recurring_logic, :purpose => 'test', :state => 'active')
32
+ triggering = FactoryBot.build(:triggering, :recurring_logic => logic, :mode => :recurring, :input_type => :cronline, :cronline => '* * * * *')
33
+ _(triggering).wont_be :valid?
34
+ end
35
+
36
+ it 'is valid when recurring logic with given purpose exists and is not active or disabled' do
37
+ ['finished', 'cancelled', 'failed'].each do |item|
38
+ FactoryBot.create(:recurring_logic, :purpose => 'test', :state => item)
39
+ end
40
+ logic = FactoryBot.build(:recurring_logic, :purpose => 'test')
41
+ triggering = FactoryBot.build(:triggering, :recurring_logic => logic, :mode => :recurring, :input_type => :cronline, :cronline => '* * * * *')
42
+ _(triggering).must_be :valid?
43
+ end
22
44
  end
23
45
 
24
46
  it 'cannot have mode set to arbitrary value' do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: foreman-tasks
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.1.5
4
+ version: 5.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ivan Nečas
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-08-31 00:00:00.000000000 Z
11
+ date: 2021-11-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dynflow
@@ -24,20 +24,6 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: 1.2.3
27
- - !ruby/object:Gem::Dependency
28
- name: foreman-tasks-core
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - ">="
32
- - !ruby/object:Gem::Version
33
- version: '0'
34
- type: :runtime
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - ">="
39
- - !ruby/object:Gem::Version
40
- version: '0'
41
27
  - !ruby/object:Gem::Dependency
42
28
  name: get_process_mem
43
29
  requirement: !ruby/object:Gem::Requirement
@@ -147,6 +133,10 @@ files:
147
133
  - app/controllers/foreman_tasks/react_controller.rb
148
134
  - app/controllers/foreman_tasks/recurring_logics_controller.rb
149
135
  - app/controllers/foreman_tasks/tasks_controller.rb
136
+ - app/graphql/mutations/recurring_logics/cancel.rb
137
+ - app/graphql/types/recurring_logic.rb
138
+ - app/graphql/types/task.rb
139
+ - app/graphql/types/triggering.rb
150
140
  - app/helpers/foreman_tasks/foreman_tasks_helper.rb
151
141
  - app/helpers/foreman_tasks/tasks_helper.rb
152
142
  - app/lib/actions/action_with_sub_plans.rb
@@ -176,6 +166,7 @@ files:
176
166
  - app/lib/actions/proxy_action.rb
177
167
  - app/lib/actions/recurring_action.rb
178
168
  - app/lib/actions/serializers/active_record_serializer.rb
169
+ - app/lib/actions/trigger_proxy_batch.rb
179
170
  - app/lib/foreman_tasks/concerns/polling_action_extensions.rb
180
171
  - app/lib/proxy_api/foreman_dynflow/dynflow_proxy.rb
181
172
  - app/models/foreman_tasks/concerns/action_subject.rb
@@ -259,6 +250,7 @@ files:
259
250
  - db/migrate/20200517215015_rename_bookmarks_controller.rb
260
251
  - db/migrate/20200519093217_drop_dynflow_allow_dangerous_actions_setting.foreman_tasks.rb
261
252
  - db/migrate/20200611090846_add_task_lock_index_on_resource_type_and_task_id.rb
253
+ - db/migrate/20210720115251_add_purpose_to_recurring_logic.rb
262
254
  - db/seeds.d/20-foreman_tasks_permissions.rb
263
255
  - db/seeds.d/30-notification_blueprints.rb
264
256
  - db/seeds.d/60-dynflow_proxy_feature.rb
@@ -267,12 +259,15 @@ files:
267
259
  - deploy/foreman-tasks.sysconfig
268
260
  - extra/dynflow-debug.sh
269
261
  - extra/dynflow-executor.example
262
+ - extra/foreman-tasks-cleanup.sh
263
+ - extra/foreman-tasks-export.sh
270
264
  - foreman-tasks.gemspec
271
265
  - gemfile.d/foreman-tasks.rb
272
266
  - lib/foreman-tasks.rb
273
267
  - lib/foreman_tasks.rb
274
268
  - lib/foreman_tasks/authorizer_ext.rb
275
269
  - lib/foreman_tasks/cleaner.rb
270
+ - lib/foreman_tasks/continuous_output.rb
276
271
  - lib/foreman_tasks/dynflow.rb
277
272
  - lib/foreman_tasks/dynflow/configuration.rb
278
273
  - lib/foreman_tasks/dynflow/console_authorizer.rb
@@ -306,14 +301,15 @@ files:
306
301
  - test/controllers/api/tasks_controller_test.rb
307
302
  - test/controllers/recurring_logics_controller_test.rb
308
303
  - test/controllers/tasks_controller_test.rb
309
- - test/core/unit/dispatcher_test.rb
310
- - test/core/unit/runner_test.rb
311
- - test/core/unit/task_launcher_test.rb
312
304
  - test/factories/recurring_logic_factory.rb
313
305
  - test/factories/task_factory.rb
314
306
  - test/factories/triggering_factory.rb
315
- - test/foreman_tasks_core_test_helper.rb
316
307
  - test/foreman_tasks_test_helper.rb
308
+ - test/graphql/mutations/recurring_logics/cancel_mutation_test.rb
309
+ - test/graphql/queries/recurring_logic_test.rb
310
+ - test/graphql/queries/recurring_logics_query_test.rb
311
+ - test/graphql/queries/task_query_test.rb
312
+ - test/graphql/queries/tasks_query_test.rb
317
313
  - test/helpers/foreman_tasks/foreman_tasks_helper_test.rb
318
314
  - test/helpers/foreman_tasks/tasks_helper_test.rb
319
315
  - test/lib/actions/middleware/keep_current_request_id_test.rb
@@ -332,11 +328,11 @@ files:
332
328
  - test/unit/actions/bulk_action_test.rb
333
329
  - test/unit/actions/proxy_action_test.rb
334
330
  - test/unit/actions/recurring_action_test.rb
331
+ - test/unit/actions/trigger_proxy_batch_test.rb
335
332
  - test/unit/cleaner_test.rb
336
333
  - test/unit/config/environment.rb
337
334
  - test/unit/dynflow_console_authorizer_test.rb
338
335
  - test/unit/locking_test.rb
339
- - test/unit/otp_manager_test.rb
340
336
  - test/unit/proxy_selector_test.rb
341
337
  - test/unit/recurring_logic_test.rb
342
338
  - test/unit/remote_task_test.rb
@@ -620,14 +616,15 @@ test_files:
620
616
  - test/controllers/api/tasks_controller_test.rb
621
617
  - test/controllers/recurring_logics_controller_test.rb
622
618
  - test/controllers/tasks_controller_test.rb
623
- - test/core/unit/dispatcher_test.rb
624
- - test/core/unit/runner_test.rb
625
- - test/core/unit/task_launcher_test.rb
626
619
  - test/factories/recurring_logic_factory.rb
627
620
  - test/factories/task_factory.rb
628
621
  - test/factories/triggering_factory.rb
629
- - test/foreman_tasks_core_test_helper.rb
630
622
  - test/foreman_tasks_test_helper.rb
623
+ - test/graphql/mutations/recurring_logics/cancel_mutation_test.rb
624
+ - test/graphql/queries/recurring_logic_test.rb
625
+ - test/graphql/queries/recurring_logics_query_test.rb
626
+ - test/graphql/queries/task_query_test.rb
627
+ - test/graphql/queries/tasks_query_test.rb
631
628
  - test/helpers/foreman_tasks/foreman_tasks_helper_test.rb
632
629
  - test/helpers/foreman_tasks/tasks_helper_test.rb
633
630
  - test/lib/actions/middleware/keep_current_request_id_test.rb
@@ -646,11 +643,11 @@ test_files:
646
643
  - test/unit/actions/bulk_action_test.rb
647
644
  - test/unit/actions/proxy_action_test.rb
648
645
  - test/unit/actions/recurring_action_test.rb
646
+ - test/unit/actions/trigger_proxy_batch_test.rb
649
647
  - test/unit/cleaner_test.rb
650
648
  - test/unit/config/environment.rb
651
649
  - test/unit/dynflow_console_authorizer_test.rb
652
650
  - test/unit/locking_test.rb
653
- - test/unit/otp_manager_test.rb
654
651
  - test/unit/proxy_selector_test.rb
655
652
  - test/unit/recurring_logic_test.rb
656
653
  - test/unit/remote_task_test.rb
@@ -1,43 +0,0 @@
1
- require 'foreman_tasks_core_test_helper'
2
- require 'foreman_tasks/test_helpers'
3
- require 'foreman_tasks_core/runner'
4
-
5
- module ForemanTasksCore
6
- module Runner
7
- describe Dispatcher::RunnerActor do
8
- include ForemanTasks::TestHelpers::WithInThreadExecutor
9
-
10
- let(:dispatcher) { Dispatcher.instance }
11
- let(:suspended_action) { mock }
12
- let(:runner) { mock.tap { |r| r.stubs(:id) } }
13
- let(:clock) { ForemanTasks.dynflow.world.clock }
14
- let(:logger) { mock.tap { |l| l.stubs(:debug) } }
15
- let(:actor) do
16
- Dispatcher::RunnerActor.new dispatcher, suspended_action, runner, clock, logger
17
- end
18
-
19
- it 'delivers all updates to actions' do
20
- targets = (0..2).map { mock }.each_with_index { |mock, index| mock.expects(:<<).with(index) }
21
- updates = targets.each_with_index.reduce({}) { |acc, (cur, index)| acc.merge(cur => index) }
22
- runner.expects(:run_refresh).returns(updates)
23
- actor.expects(:plan_next_refresh)
24
- actor.refresh_runner
25
- end
26
-
27
- it 'plans next refresh' do
28
- runner.expects(:run_refresh).returns({})
29
- actor.expects(:plan_next_refresh)
30
- actor.refresh_runner
31
- end
32
-
33
- it 'does not plan next resfresh if done' do
34
- update = Update.new(nil, 0)
35
- suspended_action.expects(:<<).with(update)
36
- runner.expects(:run_refresh).returns(suspended_action => update)
37
- dispatcher.expects(:finish)
38
- dispatcher.ticker.expects(:tell).never
39
- actor.refresh_runner
40
- end
41
- end
42
- end
43
- end
@@ -1,116 +0,0 @@
1
- require 'foreman_tasks_core_test_helper'
2
- require 'foreman_tasks/test_helpers'
3
- require 'foreman_tasks_core/runner'
4
- require 'ostruct'
5
-
6
- module ForemanTasksCore
7
- module Runner
8
- class RunnerTest < ActiveSupport::TestCase
9
- include ForemanTasks::TestHelpers::WithInThreadExecutor
10
-
11
- describe Base do
12
- let(:suspended_action) { Class.new }
13
- let(:runner) { Base.new suspended_action: suspended_action }
14
-
15
- describe '#generate_updates' do
16
- it 'returns empty hash when there are no outputs' do
17
- _(runner.generate_updates).must_be :empty?
18
- end
19
-
20
- it 'returns a hash with outputs' do
21
- message = 'a message'
22
- type = 'stdout'
23
- runner.publish_data(message, type)
24
- updates = runner.generate_updates
25
- _(updates.keys).must_equal [suspended_action]
26
- update = updates.values.first
27
- _(update.exit_status).must_be :nil?
28
- _(update.continuous_output.raw_outputs.count).must_equal 1
29
- end
30
-
31
- it 'works in compatibility mode' do
32
- runner = Base.new
33
- message = 'a message'
34
- type = 'stdout'
35
- runner.publish_data(message, type)
36
- updates = runner.generate_updates
37
- _(updates.keys).must_equal [nil]
38
- update = updates.values.first
39
- _(update.exit_status).must_be :nil?
40
- _(update.continuous_output.raw_outputs.count).must_equal 1
41
- end
42
- end
43
- end
44
-
45
- describe Parent do
46
- let(:suspended_action) { ::Dynflow::Action::Suspended.allocate }
47
- let(:runner) { Parent.new targets, suspended_action: suspended_action }
48
- let(:targets) do
49
- { 'foo' => { 'execution_plan_id' => '123', 'run_step_id' => 2 },
50
- 'bar' => { 'execution_plan_id' => '456', 'run_step_id' => 2 } }
51
- end
52
-
53
- describe '#initialize_continuous_outputs' do
54
- it 'initializes outputs for targets and parent' do
55
- outputs = runner.initialize_continuous_outputs
56
- _(outputs.keys.count).must_equal 2
57
- outputs.values.each { |output| _(output).must_be_instance_of ContinuousOutput }
58
- end
59
- end
60
-
61
- describe '#generate_updates' do
62
- it 'returns only updates for hosts with pending outputs' do
63
- _(runner.generate_updates).must_equal({})
64
- runner.publish_data_for('foo', 'something', 'something')
65
- updates = runner.generate_updates
66
- _(updates.keys.count).must_equal 1
67
- end
68
-
69
- it 'works without compatibility mode' do
70
- runner.broadcast_data('something', 'stdout')
71
- updates = runner.generate_updates
72
- _(updates.keys.count).must_equal 2
73
- updates.keys.each do |key|
74
- _(key).must_be_instance_of ::Dynflow::Action::Suspended
75
- end
76
- end
77
- end
78
-
79
- describe '#publish_data_for' do
80
- it 'publishes data for a single host' do
81
- runner.publish_data_for('foo', 'message', 'stdout')
82
- _(runner.generate_updates.keys.count).must_equal 1
83
- end
84
- end
85
-
86
- describe '#broadcast_data' do
87
- it 'publishes data for all hosts' do
88
- runner.broadcast_data('message', 'stdout')
89
- _(runner.generate_updates.keys.count).must_equal 2
90
- end
91
- end
92
-
93
- describe '#publish_exception' do
94
- let(:exception) do
95
- exception = RuntimeError.new
96
- exception.stubs(:backtrace).returns([])
97
- exception
98
- end
99
-
100
- before { runner.logger.stubs(:error) }
101
-
102
- it 'broadcasts the exception to all targets' do
103
- runner.expects(:publish_exit_status).never
104
- runner.publish_exception('general failure', exception, false)
105
- _(runner.generate_updates.keys.count).must_equal 2
106
- end
107
-
108
- it 'publishes exit status if fatal' do
109
- runner.expects(:publish_exit_status)
110
- runner.publish_exception('general failure', exception, true)
111
- end
112
- end
113
- end
114
- end
115
- end
116
- end