foreman-tasks 1.0.1 → 1.1.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 (56) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +12 -12
  3. data/.rubocop_todo.yml +34 -116
  4. data/app/controllers/foreman_tasks/api/recurring_logics_controller.rb +20 -1
  5. data/app/controllers/foreman_tasks/api/tasks_controller.rb +29 -9
  6. data/app/controllers/foreman_tasks/concerns/hosts_controller_extension.rb +1 -1
  7. data/app/controllers/foreman_tasks/recurring_logics_controller.rb +19 -0
  8. data/app/helpers/foreman_tasks/foreman_tasks_helper.rb +1 -3
  9. data/app/lib/actions/helpers/humanizer.rb +1 -3
  10. data/app/lib/actions/proxy_action.rb +33 -12
  11. data/app/models/foreman_tasks/concerns/action_triggering.rb +1 -1
  12. data/app/models/foreman_tasks/recurring_logic.rb +1 -0
  13. data/app/models/foreman_tasks/remote_task.rb +1 -0
  14. data/app/models/foreman_tasks/task.rb +4 -0
  15. data/app/models/foreman_tasks/task/dynflow_task.rb +1 -1
  16. data/app/models/foreman_tasks/task/search.rb +11 -1
  17. data/app/services/foreman_tasks/troubleshooting_help_generator.rb +0 -4
  18. data/app/views/foreman_tasks/api/recurring_logics/base.json.rabl +2 -1
  19. data/app/views/foreman_tasks/api/tasks/details.json.rabl +1 -0
  20. data/app/views/foreman_tasks/api/tasks/show.json.rabl +1 -1
  21. data/app/views/foreman_tasks/recurring_logics/index.html.erb +30 -0
  22. data/app/views/foreman_tasks/tasks/show.html.erb +3 -0
  23. data/config/routes.rb +7 -0
  24. data/foreman-tasks.gemspec +4 -6
  25. data/lib/foreman_tasks/dynflow/console_authorizer.rb +2 -2
  26. data/lib/foreman_tasks/engine.rb +15 -13
  27. data/lib/foreman_tasks/tasks/cleanup.rake +1 -1
  28. data/lib/foreman_tasks/tasks/export_tasks.rake +2 -2
  29. data/lib/foreman_tasks/test_extensions.rb +1 -1
  30. data/lib/foreman_tasks/version.rb +1 -1
  31. data/locale/action_names.rb +1 -1
  32. data/package.json +1 -2
  33. data/script/rails +2 -2
  34. data/test/factories/task_factory.rb +34 -2
  35. data/test/foreman_tasks_test_helper.rb +4 -0
  36. data/test/unit/actions/action_with_sub_plans_test.rb +1 -1
  37. data/test/unit/task_test.rb +160 -74
  38. data/webpack/ForemanTasks/Components/TaskDetails/Components/Task.js +4 -0
  39. data/webpack/ForemanTasks/Components/TaskDetails/Components/TaskInfo.js +3 -12
  40. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/Task.test.js +1 -0
  41. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/Task.test.js.snap +3 -1
  42. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/TaskInfo.test.js.snap +2 -6
  43. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetailsSelectors.js +4 -1
  44. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/__snapshots__/TaskDetails.test.js.snap +1 -0
  45. data/webpack/ForemanTasks/Components/TaskDetails/index.js +2 -0
  46. data/webpack/ForemanTasks/Components/TasksTable/SubTasksPage.js +3 -1
  47. data/webpack/ForemanTasks/Components/TasksTable/TasksTableActions.js +87 -21
  48. data/webpack/ForemanTasks/Components/TasksTable/TasksTableConstants.js +7 -7
  49. data/webpack/ForemanTasks/Components/TasksTable/TasksTablePage.js +31 -22
  50. data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksTable.fixtures.js +2 -1
  51. data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksTableActions.test.js +44 -46
  52. data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/SubTasksPage.test.js.snap +3 -1
  53. data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksIndexPage.test.js.snap +2 -1
  54. data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksTableActions.test.js.snap +61 -5
  55. data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksTablePage.test.js.snap +6 -2
  56. metadata +10 -10
@@ -158,7 +158,7 @@ module ForemanTasks
158
158
  end
159
159
  end
160
160
  end
161
- return true
161
+ true
162
162
  ensure
163
163
  # to not execute the same execution plan twice in a row
164
164
  @execution_plan = nil
@@ -14,6 +14,7 @@ module ForemanTasks
14
14
  scoped_search :on => :max_iteration, :complete_value => false, :rename => :iteration_limit
15
15
  scoped_search :on => :iteration, :complete_value => false
16
16
  scoped_search :on => :cron_line, :complete_value => true
17
+ scoped_search :on => :state, :complete_value => true
17
18
 
18
19
  before_create do
19
20
  task_group.save
@@ -9,6 +9,7 @@ module ForemanTasks
9
9
 
10
10
  scope :triggered, -> { where(:state => 'triggered') }
11
11
  scope :pending, -> { where(:state => 'new') }
12
+ scope :external, -> { where(:state => 'external') }
12
13
 
13
14
  delegate :proxy_action_name, :to => :action
14
15
 
@@ -42,6 +42,10 @@ module ForemanTasks
42
42
  scoped_search :on => :start_at, :complete_value => false
43
43
  scoped_search :on => :ended_at, :complete_value => false
44
44
  scoped_search :on => :parent_task_id, :complete_value => true
45
+ scoped_search :on => :duration, :complete_value => false, :ext_method => :search_by_duration, :operators => %w[> >= = <= <], :only_explicit => true
46
+
47
+ # Note: the following searches may return duplicates, this is due to
48
+ # one task maybe having multiple locks (e.g. read/write) for the same resource_id
45
49
  scoped_search :relation => :locks, :on => :resource_id, :complete_value => false, :rename => 'location_id', :ext_method => :search_by_taxonomy, :only_explicit => true
46
50
  scoped_search :relation => :locks, :on => :resource_id, :complete_value => false, :rename => 'organization_id', :ext_method => :search_by_taxonomy, :only_explicit => true
47
51
  scoped_search :relation => :locks, :on => :resource_type, :complete_value => true, :rename => 'resource_type', :ext_method => :search_by_generic_resource, :only_explicit => true
@@ -228,7 +228,7 @@ module ForemanTasks
228
228
  # if we fail updating the data from dynflow, it usually means there is something
229
229
  # odd with the data consistency and at this point it is not possible to resume, switching
230
230
  # the task to stopped/error
231
- task.update_attributes(:state => 'stopped', :result => 'error')
231
+ task.update(:state => 'stopped', :result => 'error')
232
232
  Foreman::Logging.exception("Failed at consistency check for task #{task.id}", e, :logger => 'foreman-tasks')
233
233
  end
234
234
  end
@@ -4,7 +4,8 @@ module ForemanTasks
4
4
  def search_by_generic_resource(key, operator, value)
5
5
  key = 'resource_type' if key.blank?
6
6
  key_name = connection.quote_column_name(key.sub(/^.*\./, ''))
7
- condition = sanitize_sql_for_conditions(["foreman_tasks_locks.#{key_name} #{operator} ?", value])
7
+ value = value.split(',') if operator.index(/IN/i)
8
+ condition = sanitize_sql_for_conditions(["foreman_tasks_locks.#{key_name} #{operator} (?)", value])
8
9
 
9
10
  { :conditions => condition, :joins => :locks }
10
11
  end
@@ -22,6 +23,15 @@ module ForemanTasks
22
23
  sql = "foreman_tasks_locks_taxonomy#{uniq_suffix}.resource_id #{operator} ? OR foreman_tasks_locks_taxonomy#{uniq_suffix}.resource_id IS NULL"
23
24
  { :conditions => sanitize_sql_for_conditions([sql, value]), :joins => joins }
24
25
  end
26
+
27
+ # Expects the time in the format "\d+ (seconds|minutes|hours|days|months|years)"
28
+ SUPPORTED_DURATION_FORMAT = /\A\s*(\d+(\s+\b(seconds?|minutes?|hours?|days?|months?|years?)\b)?)\b\s*\z/i.freeze
29
+ def search_by_duration(_key, operator, value)
30
+ raise "Unsupported duration '#{value}' specified for searching" unless value =~ SUPPORTED_DURATION_FORMAT
31
+ value = value.strip
32
+ { :conditions => "coalesce(ended_at, current_timestamp) - coalesce(coalesce(started_at, ended_at), current_timestamp) #{operator} ?::interval",
33
+ :parameter => [value] }
34
+ end
25
35
  end
26
36
  end
27
37
  end
@@ -44,10 +44,6 @@ module ForemanTasks
44
44
  # rubocop:enable Rails/OutputSafety
45
45
  end
46
46
 
47
- def generate_text
48
- (description + link_descriptions_html).join("\n")
49
- end
50
-
51
47
  def link_descriptions_html
52
48
  links.map do |link|
53
49
  link.description % { link: %(<a href="%{href}">%{title}</a>) % link.to_h }
@@ -1,3 +1,4 @@
1
1
  object @recurring_logic
2
2
 
3
- attributes :id, :cron_line, :end_time, :iteration, :task_group_id, :state
3
+ attributes :id, :cron_line, :end_time, :iteration, :task_group_id, :state,
4
+ :max_iteration
@@ -16,3 +16,4 @@ node(:locks) do
16
16
  end
17
17
  end
18
18
  node(:username_path) { username_link_task(@task.owner, @task.username) }
19
+ node(:dynflow_enable_console) { Setting['dynflow_enable_console'] }
@@ -2,5 +2,5 @@ object @task if @task
2
2
 
3
3
  attributes :id, :label, :pending, :action
4
4
  attributes :username, :started_at, :ended_at, :state, :result, :progress
5
- attributes :input, :output, :humanized, :cli_example
5
+ attributes :input, :output, :humanized, :cli_example, :start_at
6
6
  node(:available_actions) { |t| { cancellable: t.execution_plan&.cancellable?, resumable: t.resumable? } }
@@ -5,6 +5,36 @@
5
5
  <%= alert(:class => 'alert-info', :id => 'multiple-alert', :close => false, :header => '', :text => @errors) %>
6
6
  <% end %>
7
7
 
8
+ <% if authorized_for(:permission => :edit_recurring_logics, :auth_object => @recurring_logics) %>
9
+ <% title_actions link_to(_('Clear Cancelled'),
10
+ clear_cancelled_foreman_tasks_recurring_logics_path,
11
+ class: ['btn', 'btn-sm', 'btn-danger'],
12
+ :'data-toggle' => "modal",
13
+ :'data-target' => "#clear_modal")
14
+ %>
15
+
16
+ <div class="modal fade" id="clear_modal" tabindex="-1" role="dialog" aria-labelledby="Deploy" aria-hidden="true">
17
+ <div class="modal-dialog">
18
+ <div class="modal-content">
19
+ <div class="modal-header">
20
+ <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
21
+ <h2 class="modal-title" id="deploy_modal_label">
22
+ <span class="glyphicon glyphicon-warning-sign"></span>
23
+ <%= _("Clear Cancelled") %>
24
+ </h2>
25
+ </div>
26
+ <div class="modal-body">
27
+ <%= _("This action will delete all cancelled recurring logics. Please note that this action can't be reversed.") %>
28
+ </div>
29
+ <div class="modal-footer">
30
+ <button type="button" class="btn btn-default" data-dismiss="modal"><%= _("Cancel") %></button>
31
+ <%= link_to(_('Clear Cancelled'), clear_cancelled_foreman_tasks_recurring_logics_path, method: :post, class: 'btn btn-danger modal-submit') %>
32
+ </div>
33
+ </div>
34
+ </div>
35
+ </div>
36
+ <% end %>
37
+
8
38
  <table class="<%= table_css_classes('table-condensed table-fixed') %>">
9
39
  <thead>
10
40
  <th><%= N_("Cron line") %></th>
@@ -5,6 +5,9 @@
5
5
  <% content_for(:stylesheets) do %>
6
6
  <%= webpacked_plugins_css_for :'foreman-tasks' %>
7
7
  <% end %>
8
+
9
+ <% title _("Details of %s task") % @task.to_s %>
10
+
8
11
  <%= breadcrumbs(
9
12
  items: breadcrumb_items,
10
13
  name_field: 'action',
@@ -6,6 +6,9 @@ Foreman::Application.routes.draw do
6
6
  put :enable
7
7
  put :disable
8
8
  end
9
+ collection do
10
+ post :clear_cancelled
11
+ end
9
12
  end
10
13
 
11
14
  resources :tasks, :only => [:show] do
@@ -39,6 +42,9 @@ Foreman::Application.routes.draw do
39
42
  member do
40
43
  post :cancel
41
44
  end
45
+ collection do
46
+ post :bulk_destroy
47
+ end
42
48
  end
43
49
 
44
50
  resources :tasks, :only => [:show, :index] do
@@ -49,6 +55,7 @@ Foreman::Application.routes.draw do
49
55
  collection do
50
56
  post :bulk_search
51
57
  post :bulk_resume
58
+ post :bulk_cancel
52
59
  get :summary
53
60
  get '/summary/:id/sub_tasks/', action: 'summary_sub_tasks'
54
61
  post :callback
@@ -1,6 +1,4 @@
1
- # -*- coding: utf-8 -*-
2
-
3
- $LOAD_PATH.push File.expand_path("../lib", __FILE__)
1
+ $LOAD_PATH.push File.expand_path('lib', __dir__)
4
2
 
5
3
  # Maintain your gem's version:
6
4
  require "foreman_tasks/version"
@@ -29,11 +27,11 @@ same resource. It also optionally provides Dynflow infrastructure for using it f
29
27
  s.test_files = `git ls-files test`.split("\n")
30
28
  s.extra_rdoc_files = Dir['README*', 'LICENSE']
31
29
 
32
- s.add_dependency "foreman-tasks-core"
33
30
  s.add_dependency "dynflow", '>= 1.2.3'
34
- s.add_dependency "sinatra" # for Dynflow web console
35
- s.add_dependency "parse-cron", '~> 0.1.4'
31
+ s.add_dependency "foreman-tasks-core"
36
32
  s.add_dependency "get_process_mem" # for memory polling
33
+ s.add_dependency "parse-cron", '~> 0.1.4'
34
+ s.add_dependency "sinatra" # for Dynflow web console
37
35
 
38
36
  s.add_development_dependency 'factory_bot_rails', '~> 4.8.0'
39
37
  end
@@ -34,7 +34,7 @@ module ForemanTasks
34
34
  # console no matter what task it is...
35
35
  edit_permission = Permission.where(:name => :edit_foreman_tasks, :resource_type => ForemanTasks::Task.name).first
36
36
  if @user.filters.joins(:filterings).unlimited.where('filterings.permission_id' => edit_permission).first
37
- return true
37
+ true
38
38
  end
39
39
  end
40
40
 
@@ -43,7 +43,7 @@ module ForemanTasks
43
43
  begin
44
44
  original_user = User.current
45
45
  User.current = @user
46
- return Authorizer.new(@user).can?(:edit_foreman_tasks, task)
46
+ Authorizer.new(@user).can?(:edit_foreman_tasks, task)
47
47
  ensure
48
48
  User.current = original_user
49
49
  end
@@ -7,10 +7,10 @@ module ForemanTasks
7
7
  engine_name 'foreman_tasks'
8
8
 
9
9
  initializer 'foreman_tasks.load_default_settings', :before => :load_config_initializers do
10
- require_dependency File.expand_path('../../../app/models/setting/foreman_tasks.rb', __FILE__) if begin
10
+ require_dependency File.expand_path('../../app/models/setting/foreman_tasks.rb', __dir__) if begin
11
11
  Setting.table_exists?
12
- rescue
13
- false
12
+ rescue
13
+ false
14
14
  end
15
15
  end
16
16
 
@@ -26,7 +26,7 @@ module ForemanTasks
26
26
  end
27
27
 
28
28
  initializer 'foreman_tasks.register_gettext', :after => :load_config_initializers do
29
- locale_dir = File.join(File.expand_path('../../..', __FILE__), 'locale')
29
+ locale_dir = File.join(File.expand_path('../..', __dir__), 'locale')
30
30
  locale_domain = 'foreman_tasks'
31
31
 
32
32
  Foreman::Gettext::Support.add_text_domain locale_domain, locale_dir
@@ -53,15 +53,15 @@ module ForemanTasks
53
53
  :'foreman_tasks/react' => [:index],
54
54
  :'foreman_tasks/api/tasks' => [:bulk_search, :show, :index, :summary, :summary_sub_tasks, :details, :sub_tasks] }, :resource_type => ForemanTasks::Task.name
55
55
  permission :edit_foreman_tasks, { :'foreman_tasks/tasks' => [:resume, :unlock, :force_unlock, :cancel_step, :cancel, :abort],
56
- :'foreman_tasks/api/tasks' => [:bulk_resume] }, :resource_type => ForemanTasks::Task.name
56
+ :'foreman_tasks/api/tasks' => [:bulk_resume, :bulk_cancel] }, :resource_type => ForemanTasks::Task.name
57
57
 
58
58
  permission :create_recurring_logics, {}, :resource_type => ForemanTasks::RecurringLogic.name
59
59
 
60
60
  permission :view_recurring_logics, { :'foreman_tasks/recurring_logics' => [:index, :show],
61
61
  :'foreman_tasks/api/recurring_logics' => [:index, :show] }, :resource_type => ForemanTasks::RecurringLogic.name
62
62
 
63
- permission :edit_recurring_logics, { :'foreman_tasks/recurring_logics' => [:cancel, :enable, :disable],
64
- :'foreman_tasks/api/recurring_logics' => [:cancel, :update] }, :resource_type => ForemanTasks::RecurringLogic.name
63
+ permission :edit_recurring_logics, { :'foreman_tasks/recurring_logics' => [:cancel, :enable, :disable, :clear_cancelled],
64
+ :'foreman_tasks/api/recurring_logics' => [:cancel, :update, :bulk_destroy] }, :resource_type => ForemanTasks::RecurringLogic.name
65
65
  end
66
66
 
67
67
  add_all_permissions_to_default_roles
@@ -69,8 +69,10 @@ module ForemanTasks
69
69
  logger :dynflow, :enabled => true
70
70
  logger :action, :enabled => true
71
71
 
72
- role 'Tasks Manager', [:view_foreman_tasks, :edit_foreman_tasks]
73
- role 'Tasks Reader', [:view_foreman_tasks]
72
+ role 'Tasks Manager', [:view_foreman_tasks, :edit_foreman_tasks],
73
+ 'Role granting permissions to inspect, cancel, resume and unlock tasks'
74
+ role 'Tasks Reader', [:view_foreman_tasks],
75
+ 'Role granting permissions to inspect tasks'
74
76
 
75
77
  widget 'foreman_tasks/tasks/dashboard/tasks_status', :sizex => 6, :sizey => 1, :name => N_('Task Status')
76
78
  widget 'foreman_tasks/tasks/dashboard/latest_tasks_in_error_warning', :sizex => 6, :sizey => 1, :name => N_('Latest Warning/Error Tasks')
@@ -133,16 +135,16 @@ module ForemanTasks
133
135
  # to enable async Foreman operations using Dynflow
134
136
  if ENV['FOREMAN_TASKS_MONKEYS'] == 'true'
135
137
  config.to_prepare do
136
- ::Api::V2::HostsController.send :prepend, ForemanTasks::Concerns::HostsControllerExtension
137
- ::Host::Base.send :include, ForemanTasks::Concerns::HostActionSubject
138
+ ::Api::V2::HostsController.prepend ForemanTasks::Concerns::HostsControllerExtension
139
+ ::Host::Base.include ForemanTasks::Concerns::HostActionSubject
138
140
  end
139
141
  end
140
142
 
141
143
  config.to_prepare do
142
144
  ForemanTasks.dynflow.eager_load_actions! if ForemanTasks.dynflow.initialized?
143
145
 
144
- Authorizer.send(:prepend, AuthorizerExt)
145
- User.send(:include, ForemanTasks::Concerns::UserExtensions)
146
+ Authorizer.prepend AuthorizerExt
147
+ User.include ForemanTasks::Concerns::UserExtensions
146
148
  end
147
149
 
148
150
  rake_tasks do
@@ -1,6 +1,6 @@
1
1
  namespace :foreman_tasks do
2
2
  namespace :cleanup do
3
- desc <<-DESC.strip_heredoc
3
+ desc <<~DESC
4
4
  Clean tasks based on filter and age. ENV variables:
5
5
 
6
6
  * TASK_SEARCH : scoped search filter (example: 'label = "Actions::Foreman::Host::ImportFacts"')
@@ -7,7 +7,7 @@
7
7
  require 'csv'
8
8
 
9
9
  namespace :foreman_tasks do
10
- desc <<-DESC.strip_heredoc
10
+ desc <<~DESC
11
11
  Export dynflow tasks based on filter. ENV variables:
12
12
 
13
13
  * TASK_SEARCH : scoped search filter (example: 'label = "Actions::Foreman::Host::ImportFacts"')
@@ -259,7 +259,7 @@ namespace :foreman_tasks do
259
259
 
260
260
  File.open(File.join(tmp_dir, 'index.html'), 'w') { |file| file.write(PageHelper.pagify(PageHelper.generate_index(tasks))) }
261
261
 
262
- sh("tar cvzf #{export_filename} #{tmp_dir} > /dev/null")
262
+ system("tar", "czf", export_filename, tmp_dir)
263
263
  end
264
264
  elsif format == 'csv'
265
265
  CSV.open(export_filename, 'wb') do |csv|
@@ -14,4 +14,4 @@ module ForemanTasks
14
14
  end
15
15
  end
16
16
 
17
- ActiveSupport::TestCase.send(:include, ForemanTasks::TestExtensions::AccessPermissionsTestExtension)
17
+ ActiveSupport::TestCase.include ForemanTasks::TestExtensions::AccessPermissionsTestExtension
@@ -1,3 +1,3 @@
1
1
  module ForemanTasks
2
- VERSION = '1.0.1'.freeze
2
+ VERSION = '1.1.0'.freeze
3
3
  end
@@ -2,4 +2,4 @@
2
2
  _("Remote action:")
3
3
  _("Import Puppet classes")
4
4
  _("Import facts")
5
- _("Action with sub plans")
5
+ _("Action with sub plans")
@@ -27,6 +27,7 @@
27
27
  "dependencies": {
28
28
  "c3": "^0.4.11",
29
29
  "humanize-duration": "^3.20.1",
30
+ "react-html-parser": "^2.0.2",
30
31
  "react-intl": "^2.8.0"
31
32
  },
32
33
  "devDependencies": {
@@ -38,10 +39,8 @@
38
39
  "@theforeman/vendor-dev": "^4.0.2",
39
40
  "babel-eslint": "^10.0.3",
40
41
  "eslint": "^6.7.2",
41
- "identity-obj-proxy": "^3.0.0",
42
42
  "jed": "^1.1.1",
43
43
  "prettier": "^1.13.5",
44
- "react-remarkable": "^1.1.3",
45
44
  "stylelint": "^9.3.0",
46
45
  "stylelint-config-standard": "^18.0.0",
47
46
  "surge": "^0.20.3"
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env ruby
2
2
  # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
3
3
 
4
- ENGINE_ROOT = File.expand_path('../..', __FILE__)
5
- ENGINE_PATH = File.expand_path('../../lib/foreman_tasks/engine', __FILE__)
4
+ ENGINE_ROOT = File.expand_path('..', __dir__)
5
+ ENGINE_PATH = File.expand_path('../lib/foreman_tasks/engine', __dir__)
6
6
 
7
7
  require 'rails/all'
8
8
  require 'rails/engine/commands'
@@ -22,7 +22,7 @@ FactoryBot.define do
22
22
  execution_plan = ForemanTasks.dynflow.world.plan(Support::DummyDynflowAction)
23
23
  # remove the task created automatically by the persistence
24
24
  ForemanTasks::Task.where(:external_id => execution_plan.id).delete_all
25
- task.update_attributes!(:external_id => execution_plan.id)
25
+ task.update!(:external_id => execution_plan.id)
26
26
  if evaluator.sync_with_dynflow
27
27
  task.update_from_dynflow(execution_plan.to_hash)
28
28
  end
@@ -38,9 +38,41 @@ FactoryBot.define do
38
38
 
39
39
  trait :inconsistent_dynflow_task do
40
40
  after(:build) do |task|
41
- task.update_attributes!(:state => 'running')
41
+ task.update!(:state => 'running')
42
+ end
43
+ end
44
+
45
+ factory :task_with_locks 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 { 3 }
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
+ :lock,
61
+ evaluator.locks_count,
62
+ task: task,
63
+ resource_type: evaluator.resource_type,
64
+ resource_id: evaluator.resource_id
65
+ )
42
66
  end
43
67
  end
44
68
  end
45
69
  end
70
+
71
+ factory :lock, :class => ForemanTasks::Lock do
72
+ name { 'read' }
73
+ resource_type { 'Katello::Repository' }
74
+ resource_id { 1 }
75
+ exclusive { true }
76
+ association :task, factory: :task_with_locks
77
+ end
46
78
  end
@@ -27,3 +27,7 @@ def wait_for(waiting_message = 'something to happen')
27
27
  end
28
28
  raise "waiting for #{waiting_message} was not successful"
29
29
  end
30
+
31
+ def on_postgresql?
32
+ ActiveRecord::Base.connection.adapter_name == 'PostgreSQL'
33
+ end
@@ -8,7 +8,7 @@ module ForemanTasks
8
8
  end
9
9
 
10
10
  # to be able to use the locking
11
- ::User.send(:include, ForemanTasks::Concerns::ActionSubject)
11
+ ::User.include ForemanTasks::Concerns::ActionSubject
12
12
 
13
13
  class ParentAction < Actions::ActionWithSubPlans
14
14
  def plan(user)