foreman-tasks 3.0.4 → 4.1.1

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 (51) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby_tests.yml +5 -3
  3. data/app/controllers/foreman_tasks/api/tasks_controller.rb +2 -5
  4. data/app/lib/actions/entry_action.rb +8 -4
  5. data/app/lib/actions/helpers/lock.rb +11 -5
  6. data/app/lib/actions/middleware/keep_current_request_id.rb +4 -1
  7. data/app/lib/actions/middleware/keep_current_user.rb +11 -1
  8. data/app/lib/actions/observable_action.rb +80 -0
  9. data/app/lib/actions/proxy_action.rb +2 -4
  10. data/app/models/foreman_tasks/concerns/action_subject.rb +0 -6
  11. data/app/models/foreman_tasks/link.rb +60 -0
  12. data/app/models/foreman_tasks/lock.rb +30 -128
  13. data/app/models/foreman_tasks/task.rb +20 -7
  14. data/app/models/foreman_tasks/task/search.rb +7 -6
  15. data/app/views/foreman_tasks/api/locks/show.json.rabl +4 -0
  16. data/app/views/foreman_tasks/api/tasks/details.json.rabl +5 -3
  17. data/app/views/foreman_tasks/tasks/_lock_card.html.erb +10 -0
  18. data/db/migrate/20180927120509_add_user_id.foreman_tasks.rb +4 -2
  19. data/db/migrate/20181206123910_create_foreman_tasks_links.foreman_tasks.rb +26 -0
  20. data/db/migrate/20181206124952_migrate_non_exclusive_locks_to_links.foreman_tasks.rb +14 -0
  21. data/db/migrate/20181206131436_drop_old_locks.foreman_tasks.rb +20 -0
  22. data/db/migrate/20181206131627_make_locks_exclusive.foreman_tasks.rb +25 -0
  23. data/lib/foreman_tasks/cleaner.rb +10 -0
  24. data/lib/foreman_tasks/engine.rb +5 -2
  25. data/lib/foreman_tasks/tasks/export_tasks.rake +2 -2
  26. data/lib/foreman_tasks/version.rb +1 -1
  27. data/package.json +6 -6
  28. data/test/controllers/api/tasks_controller_test.rb +1 -1
  29. data/test/controllers/tasks_controller_test.rb +3 -3
  30. data/test/core/unit/runner_test.rb +4 -17
  31. data/test/factories/task_factory.rb +31 -4
  32. data/test/unit/actions/action_with_sub_plans_test.rb +5 -2
  33. data/test/unit/actions/proxy_action_test.rb +4 -1
  34. data/test/unit/cleaner_test.rb +4 -4
  35. data/test/unit/locking_test.rb +85 -0
  36. data/test/unit/task_test.rb +15 -13
  37. data/test/unit/triggering_test.rb +2 -2
  38. data/webpack/ForemanTasks/Components/TaskDetails/Components/Locks.js +2 -2
  39. data/webpack/ForemanTasks/Components/TaskDetails/Components/TaskInfo.js +3 -2
  40. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/Locks.test.js.snap +4 -4
  41. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/TaskInfo.test.js.snap +2 -0
  42. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetails.js +4 -1
  43. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetails.scss +5 -1
  44. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetailsSelectors.js +3 -0
  45. data/webpack/ForemanTasks/Components/TaskDetails/index.js +2 -0
  46. data/webpack/ForemanTasks/Components/TasksTable/TasksTablePage.scss +4 -3
  47. data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksTablePage.test.js.snap +2 -2
  48. data/webpack/ForemanTasks/Components/TasksTable/formatters/__test__/__snapshots__/actionNameCellFormatter.test.js.snap +2 -3
  49. data/webpack/ForemanTasks/Components/TasksTable/formatters/actionNameCellFormatter.js +2 -3
  50. metadata +12 -4
  51. data/test/unit/lock_test.rb +0 -22
@@ -31,6 +31,7 @@ module ForemanTasks
31
31
  has_many :recurring_logic_task_groups, -> { where :type => 'ForemanTasks::TaskGroups::RecurringLogicTaskGroup' },
32
32
  :through => :task_group_members, :source => :task_group
33
33
  belongs_to :user
34
+ has_many :links, :dependent => :destroy
34
35
 
35
36
  scoped_search :on => :id, :complete_value => false
36
37
  scoped_search :on => :action, :complete_value => false
@@ -46,10 +47,16 @@ module ForemanTasks
46
47
 
47
48
  # Note: the following searches may return duplicates, this is due to
48
49
  # one task maybe having multiple locks (e.g. read/write) for the same resource_id
49
- scoped_search :relation => :locks, :on => :resource_id, :complete_value => false, :rename => 'location_id', :ext_method => :search_by_taxonomy, :only_explicit => true
50
- scoped_search :relation => :locks, :on => :resource_id, :complete_value => false, :rename => 'organization_id', :ext_method => :search_by_taxonomy, :only_explicit => true
51
- scoped_search :relation => :locks, :on => :resource_type, :complete_value => true, :rename => 'resource_type', :ext_method => :search_by_generic_resource, :only_explicit => true
52
- scoped_search :relation => :locks, :on => :resource_id, :complete_value => false, :rename => 'resource_id', :ext_method => :search_by_generic_resource, :only_explicit => true
50
+ scoped_search :relation => :locks, :on => :resource_id, :complete_value => false, :rename => 'locked_location_id', :ext_method => :search_by_taxonomy, :only_explicit => true
51
+ scoped_search :relation => :locks, :on => :resource_id, :complete_value => false, :rename => 'locked_organization_id', :ext_method => :search_by_taxonomy, :only_explicit => true
52
+ scoped_search :relation => :locks, :on => :resource_type, :complete_value => true, :rename => 'locked_resource_type', :ext_method => :search_by_generic_resource, :only_explicit => true
53
+ scoped_search :relation => :locks, :on => :resource_id, :complete_value => false, :rename => 'locked_resource_id', :ext_method => :search_by_generic_resource, :only_explicit => true
54
+
55
+ scoped_search :relation => :links, :on => :resource_id, :complete_value => false, :rename => 'location_id', :ext_method => :search_by_taxonomy, :only_explicit => true
56
+ scoped_search :relation => :links, :on => :resource_id, :complete_value => false, :rename => 'organization_id', :ext_method => :search_by_taxonomy, :only_explicit => true
57
+ scoped_search :relation => :links, :on => :resource_type, :complete_value => true, :rename => 'resource_type', :ext_method => :search_by_generic_resource, :only_explicit => true
58
+ scoped_search :relation => :links, :on => :resource_id, :complete_value => false, :rename => 'resource_id', :ext_method => :search_by_generic_resource, :only_explicit => true
59
+
53
60
  scoped_search :on => :user_id,
54
61
  :complete_value => true,
55
62
  :rename => 'user.id',
@@ -65,8 +72,8 @@ module ForemanTasks
65
72
  scope :running, -> { where("foreman_tasks_tasks.state NOT IN ('stopped', 'paused')") }
66
73
  scope :for_resource,
67
74
  (lambda do |resource|
68
- joins(:locks).where(:"foreman_tasks_locks.resource_id" => resource.id,
69
- :"foreman_tasks_locks.resource_type" => resource.class.name)
75
+ joins(:links).where(:"foreman_tasks_links.resource_id" => resource.id,
76
+ :"foreman_tasks_links.resource_type" => resource.class.name)
70
77
  end)
71
78
  scope :for_action_types, (->(action_types) { where('foreman_tasks_tasks.label IN (?)', Array(action_types)) })
72
79
 
@@ -82,7 +89,7 @@ module ForemanTasks
82
89
  property :ended_at, ActiveSupport::TimeWithZone, desc: 'Returns date with time the task ended at'
83
90
  end
84
91
  class Jail < Safemode::Jail
85
- allow :started_at, :ended_at, :result, :state, :label, :main_action
92
+ allow :started_at, :ended_at, :result, :state, :label, :main_action, :action_continuous_output
86
93
  end
87
94
 
88
95
  def input
@@ -242,6 +249,12 @@ module ForemanTasks
242
249
  parts.join(' ').strip
243
250
  end
244
251
 
252
+ def action_continuous_output
253
+ return unless main_action.is_a?(Actions::Helpers::WithContinuousOutput)
254
+ main_action.continuous_output.sort!
255
+ main_action.continuous_output.raw_outputs
256
+ end
257
+
245
258
  protected
246
259
 
247
260
  def generate_id
@@ -5,9 +5,9 @@ module ForemanTasks
5
5
  key = 'resource_type' if key.blank?
6
6
  key_name = connection.quote_column_name(key.sub(/^.*\./, ''))
7
7
  value = value.split(',') if operator.index(/IN/i)
8
- condition = sanitize_sql_for_conditions(["foreman_tasks_locks.#{key_name} #{operator} (?)", value])
8
+ condition = sanitize_sql_for_conditions(["foreman_tasks_links.#{key_name} #{operator} (?)", value])
9
9
 
10
- { :conditions => condition, :joins => :locks }
10
+ { :conditions => condition, :joins => :links }
11
11
  end
12
12
 
13
13
  def search_by_taxonomy(key, operator, value)
@@ -15,12 +15,13 @@ module ForemanTasks
15
15
  resource_type = key == 'location_id' ? 'Location' : 'Organization'
16
16
 
17
17
  joins = <<-SQL
18
- LEFT JOIN foreman_tasks_locks AS foreman_tasks_locks_taxonomy#{uniq_suffix}
19
- ON (foreman_tasks_locks_taxonomy#{uniq_suffix}.task_id = foreman_tasks_tasks.id AND
20
- foreman_tasks_locks_taxonomy#{uniq_suffix}.resource_type = '#{resource_type}')
18
+ LEFT JOIN foreman_tasks_links AS foreman_tasks_links_taxonomy#{uniq_suffix}
19
+ ON (foreman_tasks_links_taxonomy#{uniq_suffix}.task_id = foreman_tasks_tasks.id AND
20
+ foreman_tasks_links_taxonomy#{uniq_suffix}.resource_type = '#{resource_type}')
21
21
  SQL
22
22
  # Select only those tasks which either have the correct taxonomy or are not related to any
23
- sql = "foreman_tasks_locks_taxonomy#{uniq_suffix}.resource_id #{operator} (?) OR foreman_tasks_locks_taxonomy#{uniq_suffix}.resource_id IS NULL"
23
+ sql = "foreman_tasks_links_taxonomy#{uniq_suffix}.resource_id #{operator} (?) OR foreman_tasks_links_taxonomy#{uniq_suffix}.resource_id IS NULL"
24
+ value = value.split(',') if operator.index(/IN/i)
24
25
  { :conditions => sanitize_sql_for_conditions([sql, value]), :joins => joins }
25
26
  end
26
27
 
@@ -0,0 +1,4 @@
1
+ object @lock
2
+
3
+ attributes :name, :resource_type, :resource_id
4
+ node(:exclusive) { !locals[:link] }
@@ -9,10 +9,12 @@ node(:failed_steps) { @task.input_output_failed_steps }
9
9
  node(:running_steps) { @task.input_output_running_steps }
10
10
  node(:help) { troubleshooting_info_text }
11
11
  node(:has_sub_tasks) { @task.sub_tasks.any? }
12
+
12
13
  node(:locks) do
13
- @task.locks.map do |lock|
14
- { name: lock.name, exclusive: lock.exclusive, resource_type: lock.resource_type, resource_id: lock.resource_id }
15
- end
14
+ @task.locks.map { |lock| partial('foreman_tasks/api/locks/show', :object => lock) }
15
+ end
16
+ node(:links) do
17
+ @task.links.map { |link| partial('foreman_tasks/api/locks/show', :object => link, :locals => { :link => true }) }
16
18
  end
17
19
  node(:username_path) { username_link_task(@task.owner, @task.username) }
18
20
  node(:dynflow_enable_console) { Setting['dynflow_enable_console'] }
@@ -0,0 +1,10 @@
1
+ <div class="col-xs-6 col-sm-4 col-md-4">
2
+ <div class="card-pf card-pf-accented card-pf-aggregate-status">
3
+ <h2 class="card-pf-title">
4
+ <span class="fa <%= lock.is_a?(::ForemanTasks::Lock) ? 'fa-lock' : 'fa-unlock-alt' %>"></span> <%= lock.resource_type %>
5
+ </h2>
6
+ <div class="card-pf-body">
7
+ <%= format('id:%s', lock.resource_id) %><br>
8
+ </div>
9
+ </div>
10
+ </div>
@@ -1,4 +1,6 @@
1
1
  class AddUserId < ActiveRecord::Migration[5.0]
2
+ OWNER_LOCK_NAME = :task_owner
3
+
2
4
  def up
3
5
  add_reference :foreman_tasks_tasks, :user, :foreign_key => true
4
6
 
@@ -29,7 +31,7 @@ class AddUserId < ActiveRecord::Migration[5.0]
29
31
  private
30
32
 
31
33
  def create_lock(user_id, task)
32
- ForemanTasks::Lock.new(:name => ForemanTasks::Lock::OWNER_LOCK_NAME,
34
+ ForemanTasks::Lock.new(:name => OWNER_LOCK_NAME,
33
35
  :resource_type => User.name,
34
36
  :resource_id => user_id,
35
37
  :task_id => task.id,
@@ -37,6 +39,6 @@ class AddUserId < ActiveRecord::Migration[5.0]
37
39
  end
38
40
 
39
41
  def user_locks
40
- ForemanTasks::Lock.where(:name => ForemanTasks::Lock::OWNER_LOCK_NAME)
42
+ ForemanTasks::Lock.where(:name => OWNER_LOCK_NAME)
41
43
  end
42
44
  end
@@ -0,0 +1,26 @@
1
+ class CreateForemanTasksLinks < ActiveRecord::Migration[4.2]
2
+ def change
3
+ # rubocop:disable Rails/CreateTableWithTimestamps
4
+ create_table :foreman_tasks_links do |t|
5
+ task_id_options = { :index => true, :null => true }
6
+ if on_postgresql?
7
+ t.uuid :task_id, task_id_options
8
+ else
9
+ t.string :task_id, task_id_options
10
+ end
11
+ t.string :resource_type
12
+ t.integer :resource_id
13
+ end
14
+ # rubocop:enable Rails/CreateTableWithTimestamps
15
+
16
+ add_index :foreman_tasks_links, [:resource_type, :resource_id]
17
+ add_index :foreman_tasks_links, [:task_id, :resource_type, :resource_id],
18
+ :unique => true, :name => 'foreman_tasks_links_unique_index'
19
+ end
20
+
21
+ private
22
+
23
+ def on_postgresql?
24
+ ActiveRecord::Base.connection.adapter_name.casecmp('postgresql').zero?
25
+ end
26
+ end
@@ -0,0 +1,14 @@
1
+ class MigrateNonExclusiveLocksToLinks < ActiveRecord::Migration[5.0]
2
+ def up
3
+ execute <<-SQL
4
+ INSERT INTO foreman_tasks_links(task_id, resource_type, resource_id)
5
+ SELECT DISTINCT locks.task_id, locks.resource_type, locks.resource_id
6
+ FROM foreman_tasks_locks AS locks
7
+ LEFT JOIN foreman_tasks_links AS links
8
+ ON links.task_id = locks.task_id
9
+ AND links.resource_type = locks.resource_type
10
+ AND links.resource_id = locks.resource_id
11
+ WHERE locks.exclusive = FALSE AND links.task_id IS NULL;
12
+ SQL
13
+ end
14
+ end
@@ -0,0 +1,20 @@
1
+ class DropOldLocks < ActiveRecord::Migration[5.0]
2
+ BATCH_SIZE = 10_000
3
+
4
+ # Delete all locks which are exclusive or have a stopped task or are orphaned
5
+ def up
6
+ scope = ForemanTasks::Lock.left_outer_joins(:task)
7
+ scope = scope.where(:exclusive => false)
8
+ .or(scope.where("#{ForemanTasks::Task.table_name}.state" => ['stopped', nil]))
9
+ scope.limit(BATCH_SIZE).delete_all while scope.any?
10
+
11
+ # For each group of locks, where each lock has the same task_id, resource_type and resource_id
12
+ # return the highest id within the group, if there is more than 1 lock in the group
13
+ scope = ForemanTasks::Lock.select("MAX(id) as id")
14
+ .group(:task_id, :resource_type, :resource_id)
15
+ .having("count(*) > 1")
16
+
17
+ # Make sure there is at most one lock per task and resource
18
+ ForemanTasks::Lock.where(:id => scope.limit(BATCH_SIZE)).delete_all while scope.any?
19
+ end
20
+ end
@@ -0,0 +1,25 @@
1
+ class MakeLocksExclusive < ActiveRecord::Migration[5.0]
2
+ BATCH_SIZE = 2
3
+
4
+ def up
5
+ change_table :foreman_tasks_locks do |t|
6
+ t.remove :exclusive
7
+ t.remove :name
8
+ t.remove_index :name => 'index_foreman_tasks_locks_on_resource_type_and_resource_id'
9
+ t.index [:resource_type, :resource_id], :unique => true
10
+ end
11
+ end
12
+
13
+ def down
14
+ change_table :foreman_tasks_locks do |t|
15
+ t.boolean :exclusive, index: true
16
+ t.string :name, index: true
17
+ t.remove_index :name => 'index_foreman_tasks_locks_on_resource_type_and_resource_id'
18
+ t.index [:resource_type, :resource_id]
19
+ end
20
+
21
+ scope = ForemanTasks::Lock.where(:name => nil)
22
+ while scope.limit(BATCH_SIZE).update_all(:name => 'lock') == BATCH_SIZE; end
23
+ change_column_null(:foreman_tasks_locks, :name, false)
24
+ end
25
+ end
@@ -103,6 +103,7 @@ module ForemanTasks
103
103
  end
104
104
  end
105
105
  delete_orphaned_locks
106
+ delete_orphaned_links
106
107
  delete_orphaned_dynflow_tasks
107
108
  end
108
109
 
@@ -156,6 +157,15 @@ module ForemanTasks
156
157
  end
157
158
  end
158
159
 
160
+ def delete_orphaned_links
161
+ orphaned_links = ForemanTasks::Link.left_outer_joins(:task).where(:'foreman_tasks_tasks.id' => nil)
162
+ with_noop(orphaned_links, 'orphaned task links') do |source, name|
163
+ with_batches(source, name) do |chunk|
164
+ ForemanTasks::Link.where(id: chunk.pluck(:id)).delete_all
165
+ end
166
+ end
167
+ end
168
+
159
169
  def delete_orphaned_dynflow_tasks
160
170
  with_noop(orphaned_dynflow_tasks, 'orphaned execution plans') do |source, name|
161
171
  with_batches(source, name) do |chunk|
@@ -34,7 +34,7 @@ module ForemanTasks
34
34
 
35
35
  initializer 'foreman_tasks.register_plugin', :before => :finisher_hook do |_app|
36
36
  Foreman::Plugin.register :"foreman-tasks" do
37
- requires_foreman '>= 2.2.0'
37
+ requires_foreman '>= 2.4.0'
38
38
  divider :top_menu, :parent => :monitor_menu, :last => true, :caption => N_('Foreman Tasks')
39
39
  menu :top_menu, :tasks,
40
40
  :url_hash => { :controller => 'foreman_tasks/tasks', :action => :index },
@@ -76,6 +76,9 @@ module ForemanTasks
76
76
 
77
77
  widget 'foreman_tasks/tasks/dashboard/tasks_status', :sizex => 6, :sizey => 1, :name => N_('Task Status')
78
78
  widget 'foreman_tasks/tasks/dashboard/latest_tasks_in_error_warning', :sizex => 6, :sizey => 1, :name => N_('Latest Warning/Error Tasks')
79
+
80
+ ForemanTasks.dynflow.eager_load_actions!
81
+ extend_observable_events(::Dynflow::Action.descendants.select { |klass| klass <= ::Actions::ObservableAction }.map(&:namespaced_event_names))
79
82
  end
80
83
  end
81
84
 
@@ -108,7 +111,7 @@ module ForemanTasks
108
111
  ForemanTasks.dynflow.require!
109
112
  ::ForemanTasks.dynflow.config.on_init(false) do |world|
110
113
  world.middleware.use Actions::Middleware::KeepCurrentTaxonomies
111
- world.middleware.use Actions::Middleware::KeepCurrentUser
114
+ world.middleware.use Actions::Middleware::KeepCurrentUser, :before => ::Dynflow::Middleware::Common::Transaction
112
115
  world.middleware.use Actions::Middleware::KeepCurrentTimezone
113
116
  world.middleware.use Actions::Middleware::KeepCurrentRequestID
114
117
  end
@@ -252,7 +252,7 @@ namespace :foreman_tasks do
252
252
  renderer = TaskRender.new
253
253
  total = tasks.count
254
254
 
255
- tasks.each_with_index do |task, count|
255
+ tasks.find_each.with_index do |task, count|
256
256
  File.open(File.join(tmp_dir, "#{task.id}.html"), 'w') { |file| file.write(PageHelper.pagify(renderer.render_task(task))) }
257
257
  puts "#{count + 1}/#{total}"
258
258
  end
@@ -264,7 +264,7 @@ namespace :foreman_tasks do
264
264
  elsif format == 'csv'
265
265
  CSV.open(export_filename, 'wb') do |csv|
266
266
  csv << %w[id state type label result parent_task_id started_at ended_at]
267
- tasks.each do |task|
267
+ tasks.find_each do |task|
268
268
  csv << [task.id, task.state, task.type, task.label, task.result,
269
269
  task.parent_task_id, task.started_at, task.ended_at]
270
270
  end
@@ -1,3 +1,3 @@
1
1
  module ForemanTasks
2
- VERSION = '3.0.4'.freeze
2
+ VERSION = '4.1.1'.freeze
3
3
  end
data/package.json CHANGED
@@ -23,7 +23,7 @@
23
23
  "url": "http://projects.theforeman.org/projects/foreman-tasks/issues"
24
24
  },
25
25
  "peerDependencies": {
26
- "@theforeman/vendor": ">= 4.0.2"
26
+ "@theforeman/vendor": ">= 6.0.0"
27
27
  },
28
28
  "dependencies": {
29
29
  "c3": "^0.4.11",
@@ -32,11 +32,11 @@
32
32
  },
33
33
  "devDependencies": {
34
34
  "@babel/core": "^7.7.0",
35
- "@theforeman/builder": "^4.0.2",
36
- "@theforeman/eslint-plugin-foreman": "4.0.5",
37
- "@theforeman/stories": "^4.0.2",
38
- "@theforeman/test": "^4.0.2",
39
- "@theforeman/vendor-dev": "^4.0.2",
35
+ "@theforeman/builder": "^6.0.0",
36
+ "@theforeman/eslint-plugin-foreman": "6.0.0",
37
+ "@theforeman/stories": "^6.0.0",
38
+ "@theforeman/test": "^6.0.0",
39
+ "@theforeman/vendor-dev": "^6.0.0",
40
40
  "babel-eslint": "^10.0.3",
41
41
  "eslint": "^6.7.2",
42
42
  "jed": "^1.1.1",
@@ -29,7 +29,7 @@ module ForemanTasks
29
29
 
30
30
  it 'renders task ids when searching by resource id' do
31
31
  task = FactoryBot.create(:dynflow_task, :product_create_task)
32
- ForemanTasks::Lock.create!(name: "create", resource_type: "Katello::Product", resource_id: 1, task_id: task.id)
32
+ ForemanTasks::Link.create!(resource_type: "Katello::Product", resource_id: 1, task_id: task.id)
33
33
  get :index, params: { :search => "label = Actions::Katello::Product::Create and resource_id = 1" }
34
34
  assert_response :success
35
35
  data = JSON.parse(response.body)
@@ -10,7 +10,7 @@ module ForemanTasks
10
10
  # rubocop:enable Naming/AccessorMethodName
11
11
 
12
12
  def linked_task(resource)
13
- FactoryBot.create(:some_task).tap { |t| ForemanTasks::Lock.link!(resource, t.id) }
13
+ FactoryBot.create(:some_task).tap { |t| ForemanTasks::Link.link!(resource, t) }
14
14
  end
15
15
 
16
16
  def in_taxonomy_scope(organization, location = nil)
@@ -44,8 +44,8 @@ module ForemanTasks
44
44
  @locations = [0, 0].map { FactoryBot.create(:location) }
45
45
  @tasks = [0, 0].map { FactoryBot.create(:some_task) }
46
46
  @tasks.zip(@organizations, @locations).each do |task, org, loc|
47
- Lock.link!(org, task.id)
48
- Lock.link!(loc, task.id)
47
+ Link.link!(org, task)
48
+ Link.link!(loc, task)
49
49
  end
50
50
  end
51
51
 
@@ -53,7 +53,7 @@ module ForemanTasksCore
53
53
  describe '#initialize_continuous_outputs' do
54
54
  it 'initializes outputs for targets and parent' do
55
55
  outputs = runner.initialize_continuous_outputs
56
- _(outputs.keys.count).must_equal 3
56
+ _(outputs.keys.count).must_equal 2
57
57
  outputs.values.each { |output| _(output).must_be_instance_of ContinuousOutput }
58
58
  end
59
59
  end
@@ -66,23 +66,10 @@ module ForemanTasksCore
66
66
  _(updates.keys.count).must_equal 1
67
67
  end
68
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
69
  it 'works without compatibility mode' do
83
70
  runner.broadcast_data('something', 'stdout')
84
71
  updates = runner.generate_updates
85
- _(updates.keys.count).must_equal 3
72
+ _(updates.keys.count).must_equal 2
86
73
  updates.keys.each do |key|
87
74
  _(key).must_be_instance_of ::Dynflow::Action::Suspended
88
75
  end
@@ -99,7 +86,7 @@ module ForemanTasksCore
99
86
  describe '#broadcast_data' do
100
87
  it 'publishes data for all hosts' do
101
88
  runner.broadcast_data('message', 'stdout')
102
- _(runner.generate_updates.keys.count).must_equal 3
89
+ _(runner.generate_updates.keys.count).must_equal 2
103
90
  end
104
91
  end
105
92
 
@@ -115,7 +102,7 @@ module ForemanTasksCore
115
102
  it 'broadcasts the exception to all targets' do
116
103
  runner.expects(:publish_exit_status).never
117
104
  runner.publish_exception('general failure', exception, false)
118
- _(runner.generate_updates.keys.count).must_equal 3
105
+ _(runner.generate_updates.keys.count).must_equal 2
119
106
  end
120
107
 
121
108
  it 'publishes exit status if fatal' do
@@ -42,11 +42,34 @@ FactoryBot.define do
42
42
  end
43
43
  end
44
44
 
45
+ factory :task_with_links do
46
+ # posts_count is declared as a transient attribute and available in
47
+ # attributes on the factory, as well as the callback via the evaluator
48
+ transient do
49
+ locks_count { 1 }
50
+ resource_id { 1 }
51
+ resource_type { 'type1' }
52
+ end
53
+
54
+ # the after(:create) yields two values; the user instance itself and the
55
+ # evaluator, which stores all values from the factory, including transient
56
+ # attributes; `create_list`'s second argument is the number of records
57
+ # to create and we make sure the user is associated properly to the post
58
+ after(:create) do |task, evaluator|
59
+ create_list(
60
+ :link,
61
+ 1,
62
+ task: task,
63
+ resource_type: evaluator.resource_type,
64
+ resource_id: evaluator.resource_id
65
+ )
66
+ end
67
+ end
68
+
45
69
  factory :task_with_locks do
46
70
  # posts_count is declared as a transient attribute and available in
47
71
  # attributes on the factory, as well as the callback via the evaluator
48
72
  transient do
49
- locks_count { 3 }
50
73
  resource_id { 1 }
51
74
  resource_type { 'type1' }
52
75
  end
@@ -58,7 +81,7 @@ FactoryBot.define do
58
81
  after(:create) do |task, evaluator|
59
82
  create_list(
60
83
  :lock,
61
- evaluator.locks_count,
84
+ 1,
62
85
  task: task,
63
86
  resource_type: evaluator.resource_type,
64
87
  resource_id: evaluator.resource_id
@@ -68,11 +91,15 @@ FactoryBot.define do
68
91
  end
69
92
  end
70
93
 
94
+ factory :link, :class => ForemanTasks::Link do
95
+ resource_type { 'Katello::Repository' }
96
+ resource_id { 1 }
97
+ association :task, factory: :task_with_links
98
+ end
99
+
71
100
  factory :lock, :class => ForemanTasks::Lock do
72
- name { 'read' }
73
101
  resource_type { 'Katello::Repository' }
74
102
  resource_id { 1 }
75
- exclusive { true }
76
103
  association :task, factory: :task_with_locks
77
104
  end
78
105
  end