dynflow 1.8.1 → 1.8.3

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 (233) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +1 -1
  3. data/.rubocop.yml +11 -5
  4. data/.rubocop_todo.yml +777 -345
  5. data/Gemfile +4 -3
  6. data/Rakefile +1 -0
  7. data/doc/pages/Gemfile +4 -3
  8. data/doc/pages/Rakefile +1 -0
  9. data/doc/pages/plugins/alert_block.rb +1 -0
  10. data/doc/pages/plugins/div_tag.rb +1 -0
  11. data/doc/pages/plugins/graphviz.rb +6 -6
  12. data/doc/pages/plugins/plantuml.rb +2 -3
  13. data/doc/pages/plugins/play.rb +1 -2
  14. data/doc/pages/plugins/tags.rb +2 -8
  15. data/doc/pages/plugins/toc.rb +1 -1
  16. data/dynflow.gemspec +11 -10
  17. data/examples/clock_benchmark.rb +1 -0
  18. data/examples/example_helper.rb +4 -3
  19. data/examples/future_execution.rb +0 -2
  20. data/examples/memory_limit_watcher.rb +8 -8
  21. data/examples/orchestrate.rb +9 -21
  22. data/examples/orchestrate_evented.rb +18 -33
  23. data/examples/remote_executor.rb +13 -14
  24. data/examples/singletons.rb +1 -0
  25. data/examples/sub_plan_concurrency_control.rb +0 -1
  26. data/examples/sub_plans.rb +1 -0
  27. data/examples/sub_plans_v2.rb +1 -0
  28. data/lib/dynflow/action/cancellable.rb +1 -0
  29. data/lib/dynflow/action/format.rb +1 -4
  30. data/lib/dynflow/action/missing.rb +4 -4
  31. data/lib/dynflow/action/polling.rb +2 -3
  32. data/lib/dynflow/action/progress.rb +1 -4
  33. data/lib/dynflow/action/rescue.rb +1 -2
  34. data/lib/dynflow/action/singleton.rb +1 -0
  35. data/lib/dynflow/action/suspended.rb +1 -0
  36. data/lib/dynflow/action/timeouts.rb +2 -1
  37. data/lib/dynflow/action/with_bulk_sub_plans.rb +1 -0
  38. data/lib/dynflow/action/with_polling_sub_plans.rb +1 -1
  39. data/lib/dynflow/action/with_sub_plans.rb +20 -19
  40. data/lib/dynflow/action.rb +37 -37
  41. data/lib/dynflow/active_job/queue_adapter.rb +2 -1
  42. data/lib/dynflow/actor.rb +2 -2
  43. data/lib/dynflow/actors/execution_plan_cleaner.rb +1 -0
  44. data/lib/dynflow/actors.rb +1 -0
  45. data/lib/dynflow/clock.rb +3 -4
  46. data/lib/dynflow/config.rb +6 -5
  47. data/lib/dynflow/connectors/abstract.rb +11 -10
  48. data/lib/dynflow/connectors/database.rb +2 -2
  49. data/lib/dynflow/connectors/direct.rb +2 -3
  50. data/lib/dynflow/connectors.rb +1 -0
  51. data/lib/dynflow/coordinator.rb +2 -6
  52. data/lib/dynflow/coordinator_adapters/abstract.rb +1 -0
  53. data/lib/dynflow/coordinator_adapters/sequel.rb +1 -0
  54. data/lib/dynflow/coordinator_adapters.rb +1 -2
  55. data/lib/dynflow/dead_letter_silencer.rb +1 -0
  56. data/lib/dynflow/debug/telemetry/persistence.rb +3 -2
  57. data/lib/dynflow/delayed_executors/abstract.rb +1 -2
  58. data/lib/dynflow/delayed_executors/abstract_core.rb +1 -1
  59. data/lib/dynflow/delayed_executors/polling.rb +1 -2
  60. data/lib/dynflow/delayed_executors.rb +1 -2
  61. data/lib/dynflow/delayed_plan.rb +6 -6
  62. data/lib/dynflow/director/execution_plan_manager.rb +1 -1
  63. data/lib/dynflow/director/flow_manager.rb +1 -0
  64. data/lib/dynflow/director/queue_hash.rb +2 -1
  65. data/lib/dynflow/director/running_steps_manager.rb +3 -2
  66. data/lib/dynflow/director/sequence_cursor.rb +1 -2
  67. data/lib/dynflow/director/sequential_manager.rb +1 -0
  68. data/lib/dynflow/director.rb +12 -11
  69. data/lib/dynflow/dispatcher/abstract.rb +1 -0
  70. data/lib/dynflow/dispatcher/client_dispatcher.rb +33 -33
  71. data/lib/dynflow/dispatcher/executor_dispatcher.rb +7 -6
  72. data/lib/dynflow/dispatcher.rb +8 -7
  73. data/lib/dynflow/errors.rb +1 -0
  74. data/lib/dynflow/execution_history.rb +2 -1
  75. data/lib/dynflow/execution_plan/dependency_graph.rb +1 -2
  76. data/lib/dynflow/execution_plan/hooks.rb +1 -1
  77. data/lib/dynflow/execution_plan/output_reference.rb +4 -4
  78. data/lib/dynflow/execution_plan/steps/abstract.rb +21 -20
  79. data/lib/dynflow/execution_plan/steps/abstract_flow_step.rb +1 -1
  80. data/lib/dynflow/execution_plan/steps/error.rb +10 -9
  81. data/lib/dynflow/execution_plan/steps/finalize_step.rb +1 -2
  82. data/lib/dynflow/execution_plan/steps/plan_step.rb +12 -11
  83. data/lib/dynflow/execution_plan/steps/run_step.rb +1 -1
  84. data/lib/dynflow/execution_plan/steps.rb +1 -2
  85. data/lib/dynflow/execution_plan.rb +46 -46
  86. data/lib/dynflow/executors/abstract/core.rb +4 -3
  87. data/lib/dynflow/executors/parallel/core.rb +3 -2
  88. data/lib/dynflow/executors/parallel/pool.rb +1 -4
  89. data/lib/dynflow/executors/parallel/worker.rb +1 -0
  90. data/lib/dynflow/executors/parallel.rb +3 -2
  91. data/lib/dynflow/executors/sidekiq/core.rb +3 -1
  92. data/lib/dynflow/executors/sidekiq/internal_job_base.rb +1 -0
  93. data/lib/dynflow/executors/sidekiq/orchestrator_jobs.rb +1 -0
  94. data/lib/dynflow/executors/sidekiq/redis_locking.rb +1 -0
  95. data/lib/dynflow/executors/sidekiq/serialization.rb +1 -0
  96. data/lib/dynflow/executors/sidekiq/worker_jobs.rb +1 -0
  97. data/lib/dynflow/executors.rb +1 -1
  98. data/lib/dynflow/extensions/msgpack.rb +5 -4
  99. data/lib/dynflow/extensions.rb +1 -0
  100. data/lib/dynflow/flows/abstract.rb +1 -1
  101. data/lib/dynflow/flows/abstract_composed.rb +1 -2
  102. data/lib/dynflow/flows/atom.rb +1 -2
  103. data/lib/dynflow/flows/concurrence.rb +1 -1
  104. data/lib/dynflow/flows/registry.rb +1 -0
  105. data/lib/dynflow/flows/sequence.rb +1 -1
  106. data/lib/dynflow/flows.rb +1 -2
  107. data/lib/dynflow/logger_adapters/abstract.rb +1 -1
  108. data/lib/dynflow/logger_adapters/delegator.rb +1 -1
  109. data/lib/dynflow/logger_adapters/formatters/abstract.rb +1 -0
  110. data/lib/dynflow/logger_adapters/formatters/exception.rb +1 -0
  111. data/lib/dynflow/logger_adapters/formatters.rb +1 -0
  112. data/lib/dynflow/logger_adapters/simple.rb +6 -5
  113. data/lib/dynflow/logger_adapters.rb +1 -0
  114. data/lib/dynflow/middleware/common/singleton.rb +1 -0
  115. data/lib/dynflow/middleware/common/transaction.rb +1 -0
  116. data/lib/dynflow/middleware/register.rb +1 -0
  117. data/lib/dynflow/middleware/resolver.rb +2 -3
  118. data/lib/dynflow/middleware/stack.rb +1 -0
  119. data/lib/dynflow/middleware/world.rb +1 -2
  120. data/lib/dynflow/middleware.rb +1 -0
  121. data/lib/dynflow/persistence.rb +4 -5
  122. data/lib/dynflow/persistence_adapters/abstract.rb +1 -1
  123. data/lib/dynflow/persistence_adapters/sequel.rb +14 -14
  124. data/lib/dynflow/persistence_adapters/sequel_migrations/001_initial.rb +2 -1
  125. data/lib/dynflow/persistence_adapters/sequel_migrations/002_incremental_progress.rb +1 -0
  126. data/lib/dynflow/persistence_adapters/sequel_migrations/003_parent_action.rb +1 -0
  127. data/lib/dynflow/persistence_adapters/sequel_migrations/004_coordinator_records.rb +1 -1
  128. data/lib/dynflow/persistence_adapters/sequel_migrations/005_envelopes.rb +1 -0
  129. data/lib/dynflow/persistence_adapters/sequel_migrations/006_fix_data_length.rb +1 -0
  130. data/lib/dynflow/persistence_adapters/sequel_migrations/007_future_execution.rb +1 -0
  131. data/lib/dynflow/persistence_adapters/sequel_migrations/008_rename_scheduled_plans_to_delayed_plans.rb +1 -0
  132. data/lib/dynflow/persistence_adapters/sequel_migrations/009_fix_mysql_data_length.rb +1 -1
  133. data/lib/dynflow/persistence_adapters/sequel_migrations/010_add_execution_plans_label.rb +1 -0
  134. data/lib/dynflow/persistence_adapters/sequel_migrations/011_placeholder.rb +1 -0
  135. data/lib/dynflow/persistence_adapters/sequel_migrations/012_add_delayed_plans_serialized_args.rb +1 -0
  136. data/lib/dynflow/persistence_adapters/sequel_migrations/013_add_action_columns.rb +1 -0
  137. data/lib/dynflow/persistence_adapters/sequel_migrations/014_add_step_columns.rb +1 -0
  138. data/lib/dynflow/persistence_adapters/sequel_migrations/015_add_execution_plan_columns.rb +1 -0
  139. data/lib/dynflow/persistence_adapters/sequel_migrations/016_add_step_queue.rb +1 -0
  140. data/lib/dynflow/persistence_adapters/sequel_migrations/017_add_delayed_plan_frozen.rb +1 -0
  141. data/lib/dynflow/persistence_adapters/sequel_migrations/018_add_uuid_column.rb +37 -30
  142. data/lib/dynflow/persistence_adapters/sequel_migrations/019_update_mysql_time_precision.rb +1 -0
  143. data/lib/dynflow/persistence_adapters/sequel_migrations/020_drop_duplicate_indices.rb +1 -0
  144. data/lib/dynflow/persistence_adapters/sequel_migrations/021_create_output_chunks.rb +4 -3
  145. data/lib/dynflow/persistence_adapters/sequel_migrations/023_sqlite_workarounds.rb +1 -0
  146. data/lib/dynflow/persistence_adapters.rb +1 -0
  147. data/lib/dynflow/rails/configuration.rb +5 -4
  148. data/lib/dynflow/rails/daemon.rb +1 -1
  149. data/lib/dynflow/rails.rb +3 -2
  150. data/lib/dynflow/round_robin.rb +2 -2
  151. data/lib/dynflow/semaphores/abstract.rb +1 -1
  152. data/lib/dynflow/semaphores/aggregating.rb +1 -2
  153. data/lib/dynflow/semaphores/dummy.rb +1 -1
  154. data/lib/dynflow/semaphores/stateful.rb +1 -1
  155. data/lib/dynflow/semaphores.rb +1 -0
  156. data/lib/dynflow/serializable.rb +1 -0
  157. data/lib/dynflow/serializer.rb +2 -2
  158. data/lib/dynflow/serializers/abstract.rb +1 -2
  159. data/lib/dynflow/serializers/noop.rb +1 -2
  160. data/lib/dynflow/serializers.rb +1 -2
  161. data/lib/dynflow/stateful.rb +1 -0
  162. data/lib/dynflow/telemetry.rb +11 -10
  163. data/lib/dynflow/telemetry_adapters/abstract.rb +1 -0
  164. data/lib/dynflow/telemetry_adapters/dummy.rb +1 -0
  165. data/lib/dynflow/telemetry_adapters/statsd.rb +2 -1
  166. data/lib/dynflow/testing/assertions.rb +7 -7
  167. data/lib/dynflow/testing/dummy_coordinator.rb +1 -0
  168. data/lib/dynflow/testing/dummy_execution_plan.rb +1 -0
  169. data/lib/dynflow/testing/dummy_executor.rb +1 -0
  170. data/lib/dynflow/testing/dummy_planned_action.rb +3 -1
  171. data/lib/dynflow/testing/dummy_step.rb +1 -0
  172. data/lib/dynflow/testing/dummy_world.rb +1 -0
  173. data/lib/dynflow/testing/factories.rb +42 -37
  174. data/lib/dynflow/testing/in_thread_executor.rb +1 -0
  175. data/lib/dynflow/testing/in_thread_world.rb +1 -0
  176. data/lib/dynflow/testing/managed_clock.rb +1 -1
  177. data/lib/dynflow/testing/mimic.rb +4 -4
  178. data/lib/dynflow/testing.rb +1 -0
  179. data/lib/dynflow/throttle_limiter.rb +1 -1
  180. data/lib/dynflow/transaction_adapters/abstract.rb +1 -0
  181. data/lib/dynflow/transaction_adapters/active_record.rb +1 -0
  182. data/lib/dynflow/transaction_adapters/none.rb +1 -0
  183. data/lib/dynflow/transaction_adapters.rb +1 -2
  184. data/lib/dynflow/utils/indifferent_hash.rb +7 -1
  185. data/lib/dynflow/utils/priority_queue.rb +1 -0
  186. data/lib/dynflow/utils.rb +1 -1
  187. data/lib/dynflow/version.rb +2 -1
  188. data/lib/dynflow/watchers/memory_consumption_watcher.rb +1 -1
  189. data/lib/dynflow/web/console.rb +1 -3
  190. data/lib/dynflow/web/console_helpers.rb +5 -4
  191. data/lib/dynflow/web/filtering_helpers.rb +1 -0
  192. data/lib/dynflow/web/world_helpers.rb +1 -0
  193. data/lib/dynflow/web.rb +3 -3
  194. data/lib/dynflow/web_console.rb +1 -0
  195. data/lib/dynflow/world/invalidation.rb +1 -0
  196. data/lib/dynflow/world.rb +19 -19
  197. data/lib/dynflow.rb +3 -6
  198. data/test/abnormal_states_recovery_test.rb +4 -8
  199. data/test/action_test.rb +10 -18
  200. data/test/activejob_adapter_test.rb +2 -2
  201. data/test/batch_sub_tasks_test.rb +1 -1
  202. data/test/clock_test.rb +2 -3
  203. data/test/concurrency_control_test.rb +6 -7
  204. data/test/coordinator_test.rb +1 -0
  205. data/test/daemon_test.rb +3 -2
  206. data/test/dead_letter_silencer_test.rb +2 -1
  207. data/test/dispatcher_test.rb +4 -5
  208. data/test/execution_plan_cleaner_test.rb +1 -0
  209. data/test/execution_plan_hooks_test.rb +1 -0
  210. data/test/execution_plan_test.rb +10 -32
  211. data/test/executor_test.rb +20 -37
  212. data/test/extensions_test.rb +1 -0
  213. data/test/flows_test.rb +2 -2
  214. data/test/future_execution_test.rb +2 -3
  215. data/test/memory_cosumption_watcher_test.rb +1 -0
  216. data/test/middleware_test.rb +4 -6
  217. data/test/persistence_test.rb +26 -26
  218. data/test/redis_locking_test.rb +1 -0
  219. data/test/rescue_test.rb +3 -11
  220. data/test/round_robin_test.rb +1 -0
  221. data/test/semaphores_test.rb +5 -7
  222. data/test/support/code_workflow_example.rb +11 -28
  223. data/test/support/dummy_example.rb +20 -19
  224. data/test/support/middleware_example.rb +2 -8
  225. data/test/support/rescue_example.rb +1 -14
  226. data/test/support/test_execution_log.rb +1 -2
  227. data/test/test_helper.rb +3 -7
  228. data/test/testing_test.rb +6 -8
  229. data/test/utils_test.rb +1 -0
  230. data/test/v2_sub_plans_test.rb +1 -0
  231. data/test/web_console_test.rb +4 -4
  232. data/test/world_test.rb +4 -3
  233. metadata +43 -43
@@ -1,10 +1,10 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require_relative 'test_helper'
3
4
 
4
5
  module Dynflow
5
6
  module ExecutionPlanTest
6
7
  describe ExecutionPlan do
7
-
8
8
  include PlanAssertions
9
9
 
10
10
  let(:world) { WorldFactory.create_world }
@@ -15,7 +15,6 @@ module Dynflow
15
15
  end
16
16
 
17
17
  describe 'serialization' do
18
-
19
18
  let :execution_plan do
20
19
  world.plan(Support::CodeWorkflowExample::FastCommit, 'sha' => 'abc123')
21
20
  end
@@ -25,7 +24,6 @@ module Dynflow
25
24
  end
26
25
 
27
26
  describe 'serialized execution plan' do
28
-
29
27
  before { execution_plan.save }
30
28
  after { world.persistence.delete_execution_plans(:uuid => execution_plan.id) }
31
29
 
@@ -46,26 +44,24 @@ module Dynflow
46
44
 
47
45
  it 'handles issues with loading the data' do
48
46
  world.persistence.adapter.send(:table, :step)
49
- .where(execution_plan_uuid: execution_plan.id).delete
47
+ .where(execution_plan_uuid: execution_plan.id).delete
50
48
  refute deserialized_execution_plan.valid?
51
49
  assert_equal Dynflow::Errors::DataConsistencyError, deserialized_execution_plan.exception.class
52
50
  [:label, :state, :started_at, :ended_at].each do |attr|
53
51
  assert_equal execution_plan.send(attr).to_s,
54
- deserialized_execution_plan.send(attr).to_s,
55
- "invalid plan is supposed to still store #{attr}"
52
+ deserialized_execution_plan.send(attr).to_s,
53
+ "invalid plan is supposed to still store #{attr}"
56
54
  end
57
55
  [:execution_time, :real_time].each do |attr|
58
56
  assert_equal execution_plan.send(attr).to_f,
59
- deserialized_execution_plan.send(attr).to_f,
60
- "invalid plan is supposed to still store #{attr}"
57
+ deserialized_execution_plan.send(attr).to_f,
58
+ "invalid plan is supposed to still store #{attr}"
61
59
  end
62
60
  assert_equal execution_plan.execution_history.events,
63
- deserialized_execution_plan.execution_history.events,
64
- "invalid plan is supposed to still store execution history"
61
+ deserialized_execution_plan.execution_history.events,
62
+ "invalid plan is supposed to still store execution history"
65
63
  end
66
-
67
64
  end
68
-
69
65
  end
70
66
 
71
67
  describe '#label' do
@@ -83,24 +79,20 @@ module Dynflow
83
79
  end
84
80
  end
85
81
  describe '#result' do
86
-
87
82
  let :execution_plan do
88
83
  world.plan(Support::CodeWorkflowExample::FastCommit, 'sha' => 'abc123')
89
84
  end
90
85
 
91
86
  describe 'for error in planning phase' do
92
-
93
87
  before { execution_plan.steps[2].set_state :error, true }
94
88
 
95
89
  it 'should be :error' do
96
90
  _(execution_plan.result).must_equal :error
97
91
  _(execution_plan.error?).must_equal true
98
92
  end
99
-
100
93
  end
101
94
 
102
95
  describe 'for error in running phase' do
103
-
104
96
  before do
105
97
  step_id = execution_plan.run_flow.all_step_ids[2]
106
98
  execution_plan.steps[step_id].set_state :error, true
@@ -109,11 +101,9 @@ module Dynflow
109
101
  it 'should be :error' do
110
102
  _(execution_plan.result).must_equal :error
111
103
  end
112
-
113
104
  end
114
105
 
115
106
  describe 'for pending step in running phase' do
116
-
117
107
  before do
118
108
  step_id = execution_plan.run_flow.all_step_ids[2]
119
109
  execution_plan.steps[step_id].set_state :pending, true
@@ -122,11 +112,9 @@ module Dynflow
122
112
  it 'should be :pending' do
123
113
  _(execution_plan.result).must_equal :pending
124
114
  end
125
-
126
115
  end
127
116
 
128
117
  describe 'for all steps successful or skipped' do
129
-
130
118
  before do
131
119
  execution_plan.run_flow.all_step_ids.each_with_index do |step_id, index|
132
120
  step = execution_plan.steps[step_id]
@@ -137,9 +125,7 @@ module Dynflow
137
125
  it 'should be :warning' do
138
126
  _(execution_plan.result).must_equal :warning
139
127
  end
140
-
141
128
  end
142
-
143
129
  end
144
130
 
145
131
  describe 'sub plans' do
@@ -171,11 +157,9 @@ module Dynflow
171
157
  NotifyAssignee
172
158
  PLAN_STEPS
173
159
  end
174
-
175
160
  end
176
161
 
177
162
  describe 'persisted action' do
178
-
179
163
  let :execution_plan do
180
164
  world.plan(Support::CodeWorkflowExample::IncomingIssues, issues_data)
181
165
  end
@@ -206,7 +190,6 @@ module Dynflow
206
190
  end
207
191
 
208
192
  describe 'planning algorithm' do
209
-
210
193
  describe 'single dependencies' do
211
194
  let :execution_plan do
212
195
  world.plan(Support::CodeWorkflowExample::IncomingIssues, issues_data)
@@ -225,7 +208,6 @@ module Dynflow
225
208
  18: NotifyAssignee(pending) {"triage"=>Step(13).output}
226
209
  RUN_FLOW
227
210
  end
228
-
229
211
  end
230
212
 
231
213
  describe 'error in planning phase' do
@@ -286,7 +268,6 @@ module Dynflow
286
268
  end
287
269
 
288
270
  describe 'finalize flow' do
289
-
290
271
  let :execution_plan do
291
272
  world.plan(Support::CodeWorkflowExample::IncomingIssues, issues_data)
292
273
  end
@@ -301,7 +282,6 @@ module Dynflow
301
282
  20: IncomingIssues(pending) {\"issues\"=>[{\"author\"=>\"Peter Smith\", \"text\"=>\"Failing test\"}, {\"author\"=>\"John Doe\", \"text\"=>\"Internal server error\"}]}
302
283
  RUN_FLOW
303
284
  end
304
-
305
285
  end
306
286
  end
307
287
 
@@ -355,7 +335,6 @@ module Dynflow
355
335
  end
356
336
 
357
337
  describe ExecutionPlan::Steps::Error do
358
-
359
338
  it "doesn't fail when deserializing with missing class" do
360
339
  error = ExecutionPlan::Steps::Error.new_from_hash(exception_class: "RenamedError",
361
340
  message: "This errror is not longer here",
@@ -364,7 +343,6 @@ module Dynflow
364
343
  _(error.exception_class.to_s).must_equal "Dynflow::Errors::UnknownError[RenamedError]"
365
344
  _(error.exception.inspect).must_equal "Dynflow::Errors::UnknownError[RenamedError]: This errror is not longer here"
366
345
  end
367
-
368
346
  end
369
347
 
370
348
  describe 'with singleton actions' do
@@ -382,7 +360,7 @@ module Dynflow
382
360
  plan = world.plan(SingletonAction)
383
361
  _(plan.state).must_equal :planned
384
362
  lock_filter = ::Dynflow::Coordinator::SingletonActionLock
385
- .unique_filter plan.entry_action.class.name
363
+ .unique_filter plan.entry_action.class.name
386
364
  _(world.coordinator.find_locks(lock_filter).count).must_equal 1
387
365
  plan = world.execute(plan.id).wait!.value
388
366
  _(plan.state).must_equal :stopped
@@ -394,7 +372,7 @@ module Dynflow
394
372
  plan = world.plan(SingletonAction, :fail => true)
395
373
  _(plan.state).must_equal :planned
396
374
  lock_filter = ::Dynflow::Coordinator::SingletonActionLock
397
- .unique_filter plan.entry_action.class.name
375
+ .unique_filter plan.entry_action.class.name
398
376
  _(world.coordinator.find_locks(lock_filter).count).must_equal 1
399
377
  plan = world.execute(plan.id).wait!.value
400
378
  _(plan.state).must_equal :paused
@@ -1,5 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  # frozen_string_literal: true
3
+
3
4
  require_relative 'test_helper'
4
5
  require 'mocha/minitest'
5
6
 
@@ -11,11 +12,13 @@ require 'dynflow/executors/sidekiq/core'
11
12
 
12
13
  module RedisMocks
13
14
  def release_orchestrator_lock; end
15
+
14
16
  def wait_for_orchestrator_lock; end
17
+
15
18
  def reacquire_orchestrator_lock; end
16
19
  end
17
20
 
18
- ::Dynflow::Executors::Sidekiq::Core.send(:prepend, RedisMocks)
21
+ ::Dynflow::Executors::Sidekiq::Core.prepend RedisMocks
19
22
 
20
23
  module Dynflow
21
24
  module ExecutorTest
@@ -71,9 +74,7 @@ module Dynflow
71
74
  end
72
75
 
73
76
  describe "execution plan state" do
74
-
75
77
  describe "after successful planning" do
76
-
77
78
  let :execution_plan do
78
79
  world.plan(Support::CodeWorkflowExample::IncomingIssues, issues_data)
79
80
  end
@@ -100,7 +101,6 @@ module Dynflow
100
101
  end
101
102
 
102
103
  describe "after error in planning" do
103
-
104
104
  class FailingAction < Dynflow::Action
105
105
  def plan
106
106
  raise "I failed"
@@ -114,7 +114,6 @@ module Dynflow
114
114
  it "is stopped" do
115
115
  _(execution_plan.state).must_equal :stopped
116
116
  end
117
-
118
117
  end
119
118
 
120
119
  describe "when being executed" do
@@ -166,7 +165,6 @@ module Dynflow
166
165
  end
167
166
 
168
167
  describe "execution of run flow" do
169
-
170
168
  before do
171
169
  TestExecutionLog.setup
172
170
  end
@@ -230,8 +228,8 @@ module Dynflow
230
228
  describe 'handling errors in setup' do
231
229
  let :execution_plan do
232
230
  world.plan(Support::DummyExample::Polling,
233
- external_task_id: '123',
234
- text: 'troll setup')
231
+ external_task_id: '123',
232
+ text: 'troll setup')
235
233
  end
236
234
 
237
235
  it 'fails' do
@@ -310,8 +308,8 @@ module Dynflow
310
308
  describe 'plan with one action' do
311
309
  let :execution_plan do
312
310
  world.plan(Support::DummyExample::Polling,
313
- { external_task_id: '123',
314
- text: 'pause in progress 20%' })
311
+ { external_task_id: '123',
312
+ text: 'pause in progress 20%' })
315
313
  end
316
314
 
317
315
  it 'determines the progress of the execution plan in percents' do
@@ -325,8 +323,8 @@ module Dynflow
325
323
  describe 'plan with more action' do
326
324
  let :execution_plan do
327
325
  world.plan(Support::DummyExample::WeightedPolling,
328
- { external_task_id: '123',
329
- text: 'pause in progress 20%' })
326
+ { external_task_id: '123',
327
+ text: 'pause in progress 20%' })
330
328
  end
331
329
 
332
330
  it 'takes the steps weight in account' do
@@ -341,8 +339,8 @@ module Dynflow
341
339
  describe 'works when resumed after error' do
342
340
  let :execution_plan do
343
341
  world.plan(Support::DummyExample::Polling,
344
- { external_task_id: '123',
345
- text: 'troll progress' })
342
+ { external_task_id: '123',
343
+ text: 'troll progress' })
346
344
  end
347
345
 
348
346
  specify do
@@ -356,11 +354,9 @@ module Dynflow
356
354
  assert_equal :success, ep.run_steps.first.state
357
355
  end
358
356
  end
359
-
360
357
  end
361
358
 
362
359
  describe "action with empty flows" do
363
-
364
360
  let :execution_plan do
365
361
  world.plan(Support::CodeWorkflowExample::Dummy, { :text => "dummy" }).tap do |plan|
366
362
  assert_equal plan.run_flow.size, 0
@@ -379,11 +375,9 @@ module Dynflow
379
375
  world.execute(execution_plan.id)
380
376
  assert_raises(Dynflow::Error) { world.execute(execution_plan.id).value! }
381
377
  end
382
-
383
378
  end
384
379
 
385
380
  describe 'action with empty run flow but some finalize flow' do
386
-
387
381
  let :execution_plan do
388
382
  world.plan(Support::CodeWorkflowExample::DummyWithFinalize, { :text => "dummy" }).tap do |plan|
389
383
  assert_equal plan.run_flow.size, 0
@@ -395,7 +389,6 @@ module Dynflow
395
389
  _(result.result).must_equal :success
396
390
  _(result.state).must_equal :stopped
397
391
  end
398
-
399
392
  end
400
393
 
401
394
  describe 'running' do
@@ -417,7 +410,6 @@ module Dynflow
417
410
  EXECUTED_RUN_FLOW
418
411
  end
419
412
  end
420
-
421
413
  end
422
414
 
423
415
  describe "execution of finalize flow" do
@@ -438,10 +430,10 @@ module Dynflow
438
430
 
439
431
  it "runs all the steps in the finalize flow" do
440
432
  assert_finalized(Support::CodeWorkflowExample::IncomingIssues,
441
- { "issues" => [{ "author" => "Peter Smith", "text" => "Failing test" },
442
- { "author" => "John Doe", "text" => "Internal server error" }] })
433
+ { "issues" => [{ "author" => "Peter Smith", "text" => "Failing test" },
434
+ { "author" => "John Doe", "text" => "Internal server error" }] })
443
435
  assert_finalized(Support::CodeWorkflowExample::Triage,
444
- { "author" => "Peter Smith", "text" => "Failing test" })
436
+ { "author" => "Peter Smith", "text" => "Failing test" })
445
437
  end
446
438
  end
447
439
 
@@ -454,7 +446,6 @@ module Dynflow
454
446
  _(TestExecutionLog.finalize.size).must_equal 0
455
447
  end
456
448
  end
457
-
458
449
  end
459
450
 
460
451
  describe "re-execution of run flow after fix in run phase" do
@@ -493,13 +484,11 @@ module Dynflow
493
484
  13: Triage(success) {\"author\"=>\"John Doe\", \"text\"=>\"ok\"} --> {\"classification\"=>{\"assignee\"=>\"John Doe\", \"severity\"=>\"medium\"}}
494
485
  16: UpdateIssue(success) {\"author\"=>\"John Doe\", \"text\"=>\"trolling\", \"assignee\"=>\"John Doe\", \"severity\"=>\"medium\"} --> {}
495
486
  18: NotifyAssignee(success) {\"triage\"=>{\"classification\"=>{\"assignee\"=>\"John Doe\", \"severity\"=>\"medium\"}}} --> {}
496
- EXECUTED_RUN_FLOW
487
+ EXECUTED_RUN_FLOW
497
488
  end
498
-
499
489
  end
500
490
 
501
491
  describe "re-execution of run flow after fix in finalize phase" do
502
-
503
492
  after do
504
493
  TestExecutionLog.teardown
505
494
  end
@@ -532,13 +521,11 @@ module Dynflow
532
521
  14: Triage(success) {\"author\"=>\"John Doe\", \"text\"=>\"ok\"} --> {\"classification\"=>{\"assignee\"=>\"John Doe\", \"severity\"=>\"medium\"}}
533
522
  19: NotifyAssignee(success) {\"triage\"=>{\"classification\"=>{\"assignee\"=>\"John Doe\", \"severity\"=>\"medium\"}}} --> {}
534
523
  20: IncomingIssues(success) {\"issues\"=>[{\"author\"=>\"Peter Smith\", \"text\"=>\"Failing test\"}, {\"author\"=>\"John Doe\", \"text\"=>\"trolling in finalize\"}]} --> {}
535
- EXECUTED_RUN_FLOW
524
+ EXECUTED_RUN_FLOW
536
525
  end
537
-
538
526
  end
539
527
 
540
528
  describe "re-execution of run flow after skipping" do
541
-
542
529
  after do
543
530
  TestExecutionLog.teardown
544
531
  end
@@ -571,7 +558,7 @@ module Dynflow
571
558
  13: Triage(skipped) {\"author\"=>\"John Doe\", \"text\"=>\"trolling\"} --> {}
572
559
  16: UpdateIssue(skipped) {\"author\"=>\"John Doe\", \"text\"=>\"trolling\", \"assignee\"=>Step(13).output[:classification][:assignee], \"severity\"=>Step(13).output[:classification][:severity]} --> {}
573
560
  18: NotifyAssignee(skipped) {\"triage\"=>Step(13).output} --> {}
574
- EXECUTED_RUN_FLOW
561
+ EXECUTED_RUN_FLOW
575
562
 
576
563
  assert_finalize_flow <<-FINALIZE_FLOW, resumed_execution_plan
577
564
  Dynflow::Flows::Sequence
@@ -580,8 +567,7 @@ module Dynflow
580
567
  14: Triage(skipped) {\"author\"=>\"John Doe\", \"text\"=>\"trolling\"} --> {}
581
568
  19: NotifyAssignee(skipped) {\"triage\"=>Step(13).output} --> {}
582
569
  20: IncomingIssues(success) {\"issues\"=>[{\"author\"=>\"Peter Smith\", \"text\"=>\"Failing test\"}, {\"author\"=>\"John Doe\", \"text\"=>\"trolling\"}]} --> {}
583
- FINALIZE_FLOW
584
-
570
+ FINALIZE_FLOW
585
571
  end
586
572
  end
587
573
 
@@ -617,7 +603,6 @@ module Dynflow
617
603
  end
618
604
 
619
605
  describe 'what_is_next with errors' do
620
-
621
606
  it "doesn't return next steps if requirements failed" do
622
607
  assert_next_steps([4, 13])
623
608
  assert_next_steps([], 4, false)
@@ -631,7 +616,6 @@ module Dynflow
631
616
  assert manager.done?
632
617
  end
633
618
  end
634
-
635
619
  end
636
620
 
637
621
  describe 'Pool::JobStorage' do
@@ -673,7 +657,6 @@ module Dynflow
673
657
  assert_nil storage.pop
674
658
  end
675
659
  end
676
-
677
660
  end
678
661
 
679
662
  describe 'termination' do
@@ -682,7 +665,7 @@ module Dynflow
682
665
  it 'waits for currently running actions' do
683
666
  $slow_actions_done = 0
684
667
  running = world.trigger(Support::DummyExample::Slow, 1)
685
- suspended = world.trigger(Support::DummyExample::DeprecatedEventedAction, :timeout => 3 )
668
+ suspended = world.trigger(Support::DummyExample::DeprecatedEventedAction, :timeout => 3)
686
669
  sleep 0.2
687
670
  world.terminate.wait
688
671
  _($slow_actions_done).must_equal 1
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require_relative 'test_helper'
3
4
  require 'active_support/time'
4
5
 
data/test/flows_test.rb CHANGED
@@ -1,10 +1,10 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require_relative 'test_helper'
3
4
  require 'mocha/minitest'
4
5
 
5
6
  module Dynflow
6
7
  describe 'flow' do
7
-
8
8
  class TestRegistry < Flows::Registry
9
9
  class << self
10
10
  def reset!
@@ -22,7 +22,7 @@ module Dynflow
22
22
  TestRegistry.register!(TestRegistry, 'TS')
23
23
  TestRegistry.register!(Integer, 'I')
24
24
  map = TestRegistry.instance_variable_get("@serialization_map")
25
- _(map).must_equal({'TS' => TestRegistry, 'I' => Integer})
25
+ _(map).must_equal({ 'TS' => TestRegistry, 'I' => Integer })
26
26
  end
27
27
 
28
28
  it "prevents overwriting values" do
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require_relative 'test_helper'
3
4
 
4
5
  module Dynflow
@@ -9,7 +10,6 @@ module Dynflow
9
10
  include Dynflow::Testing::Factories
10
11
 
11
12
  describe 'action scheduling' do
12
-
13
13
  before do
14
14
  @start_at = Time.now.utc + 180
15
15
  world.persistence.delete_delayed_plans({})
@@ -98,10 +98,9 @@ module Dynflow
98
98
  delayed_plan.timeout
99
99
  _(execution_plan.state).must_equal :stopped
100
100
  _(execution_plan.result).must_equal :error
101
- _(execution_plan.errors.first.message).must_match /could not be started before set time/
101
+ _(execution_plan.errors.first.message).must_match(/could not be started before set time/)
102
102
  _(history_names.call(execution_plan)).must_equal %W(delay timeout)
103
103
  end
104
-
105
104
  end
106
105
 
107
106
  describe 'polling delayed executor' do
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require_relative 'test_helper'
3
4
  require 'fileutils'
4
5
  require 'dynflow/watchers/memory_consumption_watcher'
@@ -1,9 +1,9 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require_relative 'test_helper'
3
4
 
4
5
  module Dynflow
5
6
  module MiddlewareTest
6
-
7
7
  describe 'Middleware' do
8
8
  let(:world) { WorldFactory.create_world }
9
9
  let(:log) { Support::MiddlewareExample::LogMiddleware.log }
@@ -77,8 +77,7 @@ module Dynflow
77
77
  let(:world_with_middleware) do
78
78
  WorldFactory.create_world.tap do |world|
79
79
  world.middleware.use(Support::MiddlewareExample::AnotherLogRunMiddleware,
80
- after: Support::MiddlewareExample::LogRunMiddleware)
81
-
80
+ after: Support::MiddlewareExample::LogRunMiddleware)
82
81
  end
83
82
  end
84
83
 
@@ -112,7 +111,7 @@ module Dynflow
112
111
  it "allows access the running action" do
113
112
  world = WorldFactory.create_world
114
113
  world.middleware.use(Support::MiddlewareExample::ObservingMiddleware,
115
- replace: Support::MiddlewareExample::LogRunMiddleware)
114
+ replace: Support::MiddlewareExample::LogRunMiddleware)
116
115
  world.trigger(Support::MiddlewareExample::Action, message: 'hello').finished.wait
117
116
  _(log).must_equal %w[input#message:hello
118
117
  run
@@ -122,7 +121,7 @@ module Dynflow
122
121
  it "allows modification of the running action when delaying execution" do
123
122
  world = WorldFactory.create_world
124
123
  world.middleware.use(Support::MiddlewareExample::AnotherObservingMiddleware,
125
- replace: Support::MiddlewareExample::LogRunMiddleware)
124
+ replace: Support::MiddlewareExample::LogRunMiddleware)
126
125
  delay = world.delay(Support::MiddlewareExample::Action, { :start_at => Time.now - 60 })
127
126
  plan = world.persistence.load_delayed_plan delay.execution_plan_id
128
127
  plan.plan
@@ -183,7 +182,6 @@ module Dynflow
183
182
  _(presenter_without_middleware.input['text']).must_equal('Lord Voldemort is comming')
184
183
  end
185
184
  end
186
-
187
185
  end
188
186
  end
189
187
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require_relative 'test_helper'
3
4
  require 'tmpdir'
4
5
  require 'ostruct'
@@ -6,7 +7,6 @@ require 'ostruct'
6
7
  module Dynflow
7
8
  module PersistenceTest
8
9
  describe 'persistence adapters' do
9
-
10
10
  let :execution_plans_data do
11
11
  [{ id: 'plan1', :label => 'test1', root_plan_step_id: 1, class: 'Dynflow::ExecutionPlan', state: 'paused' },
12
12
  { id: 'plan2', :label => 'test2', root_plan_step_id: 1, class: 'Dynflow::ExecutionPlan', state: 'stopped' },
@@ -20,8 +20,8 @@ module Dynflow
20
20
  caller_execution_plan_id: nil,
21
21
  caller_action_id: nil,
22
22
  class: 'Dynflow::Action',
23
- input: {key: 'value'},
24
- output: {something: 'else'},
23
+ input: { key: 'value' },
24
+ output: { something: 'else' },
25
25
  plan_step_id: 1,
26
26
  run_step_id: 2,
27
27
  finalize_step_id: 3
@@ -150,9 +150,9 @@ module Dynflow
150
150
  _(loaded_plans).must_be_empty
151
151
 
152
152
  adapter.save_delayed_plan('plan1',
153
- :execution_plan_uuid => 'plan1',
154
- :start_at => format_time(Time.now + 60),
155
- :start_before => format_time(Time.now - 60))
153
+ :execution_plan_uuid => 'plan1',
154
+ :start_at => format_time(Time.now + 60),
155
+ :start_before => format_time(Time.now - 60))
156
156
  loaded_plans = adapter.find_execution_plans(filters: { label: ['test1'], :delayed => true })
157
157
  _(loaded_plans.map { |h| h[:id] }).must_equal ['plan1']
158
158
  end
@@ -169,29 +169,29 @@ module Dynflow
169
169
  prepare_and_save_plans
170
170
  if adapter.ordering_by.include?('state')
171
171
  loaded_plans = adapter.find_execution_plan_statuses(filters: { label: ['test1'] })
172
- _(loaded_plans).must_equal({ 'plan1' => { state: 'paused', result: nil} })
172
+ _(loaded_plans).must_equal({ 'plan1' => { state: 'paused', result: nil } })
173
173
 
174
174
  loaded_plans = adapter.find_execution_plan_statuses(filters: { state: ['paused'] })
175
- _(loaded_plans).must_equal({"plan1"=>{:state=>"paused", :result=>nil},
176
- "plan3"=>{:state=>"paused", :result=>nil},
177
- "plan4"=>{:state=>"paused", :result=>nil}})
175
+ _(loaded_plans).must_equal({ "plan1" => { :state => "paused", :result => nil },
176
+ "plan3" => { :state => "paused", :result => nil },
177
+ "plan4" => { :state => "paused", :result => nil } })
178
178
 
179
179
  loaded_plans = adapter.find_execution_plan_statuses(filters: { state: ['stopped'] })
180
- _(loaded_plans).must_equal({"plan2"=>{:state=>"stopped", :result=>nil}})
180
+ _(loaded_plans).must_equal({ "plan2" => { :state => "stopped", :result => nil } })
181
181
 
182
182
  loaded_plans = adapter.find_execution_plan_statuses(filters: { state: [] })
183
183
  _(loaded_plans).must_equal({})
184
184
 
185
185
  loaded_plans = adapter.find_execution_plan_statuses(filters: { state: ['stopped', 'paused'] })
186
- _(loaded_plans).must_equal({"plan1"=>{:state=>"paused", :result=>nil},
187
- "plan2"=>{:state=>"stopped", :result=>nil},
188
- "plan3"=>{:state=>"paused", :result=>nil}, "plan4"=>{:state=>"paused", :result=>nil}})
186
+ _(loaded_plans).must_equal({ "plan1" => { :state => "paused", :result => nil },
187
+ "plan2" => { :state => "stopped", :result => nil },
188
+ "plan3" => { :state => "paused", :result => nil }, "plan4" => { :state => "paused", :result => nil } })
189
189
 
190
190
  loaded_plans = adapter.find_execution_plan_statuses(filters: { 'state' => ['stopped', 'paused'] })
191
- _(loaded_plans).must_equal({"plan1"=>{:state=>"paused", :result=>nil},
192
- "plan2"=>{:state=>"stopped", :result=>nil},
193
- "plan3"=>{:state=>"paused", :result=>nil},
194
- "plan4"=>{:state=>"paused", :result=>nil}})
191
+ _(loaded_plans).must_equal({ "plan1" => { :state => "paused", :result => nil },
192
+ "plan2" => { :state => "stopped", :result => nil },
193
+ "plan3" => { :state => "paused", :result => nil },
194
+ "plan4" => { :state => "paused", :result => nil } })
195
195
 
196
196
  loaded_plans = adapter.find_execution_plan_statuses(filters: { label: ['test1'], :delayed => true })
197
197
  _(loaded_plans).must_equal({})
@@ -229,9 +229,9 @@ module Dynflow
229
229
  _(loaded_plans).must_equal 0
230
230
 
231
231
  adapter.save_delayed_plan('plan1',
232
- :execution_plan_uuid => 'plan1',
233
- :start_at => format_time(Time.now + 60),
234
- :start_before => format_time(Time.now - 60))
232
+ :execution_plan_uuid => 'plan1',
233
+ :start_at => format_time(Time.now + 60),
234
+ :start_before => format_time(Time.now - 60))
235
235
  loaded_plans = adapter.find_execution_plan_counts(filters: { label: ['test1'], :delayed => true })
236
236
  _(loaded_plans).must_equal 1
237
237
  end
@@ -276,14 +276,14 @@ module Dynflow
276
276
  it 'creates backup dir and produce backup including steps and actions' do
277
277
  prepare_plans_with_steps
278
278
  Dir.mktmpdir do |backup_dir|
279
- _(adapter.delete_execution_plans({'uuid' => 'plan1'}, 100, backup_dir)).must_equal 1
279
+ _(adapter.delete_execution_plans({ 'uuid' => 'plan1' }, 100, backup_dir)).must_equal 1
280
280
  plans = CSV.read(backup_dir + "/execution_plans.csv", :headers => true)
281
281
  assert_equal 1, plans.count
282
282
  assert_equal 'plan1', plans.first.to_hash['uuid']
283
283
  actions = CSV.read(backup_dir + "/actions.csv", :headers => true)
284
284
  assert_equal 1, actions.count
285
285
  assert_equal 'plan1', actions.first.to_hash['execution_plan_uuid']
286
- steps = CSV.read(backup_dir +"/steps.csv", :headers => true)
286
+ steps = CSV.read(backup_dir + "/steps.csv", :headers => true)
287
287
  assert_equal 1, steps.count
288
288
  assert_equal 'plan1', steps.first.to_hash['execution_plan_uuid']
289
289
  end
@@ -376,7 +376,7 @@ module Dynflow
376
376
  it 'deletes output chunks' do
377
377
  prepare_plans_with_actions
378
378
 
379
- adapter.save_output_chunks('plan1', 1, [{chunk: "Hello", timestamp: Time.now}, {chunk: "Bye", timestamp: Time.now}])
379
+ adapter.save_output_chunks('plan1', 1, [{ chunk: "Hello", timestamp: Time.now }, { chunk: "Bye", timestamp: Time.now }])
380
380
  chunks = adapter.load_output_chunks('plan1', 1)
381
381
  _(chunks.length).must_equal 2
382
382
  deleted = adapter.delete_output_chunks('plan1', 1)
@@ -451,7 +451,7 @@ module Dynflow
451
451
  envelopes = [client_envelope, executor_envelope]
452
452
 
453
453
  envelopes.each { |e| adapter.push_envelope(e) }
454
- adapter.insert_coordinator_record({"class"=>"Dynflow::Coordinator::ExecutorWorld",
454
+ adapter.insert_coordinator_record({ "class" => "Dynflow::Coordinator::ExecutorWorld",
455
455
  "id" => executor_world_id, "meta" => {}, "active" => true })
456
456
 
457
457
  assert_equal 1, adapter.prune_undeliverable_envelopes
@@ -526,7 +526,7 @@ module Dynflow
526
526
 
527
527
  value = 'a' * 1000
528
528
 
529
- adata = action_data.merge({:output => { :key => value }})
529
+ adata = action_data.merge({ :output => { :key => value } })
530
530
  plan_record = adapter.send(:prepare_record, :execution_plan, plan.merge(:uuid => plan[:id]))
531
531
  action_record = adapter.send(:prepare_record, :action, adata.dup)
532
532