dynflow 1.8.2 → 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.
- 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
|