foreman_remote_execution 1.2.2 → 1.3.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/README.md +11 -0
- data/app/assets/javascripts/template_invocation.js +6 -11
- data/app/controllers/api/v2/job_templates_controller.rb +1 -0
- data/app/controllers/concerns/foreman/controller/parameters/remote_execution_feature.rb +1 -1
- data/app/controllers/job_invocations_controller.rb +6 -2
- data/app/controllers/job_templates_controller.rb +0 -5
- data/app/helpers/concerns/foreman_remote_execution/hosts_helper_extensions.rb +18 -2
- data/app/helpers/concerns/foreman_remote_execution/job_templates_extensions.rb +1 -2
- data/app/helpers/remote_execution_helper.rb +42 -41
- data/app/lib/actions/remote_execution/run_host_job.rb +2 -15
- data/app/lib/actions/remote_execution/run_hosts_job.rb +17 -3
- data/app/models/concerns/foreman_remote_execution/host_extensions.rb +7 -6
- data/app/models/input_template_renderer.rb +1 -1
- data/app/models/job_invocation.rb +23 -5
- data/app/models/remote_execution_feature.rb +16 -3
- data/app/models/setting/remote_execution.rb +4 -1
- data/app/models/ssh_execution_provider.rb +33 -2
- data/app/models/targeting.rb +7 -3
- data/app/views/api/v2/remote_execution_features/base.json.rabl +1 -1
- data/app/views/job_invocations/_form.html.erb +1 -4
- data/app/views/job_invocations/_host_name_td.html.erb +2 -1
- data/app/views/job_invocations/index.html.erb +1 -1
- data/app/views/job_invocations/show.html.erb +1 -1
- data/app/views/job_templates/_custom_tabs.html.erb +1 -4
- data/app/views/overrides/nics/_execution_interface.html.erb +2 -3
- data/app/views/remote_execution_features/index.html.erb +1 -1
- data/db/migrate/20170110145641_add_host_action_button_to_remote_execution_feature.rb +5 -0
- data/foreman_remote_execution.gemspec +1 -1
- data/lib/foreman_remote_execution/engine.rb +3 -1
- data/lib/foreman_remote_execution/version.rb +1 -1
- data/locale/action_names.rb +2 -5
- data/locale/de/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/de/foreman_remote_execution.po +13 -23
- data/locale/en/foreman_remote_execution.po +12 -22
- data/locale/en_GB/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/en_GB/foreman_remote_execution.po +12 -22
- data/locale/es/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/es/foreman_remote_execution.po +13 -23
- data/locale/foreman_remote_execution.pot +71 -80
- data/locale/fr/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/fr/foreman_remote_execution.po +13 -23
- data/locale/ja/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/ja/foreman_remote_execution.po +13 -23
- data/locale/ko/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/ko/foreman_remote_execution.po +13 -23
- data/locale/pt_BR/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/pt_BR/foreman_remote_execution.po +13 -23
- data/locale/ru/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/ru/foreman_remote_execution.po +13 -23
- data/locale/zh_CN/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/zh_CN/foreman_remote_execution.po +13 -23
- data/locale/zh_TW/LC_MESSAGES/foreman_remote_execution.mo +0 -0
- data/locale/zh_TW/foreman_remote_execution.po +13 -23
- data/test/benchmark/run_hosts_job_benchmark.rb +70 -0
- data/test/benchmark/targeting_benchmark.rb +31 -0
- data/test/factories/foreman_remote_execution_factories.rb +3 -0
- data/test/functional/api/v2/job_templates_controller_test.rb +1 -1
- data/test/unit/actions/run_hosts_job_test.rb +1 -0
- data/test/unit/concerns/host_extensions_test.rb +1 -4
- data/test/unit/job_invocation_test.rb +28 -1
- data/test/unit/remote_execution_feature_test.rb +40 -0
- data/test/unit/remote_execution_provider_test.rb +55 -1
- metadata +10 -7
- data/test/unit/actions/run_host_job_test.rb +0 -50
Binary file
|
@@ -97,8 +97,8 @@ msgstr "并发等级"
|
|
97
97
|
msgid "Control concurrency level and distribution over time"
|
98
98
|
msgstr "控制并行等级及分配时间"
|
99
99
|
|
100
|
-
msgid "Could not use any proxy. Consider configuring %{global_proxy} or %{
|
101
|
-
msgstr "
|
100
|
+
msgid "Could not use any proxy. Consider configuring %{global_proxy}, %{fallback_proxy} or %{no_proxy} in settings"
|
101
|
+
msgstr ""
|
102
102
|
|
103
103
|
msgid "Could not use any template used in the job invocation"
|
104
104
|
msgstr "无法使用在任务调用中使用的任意模板"
|
@@ -118,9 +118,6 @@ msgstr "创建重复任务"
|
|
118
118
|
msgid "Create a template input"
|
119
119
|
msgstr "创建模板输入"
|
120
120
|
|
121
|
-
msgid "Create architecture"
|
122
|
-
msgstr "生成架构"
|
123
|
-
|
124
121
|
msgid "Default user to use for SSH. You may override per host by setting a parameter called remote_execution_ssh_user."
|
125
122
|
msgstr "SSH 默认使用的用户。可设置 remote_execution_ssh_user 调用的参数替换每台主机设置。"
|
126
123
|
|
@@ -136,9 +133,6 @@ msgstr "删除任务模板"
|
|
136
133
|
msgid "Delete a template input"
|
137
134
|
msgstr "删除模板输入"
|
138
135
|
|
139
|
-
msgid "Delete architecture"
|
140
|
-
msgstr "删除架构"
|
141
|
-
|
142
136
|
msgid "Description"
|
143
137
|
msgstr "描述"
|
144
138
|
|
@@ -211,9 +205,6 @@ msgstr "已失败"
|
|
211
205
|
msgid "Failed rendering template: %s"
|
212
206
|
msgstr "修改模板失败:%s"
|
213
207
|
|
214
|
-
msgid "Failed to initialize command"
|
215
|
-
msgstr "初始化命令失败"
|
216
|
-
|
217
208
|
msgid "Feature input %{input_name} not defined in template %{template_name}"
|
218
209
|
msgstr "模板 %{template_name} 的功能输入 %{input_name} "
|
219
210
|
|
@@ -262,9 +253,6 @@ msgstr ""
|
|
262
253
|
msgid "Indicates that the action should be cancelled if it cannot be started before this time."
|
263
254
|
msgstr "表示如果在这个时间之前无法启动该操作,则应将其取消。"
|
264
255
|
|
265
|
-
msgid "Initialization error: %s"
|
266
|
-
msgstr "初始化出错:%s"
|
267
|
-
|
268
256
|
msgid "Input"
|
269
257
|
msgstr "输入"
|
270
258
|
|
@@ -391,9 +379,6 @@ msgstr "尚未完成任何执行"
|
|
391
379
|
msgid "No hosts found."
|
392
380
|
msgstr "未找到任何主机。"
|
393
381
|
|
394
|
-
msgid "No output"
|
395
|
-
msgstr "无输出结果"
|
396
|
-
|
397
382
|
msgid "No template mapped to feature %{feature_name}"
|
398
383
|
msgstr "没有与功能 %{feature_name} 映射的模板"
|
399
384
|
|
@@ -418,6 +403,12 @@ msgstr "等待处理"
|
|
418
403
|
msgid "Perform no more executions after this time"
|
419
404
|
msgstr "这个时间后不再执行任何操作"
|
420
405
|
|
406
|
+
msgid "Playbook execution failed"
|
407
|
+
msgstr ""
|
408
|
+
|
409
|
+
msgid "Port to use for SSH communication. Default port 22. You may override per host by setting a parameter called remote_execution_ssh_port."
|
410
|
+
msgstr ""
|
411
|
+
|
421
412
|
msgid "Preview"
|
422
413
|
msgstr "预览"
|
423
414
|
|
@@ -511,9 +502,6 @@ msgstr "将该任务调度为在将来的某个时间开始"
|
|
511
502
|
msgid "Schedule the job to start at a later time"
|
512
503
|
msgstr "将该任务调度为于稍后开始"
|
513
504
|
|
514
|
-
msgid "Script execution failed"
|
515
|
-
msgstr "脚本执行失败"
|
516
|
-
|
517
505
|
msgid "Scroll to bottom"
|
518
506
|
msgstr "滚动到底部"
|
519
507
|
|
@@ -699,9 +687,6 @@ msgstr "更新任务模板"
|
|
699
687
|
msgid "Update a template input"
|
700
688
|
msgstr "更新模板输入"
|
701
689
|
|
702
|
-
msgid "Update architecture"
|
703
|
-
msgstr "更新架构"
|
704
|
-
|
705
690
|
msgid "Use default description template"
|
706
691
|
msgstr "使用默认描述模板"
|
707
692
|
|
@@ -735,6 +720,11 @@ msgstr "应由什么用户运行此脚本(使用类似 sudo 的机制)。"
|
|
735
720
|
msgid "What user should be used to run the script (using sudo-like mechanisms). Defaults to a template parameter or global setting."
|
736
721
|
msgstr "应由什么用户运行此脚本(使用类似 sudo 的机制)。默认为模板参数或全局设置。"
|
737
722
|
|
723
|
+
msgid ""
|
724
|
+
"When enabled, the remote execution will try to run the commands directly, when no\n"
|
725
|
+
" proxy with remote execution feature is configured for the host."
|
726
|
+
msgstr ""
|
727
|
+
|
738
728
|
msgid "Whether it should be allowed to override the effective user from the invocation form."
|
739
729
|
msgstr "是否应允许使用调用形式替代有效用户。"
|
740
730
|
|
Binary file
|
@@ -97,8 +97,8 @@ msgstr "同步等級"
|
|
97
97
|
msgid "Control concurrency level and distribution over time"
|
98
98
|
msgstr "隨時間控制週期等級並散佈"
|
99
99
|
|
100
|
-
msgid "Could not use any proxy. Consider configuring %{global_proxy} or %{
|
101
|
-
msgstr "
|
100
|
+
msgid "Could not use any proxy. Consider configuring %{global_proxy}, %{fallback_proxy} or %{no_proxy} in settings"
|
101
|
+
msgstr ""
|
102
102
|
|
103
103
|
msgid "Could not use any template used in the job invocation"
|
104
104
|
msgstr "無法使用任何用於這工作祈願的範本"
|
@@ -118,9 +118,6 @@ msgstr "建立週期性工作"
|
|
118
118
|
msgid "Create a template input"
|
119
119
|
msgstr "建立範本輸入"
|
120
120
|
|
121
|
-
msgid "Create architecture"
|
122
|
-
msgstr "建立架構"
|
123
|
-
|
124
121
|
msgid "Default user to use for SSH. You may override per host by setting a parameter called remote_execution_ssh_user."
|
125
122
|
msgstr "使用 SSH 的預設使用者。您可以透過設定參數呼叫 remote_execution_ssh_user 來覆寫每台主機的設定。"
|
126
123
|
|
@@ -136,9 +133,6 @@ msgstr "刪除工作範本"
|
|
136
133
|
msgid "Delete a template input"
|
137
134
|
msgstr "刪除範本輸入"
|
138
135
|
|
139
|
-
msgid "Delete architecture"
|
140
|
-
msgstr "刪除架構"
|
141
|
-
|
142
136
|
msgid "Description"
|
143
137
|
msgstr "說明"
|
144
138
|
|
@@ -211,9 +205,6 @@ msgstr "已失敗"
|
|
211
205
|
msgid "Failed rendering template: %s"
|
212
206
|
msgstr "無法生成範本:%s"
|
213
207
|
|
214
|
-
msgid "Failed to initialize command"
|
215
|
-
msgstr "無法初始化指令"
|
216
|
-
|
217
208
|
msgid "Feature input %{input_name} not defined in template %{template_name}"
|
218
209
|
msgstr "未知的輸入 %{input_name} 未定義於範本 %{template_name}"
|
219
210
|
|
@@ -262,9 +253,6 @@ msgstr ""
|
|
262
253
|
msgid "Indicates that the action should be cancelled if it cannot be started before this time."
|
263
254
|
msgstr "這表示如果不能在這時間之前開始,就應該取消動作。"
|
264
255
|
|
265
|
-
msgid "Initialization error: %s"
|
266
|
-
msgstr "初始化錯誤:%s"
|
267
|
-
|
268
256
|
msgid "Input"
|
269
257
|
msgstr "輸入"
|
270
258
|
|
@@ -391,9 +379,6 @@ msgstr "尚無執行完成"
|
|
391
379
|
msgid "No hosts found."
|
392
380
|
msgstr "找不到主機。"
|
393
381
|
|
394
|
-
msgid "No output"
|
395
|
-
msgstr "沒有輸出"
|
396
|
-
|
397
382
|
msgid "No template mapped to feature %{feature_name}"
|
398
383
|
msgstr "沒有範本定義至功能 %{feature_name}"
|
399
384
|
|
@@ -418,6 +403,12 @@ msgstr "等待處理中"
|
|
418
403
|
msgid "Perform no more executions after this time"
|
419
404
|
msgstr "此時間之後不再進行任何執行"
|
420
405
|
|
406
|
+
msgid "Playbook execution failed"
|
407
|
+
msgstr ""
|
408
|
+
|
409
|
+
msgid "Port to use for SSH communication. Default port 22. You may override per host by setting a parameter called remote_execution_ssh_port."
|
410
|
+
msgstr ""
|
411
|
+
|
421
412
|
msgid "Preview"
|
422
413
|
msgstr "預覽"
|
423
414
|
|
@@ -511,9 +502,6 @@ msgstr "排程工作至未來時間"
|
|
511
502
|
msgid "Schedule the job to start at a later time"
|
512
503
|
msgstr "排程工作至晚一點的時間"
|
513
504
|
|
514
|
-
msgid "Script execution failed"
|
515
|
-
msgstr "執行 script 失敗"
|
516
|
-
|
517
505
|
msgid "Scroll to bottom"
|
518
506
|
msgstr "捲動至底端"
|
519
507
|
|
@@ -699,9 +687,6 @@ msgstr "更新工作範本"
|
|
699
687
|
msgid "Update a template input"
|
700
688
|
msgstr "更新範本輸入"
|
701
689
|
|
702
|
-
msgid "Update architecture"
|
703
|
-
msgstr "更新架構"
|
704
|
-
|
705
690
|
msgid "Use default description template"
|
706
691
|
msgstr "使用預設的描述範本"
|
707
692
|
|
@@ -735,6 +720,11 @@ msgstr "哪位使用者該用來執行此 script(使用類似 sudo 機制)"
|
|
735
720
|
msgid "What user should be used to run the script (using sudo-like mechanisms). Defaults to a template parameter or global setting."
|
736
721
|
msgstr "哪位使用者該用來執行此 script(使用類似 sudo 機制)。預設值設為範本參數或全域設定。"
|
737
722
|
|
723
|
+
msgid ""
|
724
|
+
"When enabled, the remote execution will try to run the commands directly, when no\n"
|
725
|
+
" proxy with remote execution feature is configured for the host."
|
726
|
+
msgstr ""
|
727
|
+
|
738
728
|
msgid "Whether it should be allowed to override the effective user from the invocation form."
|
739
729
|
msgstr "是否允許從祈願清單覆寫有效使用者。"
|
740
730
|
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require "benchmark/benchmark_helper"
|
2
|
+
require 'dynflow/testing'
|
3
|
+
|
4
|
+
# Add plugin to FactoryGirl's paths
|
5
|
+
FactoryGirl.definition_file_paths << File.expand_path('../../factories', __FILE__)
|
6
|
+
FactoryGirl.definition_file_paths << "#{ForemanTasks::Engine.root}/test/factories"
|
7
|
+
FactoryGirl.reload
|
8
|
+
|
9
|
+
module Actions
|
10
|
+
module RemoteExecution
|
11
|
+
class RunHostsJob < Actions::ActionWithSubPlans
|
12
|
+
# stub function that calls other actions.
|
13
|
+
def trigger(*args)
|
14
|
+
nil
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
module Support
|
21
|
+
class DummyDynflowAction < Dynflow::Action
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def generate_hosts(total)
|
26
|
+
FactoryGirl.create_list(:host, total, :comment => "benchmark-#{Foreman.uuid}")
|
27
|
+
end
|
28
|
+
|
29
|
+
Rails.logger.level = Logger::ERROR
|
30
|
+
|
31
|
+
class ActionTester
|
32
|
+
include Dynflow::Testing::Factories
|
33
|
+
|
34
|
+
def initialize(task)
|
35
|
+
@task = task
|
36
|
+
end
|
37
|
+
|
38
|
+
def run_action(*args)
|
39
|
+
action = create_action(Actions::RemoteExecution::RunHostsJob)
|
40
|
+
@task.update_attributes(:external_id => action.execution_plan_id)
|
41
|
+
plan_action(action, *args)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
puts 'generating admin user'
|
46
|
+
admin = FactoryGirl.build(:user, :admin)
|
47
|
+
admin.save(:validate => false)
|
48
|
+
User.current = admin
|
49
|
+
targeting = FactoryGirl.create(:targeting, :search_query => "comment = benchmark-#{Foreman.uuid}", :user => User.current)
|
50
|
+
template_invocation = FactoryGirl.build(:template_invocation, :job_invocation => nil)
|
51
|
+
job_invocation = FactoryGirl.build(:job_invocation, :targeting => targeting, :pattern_template_invocations => [template_invocation]).tap do |invocation|
|
52
|
+
invocation.targeting = targeting
|
53
|
+
invocation.save
|
54
|
+
end
|
55
|
+
|
56
|
+
task = FactoryGirl.create(:dynflow_task, :external_id => '1')
|
57
|
+
tester = ActionTester.new(task)
|
58
|
+
|
59
|
+
puts 'generating hosts'
|
60
|
+
generate_hosts(1000)
|
61
|
+
puts 'starting benchmarking'
|
62
|
+
foreman_benchmark do
|
63
|
+
Benchmark.ips do |x|
|
64
|
+
x.config(:time => 10, :warmup => 0)
|
65
|
+
|
66
|
+
x.report("rex-run-hosts-job") do
|
67
|
+
tester.run_action(job_invocation)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require "benchmark/benchmark_helper"
|
2
|
+
require 'dynflow/testing'
|
3
|
+
|
4
|
+
# Add plugin to FactoryGirl's paths
|
5
|
+
FactoryGirl.definition_file_paths << File.expand_path('../../factories', __FILE__)
|
6
|
+
FactoryGirl.reload
|
7
|
+
|
8
|
+
def generate_hosts(total)
|
9
|
+
FactoryGirl.create_list(:host, total, :comment => "benchmark-#{Foreman.uuid}")
|
10
|
+
end
|
11
|
+
|
12
|
+
Rails.logger.level = Logger::ERROR
|
13
|
+
|
14
|
+
puts 'generating hosts'
|
15
|
+
generate_hosts(1000)
|
16
|
+
puts 'generating admin user'
|
17
|
+
admin = FactoryGirl.build(:user, :admin)
|
18
|
+
admin.save(:validate => false)
|
19
|
+
User.current = admin
|
20
|
+
|
21
|
+
puts 'starting benchmarking'
|
22
|
+
foreman_benchmark do
|
23
|
+
Benchmark.ips do |x|
|
24
|
+
x.config(:time => 10, :warmup => 0)
|
25
|
+
|
26
|
+
x.report("rex-targeting-resolve-hosts") do
|
27
|
+
targeting = FactoryGirl.create(:targeting, :search_query => "comment = benchmark-#{Foreman.uuid}", :user => User.current)
|
28
|
+
targeting.resolve_hosts!
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -5,6 +5,9 @@ FactoryGirl.define do
|
|
5
5
|
sequence(:job_category) { |n| "job name #{n}" }
|
6
6
|
f.template 'id'
|
7
7
|
f.provider_type 'SSH'
|
8
|
+
organizations { [Organization.find_by_name('Organization 1')] } if SETTINGS[:organizations_enabled]
|
9
|
+
locations { [Location.find_by_name('Location 1')] } if SETTINGS[:locations_enabled]
|
10
|
+
|
8
11
|
|
9
12
|
trait :with_input do
|
10
13
|
after(:build) do |template, evaluator|
|
@@ -43,6 +43,7 @@ module ForemanRemoteExecution
|
|
43
43
|
end
|
44
44
|
|
45
45
|
it 'triggers the RunHostJob actions on the resolved hosts in run phase' do
|
46
|
+
planned.expects(:output).returns(:planned_count => 0)
|
46
47
|
planned.expects(:trigger).with() { |*args| args[0] == Actions::RemoteExecution::RunHostJob }
|
47
48
|
planned.create_sub_plans
|
48
49
|
end
|
@@ -40,10 +40,7 @@ describe ForemanRemoteExecution::HostExtensions do
|
|
40
40
|
|
41
41
|
it 'has ssh keys in the parameters even when no user specified' do
|
42
42
|
# this is a case, when using the helper in provisioning templates
|
43
|
-
FactoryGirl.create(:smart_proxy, :ssh)
|
44
|
-
proxy.organizations << host.organization
|
45
|
-
proxy.locations << host.location
|
46
|
-
end
|
43
|
+
FactoryGirl.create(:smart_proxy, :ssh)
|
47
44
|
host.interfaces.first.subnet.remote_execution_proxies.clear
|
48
45
|
User.current = nil
|
49
46
|
host.remote_execution_ssh_keys.must_include sshkey
|
@@ -45,6 +45,10 @@ describe JobInvocation do
|
|
45
45
|
|
46
46
|
before do
|
47
47
|
input = job_invocation.pattern_template_invocations.first.template.template_inputs.create!(:name => 'foo', :required => true, :input_type => 'user')
|
48
|
+
input2 = job_invocation.pattern_template_invocations.first.template.template_inputs.create!(:name => 'bar', :required => true, :input_type => 'user')
|
49
|
+
FactoryGirl.create(:template_invocation_input_value,
|
50
|
+
:template_invocation => job_invocation.pattern_template_invocations.first,
|
51
|
+
:template_input => input2)
|
48
52
|
@input_value = FactoryGirl.create(:template_invocation_input_value,
|
49
53
|
:template_invocation => job_invocation.pattern_template_invocations.first,
|
50
54
|
:template_input => input)
|
@@ -101,6 +105,18 @@ describe JobInvocation do
|
|
101
105
|
|
102
106
|
context 'with task' do
|
103
107
|
let(:task) { ForemanTasks::Task.new }
|
108
|
+
let(:progress_report_without_sub_tasks) do
|
109
|
+
{
|
110
|
+
:error => 0,
|
111
|
+
:warning => 0,
|
112
|
+
:total => 0,
|
113
|
+
:success => 0,
|
114
|
+
:cancelled => 0,
|
115
|
+
:failed => 0,
|
116
|
+
:pending => 0,
|
117
|
+
:progress => 0
|
118
|
+
}
|
119
|
+
end
|
104
120
|
before { job_invocation.task = task }
|
105
121
|
|
106
122
|
context 'which is scheduled' do
|
@@ -109,6 +125,7 @@ describe JobInvocation do
|
|
109
125
|
specify { job_invocation.status.must_equal HostStatus::ExecutionStatus::QUEUED }
|
110
126
|
specify { job_invocation.queued?.must_equal true }
|
111
127
|
specify { job_invocation.progress.must_equal 0 }
|
128
|
+
specify { job_invocation.progress_report.must_equal progress_report_without_sub_tasks }
|
112
129
|
end
|
113
130
|
|
114
131
|
context 'with succeeded task' do
|
@@ -119,7 +136,17 @@ describe JobInvocation do
|
|
119
136
|
|
120
137
|
specify { job_invocation.status.must_equal HostStatus::ExecutionStatus::OK }
|
121
138
|
specify { job_invocation.queued?.must_equal false }
|
122
|
-
|
139
|
+
|
140
|
+
it 'calculates the progress correctly' do
|
141
|
+
sub_tasks = [ForemanTasks::Task.new]
|
142
|
+
job_invocation.targeting.expects(:resolved?).returns(true)
|
143
|
+
job_invocation.targeting.expects(:hosts).returns([1])
|
144
|
+
sub_tasks.expects(:where).with(:result => %w(success warning error)).returns(sub_tasks)
|
145
|
+
job_invocation.stubs(:sub_tasks).returns(sub_tasks)
|
146
|
+
|
147
|
+
job_invocation.progress.must_equal 100
|
148
|
+
end
|
123
149
|
end
|
124
150
|
end
|
151
|
+
|
125
152
|
end
|
@@ -42,5 +42,45 @@ describe RemoteExecutionFeature do
|
|
42
42
|
|
43
43
|
composer.targeting.search_query.must_equal "name = #{host.name}"
|
44
44
|
end
|
45
|
+
|
46
|
+
it "updates the feature when attributes change" do
|
47
|
+
updated_feature = RemoteExecutionFeature.register(install_feature.label, N_('Katello: Install package'),
|
48
|
+
:description => 'New description',
|
49
|
+
:provided_inputs => ['package', 'force'])
|
50
|
+
updated_feature.reload
|
51
|
+
updated_feature.id.must_equal(install_feature.id)
|
52
|
+
updated_feature.description.must_equal 'New description'
|
53
|
+
updated_feature.provided_input_names.must_equal ['package', 'force']
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe '.register' do
|
58
|
+
it "creates a feature if it's missing" do
|
59
|
+
feature = RemoteExecutionFeature.register('new_feature_that_does_not_exist', 'name')
|
60
|
+
feature.must_be :persisted?
|
61
|
+
feature.label.must_equal 'new_feature_that_does_not_exist'
|
62
|
+
feature.name.must_equal 'name'
|
63
|
+
refute feature.host_action_button
|
64
|
+
end
|
65
|
+
|
66
|
+
it "creates a feature with host action flag" do
|
67
|
+
feature = RemoteExecutionFeature.register('new_feature_that_does_not_exist_button', 'name', :host_action_button => true)
|
68
|
+
feature.must_be :persisted?
|
69
|
+
assert feature.host_action_button
|
70
|
+
end
|
71
|
+
|
72
|
+
it "created feature with host action flag can be found using named scope" do
|
73
|
+
feature = RemoteExecutionFeature.register('new_feature_that_does_not_exist_button', 'name', :host_action_button => true)
|
74
|
+
assert_includes RemoteExecutionFeature.with_host_action_button, feature
|
75
|
+
end
|
76
|
+
|
77
|
+
|
78
|
+
it "updates a feature if it exists" do
|
79
|
+
existing = FactoryGirl.create(:remote_execution_feature, :name => 'existing_feature_withou_action_button')
|
80
|
+
feature = RemoteExecutionFeature.register(existing.label, existing.name, :host_action_button => true)
|
81
|
+
feature.must_be :persisted?
|
82
|
+
existing.reload
|
83
|
+
assert existing.host_action_button
|
84
|
+
end
|
45
85
|
end
|
46
86
|
end
|