foreman_remote_execution 14.0.2 → 14.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/api/v2/job_invocations_controller.rb +34 -17
  3. data/app/helpers/remote_execution_helper.rb +2 -2
  4. data/app/lib/actions/remote_execution/proxy_action.rb +10 -5
  5. data/app/lib/actions/remote_execution/run_host_job.rb +1 -1
  6. data/app/lib/actions/remote_execution/template_invocation_progress_logging.rb +2 -3
  7. data/app/views/api/v2/job_invocations/hosts.json.rabl +15 -0
  8. data/config/routes.rb +1 -0
  9. data/db/migrate/20240312133027_extend_template_invocation_events.rb +19 -0
  10. data/lib/foreman_remote_execution/version.rb +1 -1
  11. data/webpack/JobInvocationDetail/JobInvocationActions.js +1 -1
  12. data/webpack/JobInvocationDetail/JobInvocationConstants.js +84 -0
  13. data/webpack/JobInvocationDetail/JobInvocationDetail.scss +0 -1
  14. data/webpack/JobInvocationDetail/JobInvocationHostTable.js +210 -0
  15. data/webpack/JobInvocationDetail/JobInvocationSelectors.js +2 -2
  16. data/webpack/JobInvocationDetail/__tests__/MainInformation.test.js +5 -1
  17. data/webpack/JobInvocationDetail/__tests__/fixtures.js +9 -0
  18. data/webpack/JobInvocationDetail/index.js +56 -34
  19. data/webpack/__mocks__/foremanReact/components/HostDetails/DetailsCard/DefaultLoaderEmptyState.js +1 -2
  20. data/webpack/react_app/components/RecentJobsCard/JobStatusIcon.js +38 -7
  21. data/webpack/react_app/components/RecentJobsCard/constants.js +4 -0
  22. data/webpack/react_app/components/TargetingHosts/__tests__/__snapshots__/HostStatus.test.js.snap +1 -1
  23. data/webpack/react_app/components/TargetingHosts/components/HostStatus.js +6 -6
  24. metadata +6 -94
  25. data/.babelrc.js +0 -3
  26. data/.eslintignore +0 -3
  27. data/.eslintrc +0 -13
  28. data/.github/workflows/js_ci.yml +0 -32
  29. data/.github/workflows/release.yml +0 -16
  30. data/.github/workflows/ruby_ci.yml +0 -19
  31. data/.gitignore +0 -19
  32. data/.packit.yaml +0 -45
  33. data/.prettierrc +0 -4
  34. data/.rubocop.yml +0 -105
  35. data/.rubocop_todo.yml +0 -516
  36. data/.tx/config +0 -10
  37. data/Gemfile +0 -5
  38. data/app/mailers/.gitkeep +0 -0
  39. data/app/views/dashboard/.gitkeep +0 -0
  40. data/foreman_remote_execution.gemspec +0 -33
  41. data/jsconfig.json +0 -8
  42. data/test/benchmark/run_hosts_job_benchmark.rb +0 -70
  43. data/test/benchmark/targeting_benchmark.rb +0 -31
  44. data/test/factories/foreman_remote_execution_factories.rb +0 -147
  45. data/test/functional/api/v2/foreign_input_sets_controller_test.rb +0 -58
  46. data/test/functional/api/v2/job_invocations_controller_test.rb +0 -446
  47. data/test/functional/api/v2/job_templates_controller_test.rb +0 -110
  48. data/test/functional/api/v2/registration_controller_test.rb +0 -73
  49. data/test/functional/api/v2/remote_execution_features_controller_test.rb +0 -34
  50. data/test/functional/api/v2/template_invocations_controller_test.rb +0 -33
  51. data/test/functional/cockpit_controller_test.rb +0 -16
  52. data/test/functional/job_invocations_controller_test.rb +0 -132
  53. data/test/functional/job_templates_controller_test.rb +0 -31
  54. data/test/functional/ui_job_wizard_controller_test.rb +0 -16
  55. data/test/graphql/mutations/job_invocations/create_test.rb +0 -58
  56. data/test/graphql/queries/job_invocation_query_test.rb +0 -31
  57. data/test/graphql/queries/job_invocations_query_test.rb +0 -35
  58. data/test/helpers/remote_execution_helper_test.rb +0 -46
  59. data/test/support/remote_execution_helper.rb +0 -5
  60. data/test/test_plugin_helper.rb +0 -9
  61. data/test/unit/actions/run_host_job_test.rb +0 -115
  62. data/test/unit/actions/run_hosts_job_test.rb +0 -214
  63. data/test/unit/api_params_test.rb +0 -25
  64. data/test/unit/concerns/foreman_tasks_cleaner_extensions_test.rb +0 -29
  65. data/test/unit/concerns/host_extensions_test.rb +0 -219
  66. data/test/unit/concerns/nic_extensions_test.rb +0 -9
  67. data/test/unit/execution_task_status_mapper_test.rb +0 -92
  68. data/test/unit/input_template_renderer_test.rb +0 -503
  69. data/test/unit/job_invocation_composer_test.rb +0 -974
  70. data/test/unit/job_invocation_report_template_test.rb +0 -60
  71. data/test/unit/job_invocation_test.rb +0 -232
  72. data/test/unit/job_template_effective_user_test.rb +0 -37
  73. data/test/unit/job_template_test.rb +0 -316
  74. data/test/unit/remote_execution_feature_test.rb +0 -86
  75. data/test/unit/remote_execution_provider_test.rb +0 -298
  76. data/test/unit/renderer_scope_input_test.rb +0 -49
  77. data/test/unit/targeting_test.rb +0 -206
  78. data/test/unit/template_invocation_input_value_test.rb +0 -38
@@ -1,214 +0,0 @@
1
- require 'test_plugin_helper'
2
- require 'securerandom'
3
-
4
- module ForemanRemoteExecution
5
- class RunHostsJobTest < ActiveSupport::TestCase
6
- include Dynflow::Testing
7
-
8
- # Adding run_step_id wich is needed in RunHostsJob as a quick fix
9
- # it will be added to dynflow in the future see https://github.com/Dynflow/dynflow/pull/391
10
- # rubocop:disable Style/ClassAndModuleChildren
11
- class Dynflow::Testing::DummyPlannedAction
12
- def run_step_id
13
- Dynflow::Testing.get_id
14
- end
15
- end
16
- # rubocop:enable Style/ClassAndModuleChildren
17
-
18
- let(:host) { FactoryBot.create(:host, :with_execution) }
19
- let(:proxy) { host.remote_execution_proxies('SSH')[:subnet].first }
20
- let(:targeting) { FactoryBot.create(:targeting, :search_query => "name = #{host.name}", :user => User.current) }
21
- let(:job_invocation) do
22
- FactoryBot.build(:job_invocation, :with_template).tap do |invocation|
23
- invocation.targeting = targeting
24
- invocation.description = 'Some short description'
25
- invocation.password = 'changeme'
26
- invocation.key_passphrase = 'changemetoo'
27
- invocation.effective_user_password = 'sudopassword'
28
- invocation.save
29
- end
30
- end
31
-
32
- let(:uuid) { SecureRandom.uuid }
33
- let(:task) do
34
- OpenStruct.new(:id => uuid).tap do |o|
35
- o.stubs(:add_missing_task_groups)
36
- o.stubs(:task_groups).returns([])
37
- o.stubs(:pending?).returns(true)
38
- end
39
- end
40
- let(:action) do
41
- create_action(Actions::RemoteExecution::RunHostsJob).tap do |action|
42
- action.expects(:action_subject).with(job_invocation, job_features: [])
43
- ForemanTasks::Task::DynflowTask.stubs(:where).returns(mock.tap { |m| m.stubs(:first! => task) })
44
- end
45
- end
46
- let(:planned) do
47
- plan_action action, job_invocation
48
- end
49
-
50
- let(:delayed) do
51
- action.delay({ :start_at => Time.now.getlocal }, job_invocation)
52
- action
53
- end
54
-
55
- before do
56
- ProxyAPI::ForemanDynflow::DynflowProxy.any_instance.stubs(:tasks_count).returns(0)
57
- User.current = users :admin
58
- action
59
- end
60
-
61
- context 'targeting resolving' do
62
- it 'resolves dynamic targeting in plan' do
63
- targeting.targeting_type = 'dynamic_query'
64
- assert_not targeting.resolved?
65
- delayed
66
- assert_not targeting.resolved?
67
- planned
68
- assert_includes targeting.hosts, host
69
- end
70
-
71
- it 'resolves the hosts on static targeting in delay' do
72
- assert_not targeting.resolved?
73
- delayed
74
- assert_includes targeting.hosts, host
75
- # Verify Targeting#resolve_hosts! won't be hit again
76
- targeting.expects(:resolve_hosts!).never
77
- planned
78
- end
79
-
80
- it 'resolves the hosts on static targeting in plan phase if not resolved yet' do
81
- planned
82
- assert_includes targeting.hosts, host
83
- end
84
- end
85
-
86
- it 'triggers the RunHostJob actions on the resolved hosts in run phase' do
87
- planned.expects(:output).at_most(5).returns(:planned_count => 0)
88
- planned.expects(:trigger).with { |*args| args[0] == Actions::RemoteExecution::RunHostJob }
89
- planned.create_sub_plans
90
- end
91
-
92
- it 'uses the BindJobInvocation middleware' do
93
- planned
94
- assert_equal job_invocation.task_id, uuid
95
- end
96
-
97
- # In plan phase this is handled by #action_subject
98
- # which is expected in tests
99
- it 'sets input in delay phase when delayed' do
100
- job_invocation_hash = delayed.input[:job_invocation]
101
- assert_equal job_invocation_hash['id'], job_invocation.id
102
- assert_equal job_invocation_hash['name'], job_invocation.job_category
103
- assert_equal job_invocation_hash['description'], job_invocation.description
104
- planned # To make the expectations happy
105
- end
106
-
107
- describe '#proxy_batch_size' do
108
- it 'defaults to Setting[foreman_tasks_proxy_batch_size]' do
109
- Setting.expects(:[]).with('foreman_tasks_proxy_batch_size').returns(14)
110
- planned
111
- assert_equal 14, planned.proxy_batch_size
112
- end
113
-
114
- it 'gets the provider value' do
115
- provider = mock('provider')
116
- provider.expects(:proxy_batch_size).returns(15)
117
- JobTemplate.any_instance.expects(:provider).returns(provider)
118
-
119
- assert_equal 15, planned.proxy_batch_size
120
- end
121
- end
122
-
123
- describe 'concurrency control' do
124
- let(:level) { 5 }
125
-
126
- it 'can be disabled' do
127
- assert_nil planned.concurrency_limit
128
- end
129
-
130
- it 'can limit concurrency level' do
131
- job_invocation.expects(:concurrency_level).twice.returns(level)
132
- assert_equal level, planned.concurrency_limit
133
- end
134
- end
135
-
136
- describe 'notifications' do
137
- it 'creates drawer notification on succeess' do
138
- blueprint = planned.job_invocation.build_notification
139
- blueprint.expects(:deliver!)
140
- planned.job_invocation.expects(:build_notification).returns(blueprint)
141
- planned.notify_on_success(nil)
142
- end
143
-
144
- it 'creates drawer notification on failure' do
145
- blueprint = planned.job_invocation.build_notification
146
- blueprint.expects(:deliver!)
147
- planned.job_invocation.expects(:build_notification).returns(blueprint)
148
- planned.notify_on_failure(nil)
149
- end
150
-
151
- describe 'ignoring drawer notification' do
152
- before do
153
- blueprint = planned.job_invocation.build_notification
154
- blueprint.expects(:deliver!)
155
- planned.job_invocation.expects(:build_notification).returns(blueprint)
156
- end
157
-
158
- let(:mail) do
159
- object = mock
160
- object.stubs(:deliver_now)
161
- object
162
- end
163
-
164
- describe 'for user subscribed to all' do
165
- before do
166
- planned.expects(:mail_notification_preference).returns(UserMailNotification.new(:interval => RexMailNotification::ALL_JOBS))
167
- end
168
-
169
- it 'sends the mail notification on success' do
170
- RexJobMailer.expects(:job_finished).returns(mail)
171
- planned.notify_on_success(nil)
172
- end
173
-
174
- it 'sends the mail notification on failure' do
175
- RexJobMailer.expects(:job_finished).returns(mail)
176
- planned.notify_on_failure(nil)
177
- end
178
- end
179
-
180
- describe 'for user subscribed to failures' do
181
- before do
182
- planned.expects(:mail_notification_preference).returns(UserMailNotification.new(:interval => RexMailNotification::FAILED_JOBS))
183
- end
184
-
185
- it 'it does not send the mail notification on success' do
186
- RexJobMailer.expects(:job_finished).never
187
- planned.notify_on_success(nil)
188
- end
189
-
190
- it 'sends the mail notification on failure' do
191
- RexJobMailer.expects(:job_finished).returns(mail)
192
- planned.notify_on_failure(nil)
193
- end
194
- end
195
-
196
- describe 'for user subscribed to successful jobs' do
197
- before do
198
- planned.expects(:mail_notification_preference).returns(UserMailNotification.new(:interval => RexMailNotification::SUCCEEDED_JOBS))
199
- end
200
-
201
- it 'sends the mail notification on success' do
202
- RexJobMailer.expects(:job_finished).returns(mail)
203
- planned.notify_on_success(nil)
204
- end
205
-
206
- it 'does not send the mail notification on failure' do
207
- RexJobMailer.expects(:job_finished).never
208
- planned.notify_on_failure(nil)
209
- end
210
- end
211
- end
212
- end
213
- end
214
- end
@@ -1,25 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'test_plugin_helper'
4
-
5
- class ApiParamsTest < ActiveSupport::TestCase
6
- describe '#format_datetime' do
7
- let(:params) { JobInvocationComposer::ApiParams.allocate }
8
-
9
- it 'leaves empty string as is' do
10
- assert_equal params.send(:format_datetime, ''), ''
11
- end
12
-
13
- it 'honors explicitly supplied time zone' do
14
- Time.use_zone(ActiveSupport::TimeZone['America/New_York']) do
15
- assert_equal '2022-07-08 08:53', params.send(:format_datetime, '2022-07-08 12:53:20 UTC')
16
- end
17
- end
18
-
19
- it 'implicitly honors current user\'s time zone' do
20
- Time.use_zone(ActiveSupport::TimeZone['America/New_York']) do
21
- assert_equal '2022-07-08 12:53', params.send(:format_datetime, '2022-07-08 12:53:20')
22
- end
23
- end
24
- end
25
- end
@@ -1,29 +0,0 @@
1
- require 'test_plugin_helper'
2
-
3
- class ForemanRemoteExecutionForemanTasksCleanerExtensionsTest < ActiveSupport::TestCase
4
- # Apply the same stubbing as in foreman-tasks
5
- before do
6
- # To stop dynflow from backing up actions, execution_plans and steps
7
- ForemanTasks.dynflow.world.persistence.adapter.stubs(:backup_to_csv)
8
- ForemanTasks::Cleaner.any_instance.stubs(:say) # Make the tests silent
9
- # Hack to make the tests pass due to ActiveRecord shenanigans
10
- ForemanTasks::Cleaner.any_instance.stubs(:delete_orphaned_dynflow_tasks)
11
- end
12
-
13
- it 'tries to delete associated job invocations' do
14
- job = FactoryBot.create(:job_invocation, :with_task)
15
- ForemanTasks::Cleaner.new(:filter => "id = #{job.task.id}").delete
16
- assert_empty JobInvocation.where(:id => job.id)
17
- end
18
-
19
- it 'removes orphaned job invocations' do
20
- job = FactoryBot.create(:job_invocation, :with_task)
21
- assert_equal 1, JobInvocation.where(:id => job.id).count
22
- job.task.delete
23
- job.reload
24
- assert_nil job.task
25
- refute_nil job.task_id
26
- ForemanTasks::Cleaner.new(:filter => '').delete
27
- assert_empty JobInvocation.where(:id => job.id)
28
- end
29
- end
@@ -1,219 +0,0 @@
1
- require 'test_plugin_helper'
2
-
3
- class ForemanRemoteExecutionHostExtensionsTest < ActiveSupport::TestCase
4
- let(:provider) { 'SSH' }
5
-
6
- before { User.current = FactoryBot.build(:user, :admin) }
7
- after { User.current = nil }
8
-
9
- describe 'ssh specific params' do
10
- let(:host) { FactoryBot.create(:host, :with_execution) }
11
- let(:sshkey) { 'ssh-rsa AAAAB3NzaC1yc2EAAAABJQ foo@example.com' }
12
-
13
- before do
14
- SmartProxy.any_instance.stubs(:pubkey).returns(sshkey)
15
- Setting[:remote_execution_ssh_user] = 'root'
16
- Setting[:remote_execution_effective_user_method] = 'sudo'
17
- end
18
-
19
- it 'has ssh user in the parameters' do
20
- assert_equal Setting[:remote_execution_ssh_user], host.host_param('remote_execution_ssh_user')
21
- end
22
-
23
- it 'can override ssh user' do
24
- host.host_parameters << FactoryBot.create(:host_parameter, :host => host, :name => 'remote_execution_ssh_user', :value => 'amy')
25
- assert_equal 'amy', host.host_param('remote_execution_ssh_user')
26
- end
27
-
28
- it 'has effective user method in the parameters' do
29
- assert_equal Setting[:remote_execution_effective_user_method], host.host_param('remote_execution_effective_user_method')
30
- end
31
-
32
- it 'can override effective user method' do
33
- host.host_parameters << FactoryBot.create(:host_parameter, :host => host, :name => 'remote_execution_effective_user_method', :value => 'su')
34
- assert_equal 'su', host.host_param('remote_execution_effective_user_method')
35
- end
36
-
37
- it 'has ssh keys in the parameters' do
38
- assert_includes host.remote_execution_ssh_keys, sshkey
39
- end
40
-
41
- it 'merges ssh keys from host parameters and proxies' do
42
- key = 'ssh-rsa not-even-a-key something@somewhere.com'
43
- host.host_parameters << FactoryBot.create(:host_parameter, :host => host, :name => 'remote_execution_ssh_keys', :value => [key])
44
- assert_includes host.host_param('remote_execution_ssh_keys'), key
45
- assert_includes host.host_param('remote_execution_ssh_keys'), sshkey
46
- end
47
-
48
- it 'merges ssh key as a string from host parameters and proxies' do
49
- key = 'ssh-rsa not-even-a-key something@somewhere.com'
50
- host.host_parameters << FactoryBot.create(:host_parameter, :host => host, :name => 'remote_execution_ssh_keys', :value => key)
51
- assert_includes host.host_param('remote_execution_ssh_keys'), key
52
- assert_includes host.host_param('remote_execution_ssh_keys'), sshkey
53
- end
54
-
55
- it 'has ssh keys in the parameters even when no user specified' do
56
- # this is a case, when using the helper in provisioning templates
57
- FactoryBot.create(:smart_proxy, :ssh)
58
- host.interfaces.first.subnet.remote_execution_proxies.clear
59
- User.current = nil
60
- assert_includes host.remote_execution_ssh_keys, sshkey
61
- end
62
- end
63
-
64
- context 'host has multiple nics' do
65
- let(:host) { FactoryBot.build(:host, :with_execution) }
66
-
67
- it 'should only have one execution interface' do
68
- host.interfaces << FactoryBot.build(:nic_managed)
69
- host.interfaces.each { |interface| interface.execution = true }
70
- assert_predicate host, :valid?
71
- assert_equal 1, host.interfaces.count(&:execution?)
72
- end
73
-
74
- it 'returns the execution interface' do
75
- assert_kind_of Nic::Managed, host.execution_interface
76
- end
77
- end
78
-
79
- context 'scoped search' do
80
- let(:job) do
81
- job = FactoryBot.create(:job_invocation, :with_task)
82
- job.template_invocations << FactoryBot.create(:template_invocation, :with_host, :with_failed_task)
83
- job
84
- end
85
-
86
- let(:job2) do
87
- job = FactoryBot.create(:job_invocation, :with_task)
88
- job.template_invocations << FactoryBot.create(:template_invocation, :with_host, :with_failed_task)
89
- job
90
- end
91
-
92
- it 'finds hosts for job_invocation.id' do
93
- found_ids = Host.search_for("job_invocation.id = #{job.id}").map(&:id).sort
94
- assert_equal job.template_invocations_host_ids.sort, found_ids
95
- end
96
-
97
- it 'finds hosts by job_invocation.result' do
98
- success, failed = job.template_invocations
99
- .partition { |template| template.run_host_job_task.result == 'success' }
100
- found_ids = Host.search_for('job_invocation.result = success').map(&:id)
101
- assert_equal success.map(&:host_id), found_ids
102
- found_ids = Host.search_for('job_invocation.result = failed').map(&:id)
103
- assert_equal failed.map(&:host_id), found_ids
104
- end
105
-
106
- it 'finds hosts by job_invocation.id and job_invocation.result' do
107
- # Force evaluation of the jobs
108
- job
109
- job2
110
-
111
- assert_equal 2, Host.search_for("job_invocation.id = #{job.id}").count
112
- assert_equal 2, Host.search_for("job_invocation.id = #{job2.id}").count
113
- assert_equal 2, Host.search_for('job_invocation.result = success').count
114
- assert_equal 2, Host.search_for('job_invocation.result = failed').count
115
-
116
- success, failed = job.template_invocations
117
- .partition { |template| template.run_host_job_task.result == 'success' }
118
- found_ids = Host.search_for("job_invocation.id = #{job.id} AND job_invocation.result = success").map(&:id)
119
- assert_equal success.map(&:host_id), found_ids
120
- found_ids = Host.search_for("job_invocation.id = #{job.id} AND job_invocation.result = failed").map(&:id)
121
- assert_equal failed.map(&:host_id), found_ids
122
- end
123
- end
124
-
125
- describe 'proxy determination strategies' do
126
- context 'subnet strategy' do
127
- let(:host) { FactoryBot.build(:host, :with_execution) }
128
- it { assert_includes host.remote_execution_proxies(provider)[:subnet], host.subnet.remote_execution_proxies.first }
129
- end
130
-
131
- context 'fallback strategy' do
132
- let(:host) { FactoryBot.build(:host, :with_tftp_subnet) }
133
-
134
- context 'enabled' do
135
- before do
136
- Setting[:remote_execution_fallback_proxy] = true
137
- host.subnet.tftp.features << FactoryBot.create(:feature, :ssh)
138
- end
139
-
140
- it 'returns a fallback proxy' do
141
- assert_includes host.remote_execution_proxies(provider)[:fallback], host.subnet.tftp
142
- end
143
- end
144
-
145
- context 'disabled' do
146
- before do
147
- Setting[:remote_execution_fallback_proxy] = false
148
- host.subnet.tftp.features << FactoryBot.create(:feature, :ssh)
149
- end
150
-
151
- it 'returns no proxy' do
152
- assert_empty host.remote_execution_proxies(provider)[:fallback]
153
- end
154
- end
155
- end
156
-
157
- context 'global strategy' do
158
- let(:tax_organization) { FactoryBot.build(:organization) }
159
- let(:tax_location) { FactoryBot.build(:location) }
160
- let(:host) { FactoryBot.build(:host, :organization => tax_organization, :location => tax_location) }
161
- let(:proxy_in_taxonomies) { FactoryBot.create(:smart_proxy, :ssh, :organizations => [tax_organization], :locations => [tax_location]) }
162
- let(:proxy_no_taxonomies) { FactoryBot.create(:smart_proxy, :ssh) }
163
-
164
- context 'enabled' do
165
- before { Setting[:remote_execution_global_proxy] = true }
166
-
167
- it 'returns correct proxies confined by taxonomies' do
168
- proxy_in_taxonomies
169
- proxy_no_taxonomies
170
- assert_includes host.remote_execution_proxies(provider)[:global], proxy_in_taxonomies
171
- refute_includes host.remote_execution_proxies(provider)[:global], proxy_no_taxonomies
172
- end
173
- end
174
-
175
- context 'disabled' do
176
- before { Setting[:remote_execution_global_proxy] = false }
177
- it 'returns no proxy' do
178
- assert_empty host.remote_execution_proxies(provider)[:global]
179
- end
180
- end
181
- end
182
- end
183
-
184
- describe '#execution_scope' do
185
- let(:host) { FactoryBot.create(:host) }
186
- let(:infra_host) { FactoryBot.create(:host, :with_infrastructure_facet) }
187
-
188
- before do
189
- host
190
- infra_host
191
- end
192
-
193
- context 'without infrastructure host permission' do
194
- it 'omits the infrastructure host' do
195
- setup_user('view', 'hosts')
196
-
197
- hosts = ::Host::Managed.execution_scope
198
- assert_includes hosts, host
199
- refute_includes hosts, infra_host
200
- end
201
- end
202
-
203
- context 'with infrastructure host permission' do
204
- it 'finds the host as admin' do
205
- assert User.current.admin?
206
- hosts = ::Host::Managed.execution_scope
207
- assert_includes hosts, host
208
- assert_includes hosts, infra_host
209
- end
210
-
211
- it 'finds the host as user with needed permissions' do
212
- setup_user('execute_jobs_on', 'infrastructure_hosts')
213
- hosts = ::Host::Managed.execution_scope
214
- assert_includes hosts, host
215
- assert_includes hosts, infra_host
216
- end
217
- end
218
- end
219
- end
@@ -1,9 +0,0 @@
1
- require 'test_plugin_helper'
2
-
3
- class ForemanRemoteExecutionNicExtensionsTest < ActiveSupport::TestCase
4
- let(:host) { FactoryBot.create(:host) }
5
-
6
- it 'sets the first primary interface as the execution interface' do
7
- assert_equal host.interfaces.first, host.execution_interface
8
- end
9
- end
@@ -1,92 +0,0 @@
1
- require 'test_plugin_helper'
2
-
3
- class ExecutionTaskStatusMapperTest < ActiveSupport::TestCase
4
- describe '.sql_conditions_for(status)' do
5
- let(:subject) { HostStatus::ExecutionStatus::ExecutionTaskStatusMapper }
6
-
7
- it 'accepts status number as well as string representation' do
8
- assert_equal subject.sql_conditions_for('failed'), subject.sql_conditions_for(HostStatus::ExecutionStatus::ERROR)
9
- end
10
-
11
- it 'does not find any task for unknown state' do
12
- assert_equal [ '1 = 0' ], subject.sql_conditions_for(-1)
13
- end
14
- end
15
-
16
- let(:task) { ForemanTasks::Task.new }
17
- let(:mapper) { HostStatus::ExecutionStatus::ExecutionTaskStatusMapper.new(task) }
18
-
19
- describe '#status' do
20
- let(:subject) { mapper }
21
-
22
- describe 'is queued' do
23
- context 'when there is no task' do
24
- before { subject.task = nil }
25
- specify { assert_equal HostStatus::ExecutionStatus::QUEUED, subject.status }
26
- end
27
-
28
- context 'when the task is scheduled in future' do
29
- before { subject.task.state = 'scheduled' }
30
- specify { assert_equal HostStatus::ExecutionStatus::QUEUED, subject.status }
31
- end
32
- end
33
-
34
- context 'when task is stopped' do
35
- before { subject.task.state = 'stopped' }
36
-
37
- describe 'is succeeded' do
38
- context 'without error' do
39
- before { subject.task.result = 'success' }
40
- specify { assert_equal HostStatus::ExecutionStatus::OK, subject.status }
41
- end
42
- end
43
-
44
- describe 'is failed' do
45
- context 'with error' do
46
- before { subject.task.result = 'error' }
47
- specify { assert_equal HostStatus::ExecutionStatus::ERROR, subject.status }
48
- end
49
-
50
- context 'without error but just with warning (sub task failed)' do
51
- before { subject.task.result = 'warning' }
52
- specify { assert_equal HostStatus::ExecutionStatus::ERROR, subject.status }
53
- end
54
- end
55
- end
56
-
57
- context 'when task is pending' do
58
- before { subject.task.state = 'running' }
59
-
60
- describe 'is pending' do
61
- specify { assert_equal HostStatus::ExecutionStatus::RUNNING, subject.status }
62
- end
63
- end
64
- end
65
-
66
- describe '#status_label' do
67
- let(:subject) { mapper.status_label }
68
-
69
- context 'status is OK' do
70
- before do
71
- mapper.task.state = 'stopped'
72
- mapper.task.result = 'success'
73
- end
74
-
75
- it 'returns ok label' do
76
- assert_equal HostStatus::ExecutionStatus::STATUS_NAMES[HostStatus::ExecutionStatus::OK], subject
77
- end
78
- end
79
-
80
- context 'status is ERROR' do
81
- before do
82
- mapper.task.state = 'stopped'
83
- mapper.task.result = 'error'
84
- end
85
-
86
- it 'returns failed label' do
87
- assert_equal HostStatus::ExecutionStatus::STATUS_NAMES[HostStatus::ExecutionStatus::ERROR], subject
88
- end
89
- end
90
- end
91
-
92
- end