foreman-tasks 4.0.0 → 5.0.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 (43) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby_tests.yml +4 -3
  3. data/app/controllers/concerns/foreman_tasks/find_tasks_common.rb +14 -0
  4. data/app/controllers/foreman_tasks/api/tasks_controller.rb +4 -6
  5. data/app/controllers/foreman_tasks/tasks_controller.rb +3 -11
  6. data/app/graphql/types/recurring_logic.rb +18 -0
  7. data/app/graphql/types/task.rb +25 -0
  8. data/app/graphql/types/triggering.rb +16 -0
  9. data/app/lib/actions/helpers/with_continuous_output.rb +1 -1
  10. data/app/lib/actions/middleware/load_setting_values.rb +35 -0
  11. data/app/lib/actions/observable_action.rb +1 -1
  12. data/app/lib/actions/proxy_action.rb +2 -4
  13. data/app/models/foreman_tasks/recurring_logic.rb +2 -0
  14. data/app/models/foreman_tasks/task.rb +30 -2
  15. data/app/models/foreman_tasks/triggering.rb +2 -0
  16. data/db/migrate/20180927120509_add_user_id.foreman_tasks.rb +4 -2
  17. data/foreman-tasks.gemspec +0 -1
  18. data/lib/foreman_tasks.rb +2 -5
  19. data/lib/foreman_tasks/continuous_output.rb +50 -0
  20. data/lib/foreman_tasks/engine.rb +7 -15
  21. data/lib/foreman_tasks/version.rb +1 -1
  22. data/locale/action_names.rb +3 -2
  23. data/locale/en/foreman_tasks.po +60 -27
  24. data/locale/foreman_tasks.pot +180 -132
  25. data/locale/fr/foreman_tasks.po +61 -28
  26. data/locale/ja/foreman_tasks.po +61 -28
  27. data/locale/zh_CN/foreman_tasks.po +61 -28
  28. data/test/controllers/api/tasks_controller_test.rb +16 -1
  29. data/test/controllers/tasks_controller_test.rb +2 -2
  30. data/test/factories/task_factory.rb +31 -4
  31. data/test/graphql/queries/recurring_logic_test.rb +28 -0
  32. data/test/graphql/queries/recurring_logics_query_test.rb +30 -0
  33. data/test/graphql/queries/task_query_test.rb +33 -0
  34. data/test/graphql/queries/tasks_query_test.rb +31 -0
  35. data/test/unit/actions/proxy_action_test.rb +4 -1
  36. data/test/unit/task_test.rb +54 -23
  37. data/test/unit/triggering_test.rb +2 -2
  38. metadata +16 -26
  39. data/test/core/unit/dispatcher_test.rb +0 -43
  40. data/test/core/unit/runner_test.rb +0 -129
  41. data/test/core/unit/task_launcher_test.rb +0 -56
  42. data/test/foreman_tasks_core_test_helper.rb +0 -4
  43. data/test/unit/otp_manager_test.rb +0 -77
@@ -14,6 +14,9 @@ module ForemanTasks
14
14
  Support::DummyProxyAction.any_instance.stubs(:with_batch_triggering?).returns(batch_triggering)
15
15
  Support::DummyProxyAction.reset
16
16
  RemoteTask.any_instance.stubs(:proxy).returns(Support::DummyProxyAction.proxy)
17
+ Setting.stubs(:[]).with('foreman_tasks_proxy_action_retry_interval')
18
+ Setting.stubs(:[]).with('foreman_tasks_proxy_action_retry_count')
19
+ Setting.stubs(:[]).with('foreman_tasks_proxy_batch_trigger')
17
20
  @action = create_and_plan_action(Support::DummyProxyAction,
18
21
  Support::DummyProxyAction.proxy,
19
22
  'Proxy::DummyAction',
@@ -107,7 +110,7 @@ module ForemanTasks
107
110
  _(action.world.clock.pending_pings.length).must_equal 1
108
111
  _(action.output[:metadata][:failed_proxy_tasks].length).must_equal 1
109
112
  2.times { action.output[:metadata][:failed_proxy_tasks] << {} }
110
- _ { proc { action = run_stubbed_action.call action } }.must_raise(Errno::ECONNREFUSED)
113
+ _(proc { action = run_stubbed_action.call action }).must_raise(Errno::ECONNREFUSED)
111
114
  _(action.state).must_equal :error
112
115
  end
113
116
 
@@ -31,9 +31,9 @@ class TasksTest < ActiveSupport::TestCase
31
31
  assert_equal [@task_one], ForemanTasks::Task.search_for("user = #{@user_one.login}")
32
32
  end
33
33
 
34
- test 'cannot search by arbitrary key' do
35
- _ { proc { ForemanTasks::Task.search_for('user.my_key ~ 5') } }.must_raise(ScopedSearch::QueryNotSupported)
36
- _ { proc { ForemanTasks::Task.search_for('user. = 5') } }.must_raise(ScopedSearch::QueryNotSupported)
34
+ it 'cannot search by arbitrary key' do
35
+ _(proc { ForemanTasks::Task.search_for('user.my_key ~ 5') }).must_raise(ScopedSearch::QueryNotSupported)
36
+ _(proc { ForemanTasks::Task.search_for('user. = 5') }).must_raise(ScopedSearch::QueryNotSupported)
37
37
  end
38
38
 
39
39
  test 'can search the tasks by negated user' do
@@ -59,8 +59,8 @@ class TasksTest < ActiveSupport::TestCase
59
59
  end
60
60
 
61
61
  test 'cannot glob on user\'s id' do
62
- _ { proc { ForemanTasks::Task.search_for("user.id ~ something") } }.must_raise(ScopedSearch::QueryNotSupported)
63
- _ { proc { ForemanTasks::Task.search_for("user.id ~ 5") } }.must_raise(ScopedSearch::QueryNotSupported)
62
+ _(proc { ForemanTasks::Task.search_for("user.id ~ something") }).must_raise(ScopedSearch::QueryNotSupported)
63
+ _(proc { ForemanTasks::Task.search_for("user.id ~ 5") }).must_raise(ScopedSearch::QueryNotSupported)
64
64
  end
65
65
 
66
66
  test 'can search the tasks by user with wildcards' do
@@ -126,17 +126,17 @@ class TasksTest < ActiveSupport::TestCase
126
126
  end
127
127
 
128
128
  it 'raises an exception if duration is unknown' do
129
- _ { proc { ForemanTasks::Task.search_for('duration = "25 potatoes"') } }.must_raise ScopedSearch::QueryNotSupported
129
+ _(proc { ForemanTasks::Task.search_for('duration = "25 potatoes"') }).must_raise ScopedSearch::QueryNotSupported
130
130
  end
131
131
  end
132
132
 
133
133
  context 'by taxonomies' do
134
134
  test 'can search by taxonomies using IN' do
135
- assert_nothing_raised(PG::SyntaxError) { ForemanTasks::Task.search_for('location_id ^ (1)').first }
136
- assert_nothing_raised(PG::SyntaxError) { ForemanTasks::Task.search_for('organization_id ^ (1)').first }
137
- assert_nothing_raised(PG::SyntaxError) { ForemanTasks::Task.search_for('location_id ^ (1,2)').first }
138
- assert_nothing_raised(PG::SyntaxError) { ForemanTasks::Task.search_for('organization_id ^ (1,2)').first }
139
- assert_nothing_raised(PG::SyntaxError) { ForemanTasks::Task.search_for('organization_id = 1').first }
135
+ assert_nothing_raised { ForemanTasks::Task.search_for('location_id ^ (1)').first }
136
+ assert_nothing_raised { ForemanTasks::Task.search_for('organization_id ^ (1)').first }
137
+ assert_nothing_raised { ForemanTasks::Task.search_for('location_id ^ (1,2)').first }
138
+ assert_nothing_raised { ForemanTasks::Task.search_for('organization_id ^ (1,2)').first }
139
+ assert_nothing_raised { ForemanTasks::Task.search_for('organization_id = 1').first }
140
140
  end
141
141
  end
142
142
  end
@@ -296,43 +296,56 @@ 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(
305
- :task_with_locks,
303
+ let(:task1_old) do
304
+ FactoryBot.create(
305
+ :task_with_links,
306
306
  started_at: '2019-10-01 11:15:55',
307
307
  ended_at: '2019-10-01 11:15:57',
308
308
  resource_id: 1,
309
309
  label: label,
310
310
  resource_type: resource_type
311
311
  )
312
- task1_new = FactoryBot.create(
313
- :task_with_locks,
312
+ end
313
+ let(:task1_new) do
314
+ FactoryBot.create(
315
+ :task_with_links,
314
316
  started_at: '2019-10-02 11:15:55',
315
317
  ended_at: '2019-10-02 11:15:57',
316
318
  resource_id: 1,
317
319
  label: label,
318
320
  resource_type: resource_type
319
321
  )
320
- task2 = FactoryBot.create(
321
- :task_with_locks,
322
+ end
323
+ let(:task2) do
324
+ FactoryBot.create(
325
+ :task_with_links,
322
326
  started_at: '2019-10-03 11:15:55',
323
327
  ended_at: '2019-10-03 11:15:57',
324
328
  resource_id: 2,
325
329
  label: label,
326
330
  resource_type: resource_type
327
331
  )
328
- task3 = FactoryBot.create(
329
- :task_with_locks,
332
+ end
333
+ let(:task3) do
334
+ FactoryBot.create(
335
+ :task_with_links,
330
336
  started_at: '2019-10-03 11:15:55',
331
337
  ended_at: '2019-10-03 11:15:57',
332
338
  resource_id: 3,
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
@@ -24,7 +24,7 @@ class TriggeringTest < ActiveSupport::TestCase
24
24
  it 'cannot have mode set to arbitrary value' do
25
25
  triggering = FactoryBot.build(:triggering)
26
26
  _(triggering).must_be :valid?
27
- _ { proc { triggering.mode = 'bogus' } }.must_raise ArgumentError
28
- _ { proc { triggering.mode = 27 } }.must_raise ArgumentError
27
+ _(proc { triggering.mode = 'bogus' }).must_raise ArgumentError
28
+ _(proc { triggering.mode = 27 }).must_raise ArgumentError
29
29
  end
30
30
  end
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.0.0
4
+ version: 5.0.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-03-02 00:00:00.000000000 Z
11
+ date: 2021-06-15 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
@@ -138,6 +124,7 @@ files:
138
124
  - app/assets/javascripts/foreman_tasks/trigger_form.js
139
125
  - app/assets/stylesheets/foreman_tasks/foreman_tasks.css
140
126
  - app/assets/stylesheets/foreman_tasks/trigger_form.css
127
+ - app/controllers/concerns/foreman_tasks/find_tasks_common.rb
141
128
  - app/controllers/foreman_tasks/api/recurring_logics_controller.rb
142
129
  - app/controllers/foreman_tasks/api/tasks_controller.rb
143
130
  - app/controllers/foreman_tasks/concerns/hosts_controller_extension.rb
@@ -146,6 +133,9 @@ files:
146
133
  - app/controllers/foreman_tasks/react_controller.rb
147
134
  - app/controllers/foreman_tasks/recurring_logics_controller.rb
148
135
  - app/controllers/foreman_tasks/tasks_controller.rb
136
+ - app/graphql/types/recurring_logic.rb
137
+ - app/graphql/types/task.rb
138
+ - app/graphql/types/triggering.rb
149
139
  - app/helpers/foreman_tasks/foreman_tasks_helper.rb
150
140
  - app/helpers/foreman_tasks/tasks_helper.rb
151
141
  - app/lib/actions/action_with_sub_plans.rb
@@ -166,6 +156,7 @@ files:
166
156
  - app/lib/actions/middleware/keep_current_taxonomies.rb
167
157
  - app/lib/actions/middleware/keep_current_timezone.rb
168
158
  - app/lib/actions/middleware/keep_current_user.rb
159
+ - app/lib/actions/middleware/load_setting_values.rb
169
160
  - app/lib/actions/middleware/proxy_batch_triggering.rb
170
161
  - app/lib/actions/middleware/rails_executor_wrap.rb
171
162
  - app/lib/actions/middleware/recurring_logic.rb
@@ -272,6 +263,7 @@ files:
272
263
  - lib/foreman_tasks.rb
273
264
  - lib/foreman_tasks/authorizer_ext.rb
274
265
  - lib/foreman_tasks/cleaner.rb
266
+ - lib/foreman_tasks/continuous_output.rb
275
267
  - lib/foreman_tasks/dynflow.rb
276
268
  - lib/foreman_tasks/dynflow/configuration.rb
277
269
  - lib/foreman_tasks/dynflow/console_authorizer.rb
@@ -305,14 +297,14 @@ files:
305
297
  - test/controllers/api/tasks_controller_test.rb
306
298
  - test/controllers/recurring_logics_controller_test.rb
307
299
  - test/controllers/tasks_controller_test.rb
308
- - test/core/unit/dispatcher_test.rb
309
- - test/core/unit/runner_test.rb
310
- - test/core/unit/task_launcher_test.rb
311
300
  - test/factories/recurring_logic_factory.rb
312
301
  - test/factories/task_factory.rb
313
302
  - test/factories/triggering_factory.rb
314
- - test/foreman_tasks_core_test_helper.rb
315
303
  - test/foreman_tasks_test_helper.rb
304
+ - test/graphql/queries/recurring_logic_test.rb
305
+ - test/graphql/queries/recurring_logics_query_test.rb
306
+ - test/graphql/queries/task_query_test.rb
307
+ - test/graphql/queries/tasks_query_test.rb
316
308
  - test/helpers/foreman_tasks/foreman_tasks_helper_test.rb
317
309
  - test/helpers/foreman_tasks/tasks_helper_test.rb
318
310
  - test/lib/actions/middleware/keep_current_request_id_test.rb
@@ -336,7 +328,6 @@ files:
336
328
  - test/unit/dashboard_table_filter_test.rb
337
329
  - test/unit/dynflow_console_authorizer_test.rb
338
330
  - test/unit/locking_test.rb
339
- - test/unit/otp_manager_test.rb
340
331
  - test/unit/proxy_selector_test.rb
341
332
  - test/unit/recurring_logic_test.rb
342
333
  - test/unit/remote_task_test.rb
@@ -620,14 +611,14 @@ test_files:
620
611
  - test/controllers/api/tasks_controller_test.rb
621
612
  - test/controllers/recurring_logics_controller_test.rb
622
613
  - 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
614
  - test/factories/recurring_logic_factory.rb
627
615
  - test/factories/task_factory.rb
628
616
  - test/factories/triggering_factory.rb
629
- - test/foreman_tasks_core_test_helper.rb
630
617
  - test/foreman_tasks_test_helper.rb
618
+ - test/graphql/queries/recurring_logic_test.rb
619
+ - test/graphql/queries/recurring_logics_query_test.rb
620
+ - test/graphql/queries/task_query_test.rb
621
+ - test/graphql/queries/tasks_query_test.rb
631
622
  - test/helpers/foreman_tasks/foreman_tasks_helper_test.rb
632
623
  - test/helpers/foreman_tasks/tasks_helper_test.rb
633
624
  - test/lib/actions/middleware/keep_current_request_id_test.rb
@@ -651,7 +642,6 @@ test_files:
651
642
  - test/unit/dashboard_table_filter_test.rb
652
643
  - test/unit/dynflow_console_authorizer_test.rb
653
644
  - test/unit/locking_test.rb
654
- - test/unit/otp_manager_test.rb
655
645
  - test/unit/proxy_selector_test.rb
656
646
  - test/unit/recurring_logic_test.rb
657
647
  - 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,129 +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 3
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 in compatibility mode' do
70
- runner = Parent.new targets
71
- _(runner.generate_updates).must_equal({})
72
- runner.broadcast_data('something', 'stdout')
73
- updates = runner.generate_updates
74
- _(updates.keys.count).must_equal 3
75
- # One of the keys is nil in compatibility mode
76
- _(updates.keys.compact.count).must_equal 2
77
- updates.keys.compact.each do |key|
78
- _(key).must_be_instance_of ::Dynflow::Action::Suspended
79
- end
80
- end
81
-
82
- it 'works without compatibility mode' do
83
- runner.broadcast_data('something', 'stdout')
84
- updates = runner.generate_updates
85
- _(updates.keys.count).must_equal 3
86
- updates.keys.each do |key|
87
- _(key).must_be_instance_of ::Dynflow::Action::Suspended
88
- end
89
- end
90
- end
91
-
92
- describe '#publish_data_for' do
93
- it 'publishes data for a single host' do
94
- runner.publish_data_for('foo', 'message', 'stdout')
95
- _(runner.generate_updates.keys.count).must_equal 1
96
- end
97
- end
98
-
99
- describe '#broadcast_data' do
100
- it 'publishes data for all hosts' do
101
- runner.broadcast_data('message', 'stdout')
102
- _(runner.generate_updates.keys.count).must_equal 3
103
- end
104
- end
105
-
106
- describe '#publish_exception' do
107
- let(:exception) do
108
- exception = RuntimeError.new
109
- exception.stubs(:backtrace).returns([])
110
- exception
111
- end
112
-
113
- before { runner.logger.stubs(:error) }
114
-
115
- it 'broadcasts the exception to all targets' do
116
- runner.expects(:publish_exit_status).never
117
- runner.publish_exception('general failure', exception, false)
118
- _(runner.generate_updates.keys.count).must_equal 3
119
- end
120
-
121
- it 'publishes exit status if fatal' do
122
- runner.expects(:publish_exit_status)
123
- runner.publish_exception('general failure', exception, true)
124
- end
125
- end
126
- end
127
- end
128
- end
129
- end