dynflow 1.8.2 → 1.8.3
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 +2 -6
- 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 +1 -0
- data/lib/dynflow/world.rb +19 -19
- data/lib/dynflow.rb +2 -5
- 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/executor_test.rb
CHANGED
@@ -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.
|
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
|
-
|
234
|
-
|
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
|
-
|
314
|
-
|
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
|
-
|
329
|
-
|
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
|
-
|
345
|
-
|
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
|
-
|
442
|
-
|
433
|
+
{ "issues" => [{ "author" => "Peter Smith", "text" => "Failing test" },
|
434
|
+
{ "author" => "John Doe", "text" => "Internal server error" }] })
|
443
435
|
assert_finalized(Support::CodeWorkflowExample::Triage,
|
444
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
data/test/extensions_test.rb
CHANGED
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
|
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
|
data/test/middleware_test.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
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
|
-
|
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
|
data/test/persistence_test.rb
CHANGED
@@ -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
|
-
|
154
|
-
|
155
|
-
|
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
|
-
|
233
|
-
|
234
|
-
|
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
|
|
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
|