dynflow 1.8.2 → 1.8.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ruby.yml +1 -1
- data/.rubocop.yml +11 -5
- data/.rubocop_todo.yml +777 -345
- data/Gemfile +4 -3
- data/Rakefile +1 -0
- data/doc/pages/Gemfile +4 -3
- data/doc/pages/Rakefile +1 -0
- data/doc/pages/plugins/alert_block.rb +1 -0
- data/doc/pages/plugins/div_tag.rb +1 -0
- data/doc/pages/plugins/graphviz.rb +6 -6
- data/doc/pages/plugins/plantuml.rb +2 -3
- data/doc/pages/plugins/play.rb +1 -2
- data/doc/pages/plugins/tags.rb +2 -8
- data/doc/pages/plugins/toc.rb +1 -1
- data/dynflow.gemspec +11 -10
- data/examples/clock_benchmark.rb +1 -0
- data/examples/example_helper.rb +4 -3
- data/examples/future_execution.rb +0 -2
- data/examples/memory_limit_watcher.rb +8 -8
- data/examples/orchestrate.rb +9 -21
- data/examples/orchestrate_evented.rb +18 -33
- data/examples/remote_executor.rb +9 -11
- data/examples/singletons.rb +1 -0
- data/examples/sub_plan_concurrency_control.rb +0 -1
- data/examples/sub_plans.rb +1 -0
- data/examples/sub_plans_v2.rb +1 -0
- data/lib/dynflow/action/cancellable.rb +1 -0
- data/lib/dynflow/action/format.rb +1 -4
- data/lib/dynflow/action/missing.rb +4 -4
- data/lib/dynflow/action/polling.rb +2 -3
- data/lib/dynflow/action/progress.rb +1 -4
- data/lib/dynflow/action/rescue.rb +1 -2
- data/lib/dynflow/action/singleton.rb +1 -0
- data/lib/dynflow/action/suspended.rb +1 -0
- data/lib/dynflow/action/timeouts.rb +2 -1
- data/lib/dynflow/action/with_bulk_sub_plans.rb +1 -0
- data/lib/dynflow/action/with_polling_sub_plans.rb +1 -1
- data/lib/dynflow/action/with_sub_plans.rb +20 -19
- data/lib/dynflow/action.rb +37 -37
- data/lib/dynflow/active_job/queue_adapter.rb +2 -1
- data/lib/dynflow/actor.rb +2 -2
- data/lib/dynflow/actors/execution_plan_cleaner.rb +1 -0
- data/lib/dynflow/actors.rb +1 -0
- data/lib/dynflow/clock.rb +3 -4
- data/lib/dynflow/config.rb +6 -5
- data/lib/dynflow/connectors/abstract.rb +11 -10
- data/lib/dynflow/connectors/database.rb +2 -2
- data/lib/dynflow/connectors/direct.rb +2 -3
- data/lib/dynflow/connectors.rb +1 -0
- data/lib/dynflow/coordinator.rb +21 -9
- data/lib/dynflow/coordinator_adapters/abstract.rb +1 -0
- data/lib/dynflow/coordinator_adapters/sequel.rb +1 -0
- data/lib/dynflow/coordinator_adapters.rb +1 -2
- data/lib/dynflow/dead_letter_silencer.rb +1 -0
- data/lib/dynflow/debug/telemetry/persistence.rb +3 -2
- data/lib/dynflow/delayed_executors/abstract.rb +1 -2
- data/lib/dynflow/delayed_executors/abstract_core.rb +1 -1
- data/lib/dynflow/delayed_executors/polling.rb +1 -2
- data/lib/dynflow/delayed_executors.rb +1 -2
- data/lib/dynflow/delayed_plan.rb +6 -6
- data/lib/dynflow/director/execution_plan_manager.rb +1 -1
- data/lib/dynflow/director/flow_manager.rb +1 -0
- data/lib/dynflow/director/queue_hash.rb +2 -1
- data/lib/dynflow/director/running_steps_manager.rb +3 -2
- data/lib/dynflow/director/sequence_cursor.rb +1 -2
- data/lib/dynflow/director/sequential_manager.rb +1 -0
- data/lib/dynflow/director.rb +12 -11
- data/lib/dynflow/dispatcher/abstract.rb +1 -0
- data/lib/dynflow/dispatcher/client_dispatcher.rb +33 -33
- data/lib/dynflow/dispatcher/executor_dispatcher.rb +7 -6
- data/lib/dynflow/dispatcher.rb +8 -7
- data/lib/dynflow/errors.rb +1 -0
- data/lib/dynflow/execution_history.rb +2 -1
- data/lib/dynflow/execution_plan/dependency_graph.rb +1 -2
- data/lib/dynflow/execution_plan/hooks.rb +1 -1
- data/lib/dynflow/execution_plan/output_reference.rb +4 -4
- data/lib/dynflow/execution_plan/steps/abstract.rb +21 -20
- data/lib/dynflow/execution_plan/steps/abstract_flow_step.rb +1 -1
- data/lib/dynflow/execution_plan/steps/error.rb +10 -9
- data/lib/dynflow/execution_plan/steps/finalize_step.rb +1 -2
- data/lib/dynflow/execution_plan/steps/plan_step.rb +12 -11
- data/lib/dynflow/execution_plan/steps/run_step.rb +1 -1
- data/lib/dynflow/execution_plan/steps.rb +1 -2
- data/lib/dynflow/execution_plan.rb +46 -46
- data/lib/dynflow/executors/abstract/core.rb +4 -3
- data/lib/dynflow/executors/parallel/core.rb +3 -2
- data/lib/dynflow/executors/parallel/pool.rb +1 -4
- data/lib/dynflow/executors/parallel/worker.rb +1 -0
- data/lib/dynflow/executors/parallel.rb +3 -2
- data/lib/dynflow/executors/sidekiq/core.rb +2 -0
- data/lib/dynflow/executors/sidekiq/internal_job_base.rb +1 -0
- data/lib/dynflow/executors/sidekiq/orchestrator_jobs.rb +1 -0
- data/lib/dynflow/executors/sidekiq/redis_locking.rb +1 -0
- data/lib/dynflow/executors/sidekiq/serialization.rb +1 -0
- data/lib/dynflow/executors/sidekiq/worker_jobs.rb +1 -0
- data/lib/dynflow/executors.rb +1 -1
- data/lib/dynflow/extensions/msgpack.rb +5 -4
- data/lib/dynflow/extensions.rb +1 -0
- data/lib/dynflow/flows/abstract.rb +1 -1
- data/lib/dynflow/flows/abstract_composed.rb +1 -2
- data/lib/dynflow/flows/atom.rb +1 -2
- data/lib/dynflow/flows/concurrence.rb +1 -1
- data/lib/dynflow/flows/registry.rb +1 -0
- data/lib/dynflow/flows/sequence.rb +1 -1
- data/lib/dynflow/flows.rb +1 -2
- data/lib/dynflow/logger_adapters/abstract.rb +1 -1
- data/lib/dynflow/logger_adapters/delegator.rb +1 -1
- data/lib/dynflow/logger_adapters/formatters/abstract.rb +1 -0
- data/lib/dynflow/logger_adapters/formatters/exception.rb +1 -0
- data/lib/dynflow/logger_adapters/formatters.rb +1 -0
- data/lib/dynflow/logger_adapters/simple.rb +6 -5
- data/lib/dynflow/logger_adapters.rb +1 -0
- data/lib/dynflow/middleware/common/singleton.rb +1 -0
- data/lib/dynflow/middleware/common/transaction.rb +1 -0
- data/lib/dynflow/middleware/register.rb +1 -0
- data/lib/dynflow/middleware/resolver.rb +2 -3
- data/lib/dynflow/middleware/stack.rb +1 -0
- data/lib/dynflow/middleware/world.rb +1 -2
- data/lib/dynflow/middleware.rb +1 -0
- data/lib/dynflow/persistence.rb +4 -5
- data/lib/dynflow/persistence_adapters/abstract.rb +1 -1
- data/lib/dynflow/persistence_adapters/sequel.rb +14 -14
- data/lib/dynflow/persistence_adapters/sequel_migrations/001_initial.rb +2 -1
- data/lib/dynflow/persistence_adapters/sequel_migrations/002_incremental_progress.rb +1 -0
- data/lib/dynflow/persistence_adapters/sequel_migrations/003_parent_action.rb +1 -0
- data/lib/dynflow/persistence_adapters/sequel_migrations/004_coordinator_records.rb +1 -1
- data/lib/dynflow/persistence_adapters/sequel_migrations/005_envelopes.rb +1 -0
- data/lib/dynflow/persistence_adapters/sequel_migrations/006_fix_data_length.rb +1 -0
- data/lib/dynflow/persistence_adapters/sequel_migrations/007_future_execution.rb +1 -0
- data/lib/dynflow/persistence_adapters/sequel_migrations/008_rename_scheduled_plans_to_delayed_plans.rb +1 -0
- data/lib/dynflow/persistence_adapters/sequel_migrations/009_fix_mysql_data_length.rb +1 -1
- data/lib/dynflow/persistence_adapters/sequel_migrations/010_add_execution_plans_label.rb +1 -0
- data/lib/dynflow/persistence_adapters/sequel_migrations/011_placeholder.rb +1 -0
- data/lib/dynflow/persistence_adapters/sequel_migrations/012_add_delayed_plans_serialized_args.rb +1 -0
- data/lib/dynflow/persistence_adapters/sequel_migrations/013_add_action_columns.rb +1 -0
- data/lib/dynflow/persistence_adapters/sequel_migrations/014_add_step_columns.rb +1 -0
- data/lib/dynflow/persistence_adapters/sequel_migrations/015_add_execution_plan_columns.rb +1 -0
- data/lib/dynflow/persistence_adapters/sequel_migrations/016_add_step_queue.rb +1 -0
- data/lib/dynflow/persistence_adapters/sequel_migrations/017_add_delayed_plan_frozen.rb +1 -0
- data/lib/dynflow/persistence_adapters/sequel_migrations/018_add_uuid_column.rb +37 -30
- data/lib/dynflow/persistence_adapters/sequel_migrations/019_update_mysql_time_precision.rb +1 -0
- data/lib/dynflow/persistence_adapters/sequel_migrations/020_drop_duplicate_indices.rb +1 -0
- data/lib/dynflow/persistence_adapters/sequel_migrations/021_create_output_chunks.rb +4 -3
- data/lib/dynflow/persistence_adapters/sequel_migrations/023_sqlite_workarounds.rb +1 -0
- data/lib/dynflow/persistence_adapters.rb +1 -0
- data/lib/dynflow/rails/configuration.rb +1 -0
- data/lib/dynflow/rails/daemon.rb +1 -1
- data/lib/dynflow/rails.rb +3 -2
- data/lib/dynflow/round_robin.rb +2 -2
- data/lib/dynflow/semaphores/abstract.rb +1 -1
- data/lib/dynflow/semaphores/aggregating.rb +1 -2
- data/lib/dynflow/semaphores/dummy.rb +1 -1
- data/lib/dynflow/semaphores/stateful.rb +1 -1
- data/lib/dynflow/semaphores.rb +1 -0
- data/lib/dynflow/serializable.rb +1 -0
- data/lib/dynflow/serializer.rb +2 -2
- data/lib/dynflow/serializers/abstract.rb +1 -2
- data/lib/dynflow/serializers/noop.rb +1 -2
- data/lib/dynflow/serializers.rb +1 -2
- data/lib/dynflow/stateful.rb +1 -0
- data/lib/dynflow/telemetry.rb +11 -10
- data/lib/dynflow/telemetry_adapters/abstract.rb +1 -0
- data/lib/dynflow/telemetry_adapters/dummy.rb +1 -0
- data/lib/dynflow/telemetry_adapters/statsd.rb +2 -1
- data/lib/dynflow/testing/assertions.rb +7 -7
- data/lib/dynflow/testing/dummy_coordinator.rb +1 -0
- data/lib/dynflow/testing/dummy_execution_plan.rb +1 -0
- data/lib/dynflow/testing/dummy_executor.rb +1 -0
- data/lib/dynflow/testing/dummy_planned_action.rb +3 -1
- data/lib/dynflow/testing/dummy_step.rb +1 -0
- data/lib/dynflow/testing/dummy_world.rb +1 -0
- data/lib/dynflow/testing/factories.rb +42 -37
- data/lib/dynflow/testing/in_thread_executor.rb +1 -0
- data/lib/dynflow/testing/in_thread_world.rb +1 -0
- data/lib/dynflow/testing/managed_clock.rb +1 -1
- data/lib/dynflow/testing/mimic.rb +4 -4
- data/lib/dynflow/testing.rb +1 -0
- data/lib/dynflow/throttle_limiter.rb +1 -1
- data/lib/dynflow/transaction_adapters/abstract.rb +1 -0
- data/lib/dynflow/transaction_adapters/active_record.rb +1 -0
- data/lib/dynflow/transaction_adapters/none.rb +1 -0
- data/lib/dynflow/transaction_adapters.rb +1 -2
- data/lib/dynflow/utils/indifferent_hash.rb +7 -1
- data/lib/dynflow/utils/priority_queue.rb +1 -0
- data/lib/dynflow/utils.rb +1 -1
- data/lib/dynflow/version.rb +2 -1
- data/lib/dynflow/watchers/memory_consumption_watcher.rb +1 -1
- data/lib/dynflow/web/console.rb +1 -3
- data/lib/dynflow/web/console_helpers.rb +5 -4
- data/lib/dynflow/web/filtering_helpers.rb +1 -0
- data/lib/dynflow/web/world_helpers.rb +1 -0
- data/lib/dynflow/web.rb +3 -3
- data/lib/dynflow/web_console.rb +1 -0
- data/lib/dynflow/world/invalidation.rb +9 -1
- data/lib/dynflow/world.rb +20 -20
- data/lib/dynflow.rb +3 -6
- data/test/abnormal_states_recovery_test.rb +4 -8
- data/test/action_test.rb +10 -18
- data/test/activejob_adapter_test.rb +2 -2
- data/test/batch_sub_tasks_test.rb +1 -1
- data/test/clock_test.rb +2 -3
- data/test/concurrency_control_test.rb +6 -7
- data/test/coordinator_test.rb +1 -0
- data/test/daemon_test.rb +3 -2
- data/test/dead_letter_silencer_test.rb +2 -1
- data/test/dispatcher_test.rb +4 -5
- data/test/execution_plan_cleaner_test.rb +1 -0
- data/test/execution_plan_hooks_test.rb +1 -0
- data/test/execution_plan_test.rb +10 -32
- data/test/executor_test.rb +20 -37
- data/test/extensions_test.rb +1 -0
- data/test/flows_test.rb +2 -2
- data/test/future_execution_test.rb +2 -3
- data/test/memory_cosumption_watcher_test.rb +1 -0
- data/test/middleware_test.rb +4 -6
- data/test/persistence_test.rb +26 -26
- data/test/redis_locking_test.rb +1 -0
- data/test/rescue_test.rb +3 -11
- data/test/round_robin_test.rb +1 -0
- data/test/semaphores_test.rb +5 -7
- data/test/support/code_workflow_example.rb +11 -28
- data/test/support/dummy_example.rb +20 -19
- data/test/support/middleware_example.rb +2 -8
- data/test/support/rescue_example.rb +1 -14
- data/test/support/test_execution_log.rb +1 -2
- data/test/test_helper.rb +3 -7
- data/test/testing_test.rb +6 -8
- data/test/utils_test.rb +1 -0
- data/test/v2_sub_plans_test.rb +1 -0
- data/test/web_console_test.rb +4 -4
- data/test/world_test.rb +4 -3
- metadata +43 -43
data/test/redis_locking_test.rb
CHANGED
data/test/rescue_test.rb
CHANGED
@@ -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 RescueTest
|
6
7
|
describe 'on error' do
|
7
|
-
|
8
8
|
Example = Support::RescueExample
|
9
9
|
|
10
10
|
let(:world) { WorldFactory.create_world }
|
@@ -21,7 +21,6 @@ module Dynflow
|
|
21
21
|
|
22
22
|
describe 'no auto rescue' do
|
23
23
|
describe 'of simple skippable action in run phase' do
|
24
|
-
|
25
24
|
let :execution_plan do
|
26
25
|
execute(Example::ActionWithSkip, 1, :error_on_run)
|
27
26
|
end
|
@@ -36,7 +35,6 @@ module Dynflow
|
|
36
35
|
end
|
37
36
|
|
38
37
|
describe 'of simple skippable action in finalize phase' do
|
39
|
-
|
40
38
|
let :execution_plan do
|
41
39
|
execute(Example::ActionWithSkip, 1, :error_on_finalize)
|
42
40
|
end
|
@@ -51,7 +49,6 @@ module Dynflow
|
|
51
49
|
end
|
52
50
|
|
53
51
|
describe 'of complex action with skips in run phase' do
|
54
|
-
|
55
52
|
let :execution_plan do
|
56
53
|
execute(Example::ComplexActionWithSkip, :error_on_run)
|
57
54
|
end
|
@@ -66,7 +63,6 @@ module Dynflow
|
|
66
63
|
end
|
67
64
|
|
68
65
|
describe 'of complex action with skips in finalize phase' do
|
69
|
-
|
70
66
|
let :execution_plan do
|
71
67
|
execute(Example::ComplexActionWithSkip, :error_on_finalize)
|
72
68
|
end
|
@@ -81,7 +77,6 @@ module Dynflow
|
|
81
77
|
end
|
82
78
|
|
83
79
|
describe 'of complex action without skips' do
|
84
|
-
|
85
80
|
let :execution_plan do
|
86
81
|
execute(Example::ComplexActionWithoutSkip, :error_on_run)
|
87
82
|
end
|
@@ -96,7 +91,6 @@ module Dynflow
|
|
96
91
|
end
|
97
92
|
|
98
93
|
describe 'of complex action with fail' do
|
99
|
-
|
100
94
|
let :execution_plan do
|
101
95
|
execute(Example::ComplexActionWithFail, :error_on_run)
|
102
96
|
end
|
@@ -112,7 +106,6 @@ module Dynflow
|
|
112
106
|
end
|
113
107
|
|
114
108
|
describe 'auto rescue' do
|
115
|
-
|
116
109
|
let(:world) do
|
117
110
|
WorldFactory.create_world do |config|
|
118
111
|
config.auto_rescue = true
|
@@ -127,8 +120,8 @@ module Dynflow
|
|
127
120
|
it 'skips the action and continues' do
|
128
121
|
_(rescued_plan.state).must_equal :stopped
|
129
122
|
_(rescued_plan.result).must_equal :warning
|
130
|
-
_(rescued_plan.entry_action.output[:message])
|
131
|
-
must_equal "skipped because some error as you wish"
|
123
|
+
_(rescued_plan.entry_action.output[:message])
|
124
|
+
.must_equal "skipped because some error as you wish"
|
132
125
|
end
|
133
126
|
end
|
134
127
|
|
@@ -215,7 +208,6 @@ module Dynflow
|
|
215
208
|
_(execution_plan.execution_history.map { |h| [h.name, h.world_id] }).must_equal(expected_history)
|
216
209
|
end
|
217
210
|
end
|
218
|
-
|
219
211
|
end
|
220
212
|
end
|
221
213
|
end
|
data/test/round_robin_test.rb
CHANGED
data/test/semaphores_test.rb
CHANGED
@@ -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 SemaphoresTest
|
6
7
|
describe ::Dynflow::Semaphores::Stateful do
|
7
|
-
|
8
8
|
let(:semaphore_class) { ::Dynflow::Semaphores::Stateful }
|
9
9
|
let(:tickets_count) { 5 }
|
10
10
|
|
@@ -41,7 +41,6 @@ module Dynflow
|
|
41
41
|
waiting = semaphore.get_waiting
|
42
42
|
_(waiting).must_equal 3
|
43
43
|
end
|
44
|
-
|
45
44
|
end
|
46
45
|
|
47
46
|
describe ::Dynflow::Semaphores::Dummy do
|
@@ -71,10 +70,10 @@ module Dynflow
|
|
71
70
|
}
|
72
71
|
end
|
73
72
|
|
74
|
-
def assert_semaphore_state(semaphore,
|
75
|
-
_(semaphore.children[:child_A].free).must_equal
|
76
|
-
_(semaphore.children[:child_B].free).must_equal
|
77
|
-
_(semaphore.free).must_equal [
|
73
|
+
def assert_semaphore_state(semaphore, state_a, state_b)
|
74
|
+
_(semaphore.children[:child_A].free).must_equal state_a
|
75
|
+
_(semaphore.children[:child_B].free).must_equal state_b
|
76
|
+
_(semaphore.free).must_equal [state_a, state_b].min
|
78
77
|
end
|
79
78
|
|
80
79
|
it 'can be used as counter' do
|
@@ -94,6 +93,5 @@ module Dynflow
|
|
94
93
|
assert_semaphore_state semaphore, 0, 0
|
95
94
|
end
|
96
95
|
end
|
97
|
-
|
98
96
|
end
|
99
97
|
end
|
@@ -1,11 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require 'logger'
|
3
4
|
|
4
5
|
module Support
|
5
6
|
module CodeWorkflowExample
|
6
|
-
|
7
7
|
class IncomingIssues < Dynflow::Action
|
8
|
-
|
9
8
|
def plan(issues)
|
10
9
|
issues.each do |issue|
|
11
10
|
plan_action(IncomingIssue, issue)
|
@@ -36,7 +35,6 @@ module Support
|
|
36
35
|
end
|
37
36
|
|
38
37
|
class IncomingIssue < Dynflow::Action
|
39
|
-
|
40
38
|
def plan(issue)
|
41
39
|
raise "You want me to fail" if issue == :fail
|
42
40
|
plan_self(issue)
|
@@ -47,18 +45,16 @@ module Support
|
|
47
45
|
param :author, String
|
48
46
|
param :text, String
|
49
47
|
end
|
50
|
-
|
51
48
|
end
|
52
49
|
|
53
50
|
class Triage < Dynflow::Action
|
54
|
-
|
55
51
|
def plan(issue)
|
56
52
|
triage = plan_self(issue)
|
57
53
|
plan_action(UpdateIssue,
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
54
|
+
author: triage.input[:author],
|
55
|
+
text: triage.input[:text],
|
56
|
+
assignee: triage.output[:classification][:assignee],
|
57
|
+
severity: triage.output[:classification][:severity])
|
62
58
|
end
|
63
59
|
|
64
60
|
input_format do
|
@@ -84,11 +80,9 @@ module Support
|
|
84
80
|
error! 'Trolling detected' if input[:text] == "trolling in finalize"
|
85
81
|
TestExecutionLog.finalize << self
|
86
82
|
end
|
87
|
-
|
88
83
|
end
|
89
84
|
|
90
85
|
class UpdateIssue < Dynflow::Action
|
91
|
-
|
92
86
|
input_format do
|
93
87
|
param :author, String
|
94
88
|
param :text, String
|
@@ -101,7 +95,6 @@ module Support
|
|
101
95
|
end
|
102
96
|
|
103
97
|
class NotifyAssignee < Dynflow::Action
|
104
|
-
|
105
98
|
def self.subscribe
|
106
99
|
Triage
|
107
100
|
end
|
@@ -137,15 +130,14 @@ module Support
|
|
137
130
|
end
|
138
131
|
|
139
132
|
plan_action(Merge,
|
140
|
-
|
141
|
-
|
142
|
-
|
133
|
+
commit: commit,
|
134
|
+
ci_result: ci.output[:passed],
|
135
|
+
review_results: review_actions.map { |ra| ra.output[:passed] })
|
143
136
|
end
|
144
137
|
end
|
145
138
|
end
|
146
139
|
|
147
140
|
class FastCommit < Dynflow::Action
|
148
|
-
|
149
141
|
def plan(commit)
|
150
142
|
sequence do
|
151
143
|
ci, review = concurrence do
|
@@ -154,20 +146,18 @@ module Support
|
|
154
146
|
end
|
155
147
|
|
156
148
|
plan_action(Merge,
|
157
|
-
|
158
|
-
|
159
|
-
|
149
|
+
commit: commit,
|
150
|
+
ci_result: ci.output[:passed],
|
151
|
+
review_results: [review.output[:passed]])
|
160
152
|
end
|
161
153
|
end
|
162
154
|
|
163
155
|
input_format do
|
164
156
|
param :sha, String
|
165
157
|
end
|
166
|
-
|
167
158
|
end
|
168
159
|
|
169
160
|
class Ci < Dynflow::Action
|
170
|
-
|
171
161
|
input_format do
|
172
162
|
param :commit, Commit.input_format
|
173
163
|
end
|
@@ -182,7 +172,6 @@ module Support
|
|
182
172
|
end
|
183
173
|
|
184
174
|
class Review < Dynflow::Action
|
185
|
-
|
186
175
|
input_format do
|
187
176
|
param :reviewer, String
|
188
177
|
param :commit, Commit.input_format
|
@@ -202,7 +191,6 @@ module Support
|
|
202
191
|
end
|
203
192
|
|
204
193
|
class Merge < Dynflow::Action
|
205
|
-
|
206
194
|
input_format do
|
207
195
|
param :commit, Commit.input_format
|
208
196
|
param :ci_result, Ci.output_format
|
@@ -233,25 +221,21 @@ module Support
|
|
233
221
|
end
|
234
222
|
|
235
223
|
class DummySubscribe < Dynflow::Action
|
236
|
-
|
237
224
|
def self.subscribe
|
238
225
|
DummyTrigger
|
239
226
|
end
|
240
227
|
|
241
228
|
def run
|
242
229
|
end
|
243
|
-
|
244
230
|
end
|
245
231
|
|
246
232
|
class DummyMultiSubscribe < Dynflow::Action
|
247
|
-
|
248
233
|
def self.subscribe
|
249
234
|
[DummyTrigger, DummyAnotherTrigger]
|
250
235
|
end
|
251
236
|
|
252
237
|
def run
|
253
238
|
end
|
254
|
-
|
255
239
|
end
|
256
240
|
|
257
241
|
class CancelableSuspended < Dynflow::Action
|
@@ -301,6 +285,5 @@ module Support
|
|
301
285
|
external_task && external_task[:progress].to_f / 100
|
302
286
|
end
|
303
287
|
end
|
304
|
-
|
305
288
|
end
|
306
289
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require 'logger'
|
3
4
|
|
4
5
|
module Support
|
@@ -24,6 +25,7 @@ module Support
|
|
24
25
|
def delay(delay_options, *args)
|
25
26
|
MySerializer.new(args)
|
26
27
|
end
|
28
|
+
|
27
29
|
def run; end
|
28
30
|
end
|
29
31
|
|
@@ -43,7 +45,7 @@ module Support
|
|
43
45
|
sleep input[:interval]
|
44
46
|
action_logger.debug 'done with sleeping'
|
45
47
|
$slow_actions_done ||= 0
|
46
|
-
$slow_actions_done +=1
|
48
|
+
$slow_actions_done += 1
|
47
49
|
end
|
48
50
|
|
49
51
|
def queue
|
@@ -87,7 +89,6 @@ module Support
|
|
87
89
|
end
|
88
90
|
|
89
91
|
class WeightedPolling < Dynflow::Action
|
90
|
-
|
91
92
|
def plan(input)
|
92
93
|
sequence do
|
93
94
|
plan_self(input)
|
@@ -148,23 +149,23 @@ module Support
|
|
148
149
|
class ComposedAction < Dynflow::Action
|
149
150
|
def run(event = nil)
|
150
151
|
match event,
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
152
|
+
(on nil do
|
153
|
+
sub_plan = world.trigger(Dummy)
|
154
|
+
output[:sub_plan_id] = sub_plan.id
|
155
|
+
suspend do |suspended_action|
|
156
|
+
if input[:timeout]
|
157
|
+
world.clock.ping suspended_action, input[:timeout], "timeout"
|
158
|
+
end
|
159
|
+
|
160
|
+
sub_plan.finished.on_fulfillment! { suspended_action << 'finish' }
|
161
|
+
end
|
162
|
+
end),
|
163
|
+
(on 'finish' do
|
164
|
+
output[:event] = 'finish'
|
165
|
+
end),
|
166
|
+
(on 'timeout' do
|
167
|
+
output[:event] = 'timeout'
|
168
|
+
end)
|
168
169
|
end
|
169
170
|
end
|
170
171
|
end
|
@@ -1,8 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module Support
|
3
4
|
module MiddlewareExample
|
4
5
|
class LogMiddleware < Dynflow::Middleware
|
5
|
-
|
6
6
|
def self.log
|
7
7
|
@log
|
8
8
|
end
|
@@ -17,7 +17,7 @@ module Support
|
|
17
17
|
|
18
18
|
def delay(*args)
|
19
19
|
log 'before_delay'
|
20
|
-
pass
|
20
|
+
pass(*args)
|
21
21
|
log 'after_delay'
|
22
22
|
end
|
23
23
|
|
@@ -51,11 +51,9 @@ module Support
|
|
51
51
|
pass
|
52
52
|
log 'after_finalize_phase'
|
53
53
|
end
|
54
|
-
|
55
54
|
end
|
56
55
|
|
57
56
|
class LogRunMiddleware < Dynflow::Middleware
|
58
|
-
|
59
57
|
def log(message)
|
60
58
|
LogMiddleware.log << "#{self.class.name[/\w+$/]}::#{message}"
|
61
59
|
end
|
@@ -105,7 +103,6 @@ module Support
|
|
105
103
|
end
|
106
104
|
|
107
105
|
class LoggingAction < Dynflow::Action
|
108
|
-
|
109
106
|
middleware.use LogMiddleware
|
110
107
|
|
111
108
|
def log(message)
|
@@ -132,7 +129,6 @@ module Support
|
|
132
129
|
end
|
133
130
|
|
134
131
|
class ObservingMiddleware < Dynflow::Middleware
|
135
|
-
|
136
132
|
def log(message)
|
137
133
|
LogMiddleware.log << message
|
138
134
|
end
|
@@ -146,7 +142,6 @@ module Support
|
|
146
142
|
end
|
147
143
|
|
148
144
|
class AnotherObservingMiddleware < ObservingMiddleware
|
149
|
-
|
150
145
|
def delay(*args)
|
151
146
|
pass(*args).tap do
|
152
147
|
log("delay#set-input:#{action.world.id}")
|
@@ -158,7 +153,6 @@ module Support
|
|
158
153
|
log("plan#input:#{action.input[:message]}")
|
159
154
|
pass(*args)
|
160
155
|
end
|
161
|
-
|
162
156
|
end
|
163
157
|
|
164
158
|
class Action < Dynflow::Action
|
@@ -1,11 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require 'logger'
|
3
4
|
|
4
5
|
module Support
|
5
6
|
module RescueExample
|
6
|
-
|
7
7
|
class ComplexActionWithSkip < Dynflow::Action
|
8
|
-
|
9
8
|
def plan(error_state)
|
10
9
|
sequence do
|
11
10
|
concurrence do
|
@@ -20,20 +19,16 @@ module Support
|
|
20
19
|
def rescue_strategy_for_self
|
21
20
|
Dynflow::Action::Rescue::Skip
|
22
21
|
end
|
23
|
-
|
24
22
|
end
|
25
23
|
|
26
24
|
class ComplexActionWithoutSkip < ComplexActionWithSkip
|
27
|
-
|
28
25
|
def rescue_strategy_for_planned_action(action)
|
29
26
|
# enforce pause even when error on skipable action
|
30
27
|
Dynflow::Action::Rescue::Pause
|
31
28
|
end
|
32
|
-
|
33
29
|
end
|
34
30
|
|
35
31
|
class AbstractAction < Dynflow::Action
|
36
|
-
|
37
32
|
def plan(identifier, desired_state)
|
38
33
|
plan_self(identifier: identifier, desired_state: desired_state)
|
39
34
|
end
|
@@ -57,11 +52,9 @@ module Support
|
|
57
52
|
raise 'some error as you wish'
|
58
53
|
end
|
59
54
|
end
|
60
|
-
|
61
55
|
end
|
62
56
|
|
63
57
|
class ActionWithSkip < AbstractAction
|
64
|
-
|
65
58
|
def run(event = nil)
|
66
59
|
if event === Dynflow::Action::Skip
|
67
60
|
output[:message] = "skipped because #{self.error.message}"
|
@@ -74,19 +67,15 @@ module Support
|
|
74
67
|
def rescue_strategy_for_self
|
75
68
|
Dynflow::Action::Rescue::Skip
|
76
69
|
end
|
77
|
-
|
78
70
|
end
|
79
71
|
|
80
72
|
class ActionWithFail < AbstractAction
|
81
|
-
|
82
73
|
def rescue_strategy_for_self
|
83
74
|
Dynflow::Action::Rescue::Fail
|
84
75
|
end
|
85
|
-
|
86
76
|
end
|
87
77
|
|
88
78
|
class ComplexActionWithFail < ActionWithFail
|
89
|
-
|
90
79
|
def plan(error_state)
|
91
80
|
sequence do
|
92
81
|
concurrence do
|
@@ -97,8 +86,6 @@ module Support
|
|
97
86
|
plan_action(ActionWithSkip, 6, :success)
|
98
87
|
end
|
99
88
|
end
|
100
|
-
|
101
89
|
end
|
102
|
-
|
103
90
|
end
|
104
91
|
end
|
data/test/test_helper.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require 'bundler/setup'
|
3
4
|
require 'minitest/reporters'
|
4
5
|
require 'minitest/autorun'
|
@@ -13,7 +14,6 @@ $LOAD_PATH << load_path unless $LOAD_PATH.include? load_path
|
|
13
14
|
require 'dynflow'
|
14
15
|
require 'dynflow/testing'
|
15
16
|
begin require 'pry'; rescue LoadError; nil end
|
16
|
-
|
17
17
|
require 'support/code_workflow_example'
|
18
18
|
require 'support/middleware_example'
|
19
19
|
require 'support/rescue_example'
|
@@ -24,7 +24,6 @@ Concurrent.disable_at_exit_handlers!
|
|
24
24
|
|
25
25
|
# To be able to stop a process in some step and perform assertions while paused
|
26
26
|
class TestPause
|
27
|
-
|
28
27
|
def self.setup
|
29
28
|
@pause = Concurrent::Promises.resolvable_future
|
30
29
|
@ready = Concurrent::Promises.resolvable_future
|
@@ -78,7 +77,6 @@ class CoordiationAdapterWithLog < Dynflow::CoordinatorAdapters::Sequel
|
|
78
77
|
end
|
79
78
|
|
80
79
|
module WorldFactory
|
81
|
-
|
82
80
|
def self.created_worlds
|
83
81
|
@created_worlds ||= []
|
84
82
|
end
|
@@ -129,7 +127,7 @@ module WorldFactory
|
|
129
127
|
def self.clean_coordinator_records
|
130
128
|
persistence_adapter = WorldFactory.persistence_adapter
|
131
129
|
persistence_adapter.find_coordinator_records({}).each do |w|
|
132
|
-
warn "Unexpected coordinator record: #{
|
130
|
+
warn "Unexpected coordinator record: #{w}"
|
133
131
|
persistence_adapter.delete_coordinator_record(w[:class], w[:id])
|
134
132
|
end
|
135
133
|
end
|
@@ -230,7 +228,7 @@ module TestHelpers
|
|
230
228
|
'terminate execution',
|
231
229
|
'start execution',
|
232
230
|
'finish execution'],
|
233
|
-
|
231
|
+
plan.execution_history.map(&:name)
|
234
232
|
refute_equal plan.execution_history.first.world_id, plan.execution_history.to_a.last.world_id
|
235
233
|
end
|
236
234
|
end
|
@@ -302,7 +300,6 @@ events_test = -> do
|
|
302
300
|
wait_method.bind(self).call(timeout || default_timeout)
|
303
301
|
end
|
304
302
|
end
|
305
|
-
|
306
303
|
end
|
307
304
|
|
308
305
|
events_test.call
|
@@ -331,7 +328,6 @@ class ConcurrentRunTester
|
|
331
328
|
end
|
332
329
|
|
333
330
|
module PlanAssertions
|
334
|
-
|
335
331
|
def inspect_flow(execution_plan, flow)
|
336
332
|
out = "".dup
|
337
333
|
inspect_subflow(out, execution_plan, flow, "".dup)
|
data/test/testing_test.rb
CHANGED
@@ -1,15 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require_relative 'test_helper'
|
3
4
|
|
4
5
|
module Dynflow
|
5
|
-
|
6
6
|
CWE = Support::CodeWorkflowExample
|
7
7
|
|
8
8
|
describe Testing do
|
9
9
|
include Testing
|
10
10
|
|
11
11
|
describe 'testing' do
|
12
|
-
|
13
12
|
specify '#plan_action' do
|
14
13
|
input = { 'input' => 'input' }
|
15
14
|
action = create_and_plan_action Support::DummyExample::WeightedPolling, input
|
@@ -63,20 +62,20 @@ module Dynflow
|
|
63
62
|
_(action.run_progress).must_equal 0
|
64
63
|
|
65
64
|
3.times { progress_action_time action }
|
66
|
-
_(action.output).must_equal('task' => { 'progress' => 30, 'done' => false }
|
67
|
-
'poll_attempts' => {'total' => 2, 'failed'=> 0 })
|
65
|
+
_(action.output).must_equal('task' => { 'progress' => 30, 'done' => false },
|
66
|
+
'poll_attempts' => { 'total' => 2, 'failed' => 0 })
|
68
67
|
_(action.run_progress).must_equal 0.3
|
69
68
|
|
70
69
|
run_action action, Dynflow::Action::Polling::Poll
|
71
70
|
run_action action, Dynflow::Action::Polling::Poll
|
72
71
|
_(action.output).must_equal('task' => { 'progress' => 50, 'done' => false },
|
73
|
-
'poll_attempts' => {'total' => 4, 'failed' => 0 })
|
72
|
+
'poll_attempts' => { 'total' => 4, 'failed' => 0 })
|
74
73
|
_(action.run_progress).must_equal 0.5
|
75
74
|
|
76
75
|
5.times { progress_action_time action }
|
77
76
|
|
78
77
|
_(action.output).must_equal('task' => { 'progress' => 100, 'done' => true },
|
79
|
-
'poll_attempts' => {'total' => 9, 'failed' => 0 })
|
78
|
+
'poll_attempts' => { 'total' => 9, 'failed' => 0 })
|
80
79
|
_(action.run_progress).must_equal 1
|
81
80
|
end
|
82
81
|
|
@@ -100,7 +99,6 @@ module Dynflow
|
|
100
99
|
end
|
101
100
|
|
102
101
|
describe 'testing examples' do
|
103
|
-
|
104
102
|
describe CWE::Commit do
|
105
103
|
it 'plans' do
|
106
104
|
action = create_and_plan_action CWE::Commit, sha = 'commit-sha'
|
@@ -125,7 +123,7 @@ module Dynflow
|
|
125
123
|
|
126
124
|
it 'plans' do
|
127
125
|
_(planned_action.input).must_equal Utils.stringify_keys(input)
|
128
|
-
assert_run_phase planned_action, { commit: "sha", reviewer: "name", result: true}
|
126
|
+
assert_run_phase planned_action, { commit: "sha", reviewer: "name", result: true }
|
129
127
|
refute_finalize_phase planned_action
|
130
128
|
|
131
129
|
_(planned_action.execution_plan.planned_plan_steps).must_be_empty
|
data/test/utils_test.rb
CHANGED
data/test/v2_sub_plans_test.rb
CHANGED
data/test/web_console_test.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require_relative 'test_helper'
|
3
4
|
|
4
5
|
ENV['RACK_ENV'] = 'test'
|
@@ -8,14 +9,13 @@ require 'rack/test'
|
|
8
9
|
|
9
10
|
module Dynflow
|
10
11
|
describe 'web console' do
|
11
|
-
|
12
12
|
include Rack::Test::Methods
|
13
13
|
let(:world) { WorldFactory.create_world }
|
14
14
|
|
15
15
|
let :execution_plan_id do
|
16
|
-
world.trigger(Support::CodeWorkflowExample::FastCommit, 'sha' => 'abc123')
|
17
|
-
|
18
|
-
|
16
|
+
world.trigger(Support::CodeWorkflowExample::FastCommit, 'sha' => 'abc123')
|
17
|
+
.tap { |o| o.finished.wait }
|
18
|
+
.id
|
19
19
|
end
|
20
20
|
|
21
21
|
let :app do
|