dynflow 1.4.8 → 1.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/{test/prepare_travis_env.sh → .github/install_dependencies.sh} +2 -2
  3. data/.github/workflows/ruby.yml +116 -0
  4. data/dynflow.gemspec +1 -0
  5. data/examples/chunked_output_benchmark.rb +77 -0
  6. data/extras/expand/main.go +180 -0
  7. data/lib/dynflow/action/suspended.rb +4 -4
  8. data/lib/dynflow/action/timeouts.rb +2 -2
  9. data/lib/dynflow/action.rb +15 -4
  10. data/lib/dynflow/clock.rb +2 -2
  11. data/lib/dynflow/delayed_executors/abstract_core.rb +11 -9
  12. data/lib/dynflow/director.rb +42 -5
  13. data/lib/dynflow/dispatcher/client_dispatcher.rb +8 -2
  14. data/lib/dynflow/dispatcher/executor_dispatcher.rb +12 -2
  15. data/lib/dynflow/dispatcher.rb +7 -2
  16. data/lib/dynflow/execution_history.rb +1 -1
  17. data/lib/dynflow/execution_plan/hooks.rb +1 -1
  18. data/lib/dynflow/execution_plan/steps/abstract_flow_step.rb +1 -0
  19. data/lib/dynflow/execution_plan.rb +16 -5
  20. data/lib/dynflow/executors/abstract/core.rb +10 -1
  21. data/lib/dynflow/executors/parallel.rb +6 -2
  22. data/lib/dynflow/extensions/msgpack.rb +41 -0
  23. data/lib/dynflow/extensions.rb +6 -0
  24. data/lib/dynflow/flows/abstract.rb +14 -0
  25. data/lib/dynflow/flows/abstract_composed.rb +2 -7
  26. data/lib/dynflow/flows/atom.rb +2 -2
  27. data/lib/dynflow/flows/concurrence.rb +2 -0
  28. data/lib/dynflow/flows/registry.rb +32 -0
  29. data/lib/dynflow/flows/sequence.rb +2 -0
  30. data/lib/dynflow/flows.rb +1 -0
  31. data/lib/dynflow/persistence.rb +10 -0
  32. data/lib/dynflow/persistence_adapters/sequel.rb +51 -16
  33. data/lib/dynflow/persistence_adapters/sequel_migrations/021_create_output_chunks.rb +30 -0
  34. data/lib/dynflow/persistence_adapters/sequel_migrations/022_store_flows_as_msgpack.rb +90 -0
  35. data/lib/dynflow/persistence_adapters/sequel_migrations/023_sqlite_workarounds.rb +19 -0
  36. data/lib/dynflow/serializable.rb +2 -2
  37. data/lib/dynflow/testing/dummy_coordinator.rb +10 -0
  38. data/lib/dynflow/testing/dummy_planned_action.rb +4 -0
  39. data/lib/dynflow/testing/dummy_world.rb +2 -1
  40. data/lib/dynflow/testing/in_thread_executor.rb +2 -2
  41. data/lib/dynflow/testing/in_thread_world.rb +5 -5
  42. data/lib/dynflow/testing.rb +1 -0
  43. data/lib/dynflow/version.rb +1 -1
  44. data/lib/dynflow/world.rb +16 -4
  45. data/lib/dynflow.rb +2 -1
  46. data/test/dispatcher_test.rb +6 -0
  47. data/test/execution_plan_hooks_test.rb +36 -0
  48. data/test/extensions_test.rb +42 -0
  49. data/test/flows_test.rb +44 -0
  50. data/test/future_execution_test.rb +6 -3
  51. data/test/persistence_test.rb +2 -2
  52. data/web/views/flow_step.erb +1 -0
  53. metadata +37 -5
  54. data/.travis.yml +0 -33
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+ tables = [:dynflow_actions, :dynflow_delayed_plans, :dynflow_steps, :dynflow_output_chunks]
3
+ Sequel.migration do
4
+ up do
5
+ if database_type == :sqlite && Gem::Version.new(SQLite3::SQLITE_VERSION) <= Gem::Version.new('3.7.17')
6
+ tables.each do |table|
7
+ alter_table(table) { drop_foreign_key [:execution_plan_uuid] }
8
+ end
9
+ end
10
+ end
11
+
12
+ down do
13
+ if database_type == :sqlite && Gem::Version.new(SQLite3::SQLITE_VERSION) <= Gem::Version.new('3.7.17')
14
+ tables.each do |table|
15
+ alter_table(table) { add_foreign_key [:execution_plan_uuid], :dynflow_execution_plans }
16
+ end
17
+ end
18
+ end
19
+ end
@@ -45,12 +45,12 @@ module Dynflow
45
45
  if values.size == 1
46
46
  value = values.first
47
47
  case value
48
- when String, Numeric, Symbol, TrueClass, FalseClass, NilClass, Time
49
- value
50
48
  when Hash
51
49
  value.inject({}) { |h, (k, v)| h.update k => recursive_to_hash(v) }
52
50
  when Array
53
51
  value.map { |v| recursive_to_hash v }
52
+ when ->(v) { v.respond_to?(:to_msgpack) }
53
+ value
54
54
  else
55
55
  value.to_hash
56
56
  end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+ module Dynflow
3
+ module Testing
4
+ class DummyCoordinator
5
+ def find_records(*args)
6
+ []
7
+ end
8
+ end
9
+ end
10
+ end
@@ -15,6 +15,10 @@ module Dynflow
15
15
  @plan_input = args
16
16
  self
17
17
  end
18
+
19
+ def run_step_id
20
+ @run_step_id ||= Testing.get_id
21
+ end
18
22
  end
19
23
  end
20
24
  end
@@ -5,7 +5,7 @@ module Dynflow
5
5
  extend Mimic
6
6
  mimic! World
7
7
 
8
- attr_reader :clock, :executor, :middleware
8
+ attr_reader :clock, :executor, :middleware, :coordinator
9
9
  attr_accessor :action
10
10
 
11
11
  def initialize(_config = nil)
@@ -13,6 +13,7 @@ module Dynflow
13
13
  @clock = ManagedClock.new
14
14
  @executor = DummyExecutor.new(self)
15
15
  @middleware = Middleware::World.new
16
+ @coordinator = DummyCoordinator.new
16
17
  end
17
18
 
18
19
  def action_logger
@@ -34,8 +34,8 @@ module Dynflow
34
34
  @director.work_finished(work_item)
35
35
  end
36
36
 
37
- def event(execution_plan_id, step_id, event, future = Concurrent::Promises.resolvable_future)
38
- event = (Director::Event[SecureRandom.uuid, execution_plan_id, step_id, event, future])
37
+ def event(execution_plan_id, step_id, event, future = Concurrent::Promises.resolvable_future, optional: false)
38
+ event = (Director::Event[SecureRandom.uuid, execution_plan_id, step_id, event, future, optional])
39
39
  @director.handle_event(event).each do |work_item|
40
40
  @work_items << work_item
41
41
  end
@@ -58,15 +58,15 @@ module Dynflow
58
58
  future.reject e
59
59
  end
60
60
 
61
- def event(execution_plan_id, step_id, event, done = Concurrent::Promises.resolvable_future)
62
- @executor.event(execution_plan_id, step_id, event, done)
61
+ def event(execution_plan_id, step_id, event, done = Concurrent::Promises.resolvable_future, optional: false)
62
+ @executor.event(execution_plan_id, step_id, event, done, optional: optional)
63
63
  end
64
64
 
65
- def plan_event(execution_plan_id, step_id, event, time, done = Concurrent::Promises.resolvable_future)
65
+ def plan_event(execution_plan_id, step_id, event, time, done = Concurrent::Promises.resolvable_future, optional: false)
66
66
  if time.nil? || time < Time.now
67
- event(execution_plan_id, step_id, event, done)
67
+ event(execution_plan_id, step_id, event, done, optional: optional)
68
68
  else
69
- clock.ping(executor, time, Director::Event[SecureRandom.uuid, execution_plan_id, step_id, event, done], :delayed_event)
69
+ clock.ping(executor, time, Director::Event[SecureRandom.uuid, execution_plan_id, step_id, event, done, optional], :delayed_event)
70
70
  end
71
71
  end
72
72
  end
@@ -19,6 +19,7 @@ module Dynflow
19
19
 
20
20
  require 'dynflow/testing/mimic'
21
21
  require 'dynflow/testing/managed_clock'
22
+ require 'dynflow/testing/dummy_coordinator'
22
23
  require 'dynflow/testing/dummy_world'
23
24
  require 'dynflow/testing/dummy_executor'
24
25
  require 'dynflow/testing/dummy_execution_plan'
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module Dynflow
3
- VERSION = '1.4.8'
3
+ VERSION = '1.6.2'
4
4
  end
data/lib/dynflow/world.rb CHANGED
@@ -200,6 +200,14 @@ module Dynflow
200
200
  Scheduled[execution_plan.id]
201
201
  end
202
202
 
203
+ def plan_elsewhere(action_class, *args)
204
+ execution_plan = ExecutionPlan.new(self, nil)
205
+ execution_plan.delay(nil, action_class, {}, *args)
206
+ plan_request(execution_plan.id)
207
+
208
+ Scheduled[execution_plan.id]
209
+ end
210
+
203
211
  def plan(action_class, *args)
204
212
  plan_with_options(action_class: action_class, args: args)
205
213
  end
@@ -219,12 +227,16 @@ module Dynflow
219
227
  publish_request(Dispatcher::Execution[execution_plan_id], done, true)
220
228
  end
221
229
 
222
- def event(execution_plan_id, step_id, event, done = Concurrent::Promises.resolvable_future)
223
- publish_request(Dispatcher::Event[execution_plan_id, step_id, event], done, false)
230
+ def event(execution_plan_id, step_id, event, done = Concurrent::Promises.resolvable_future, optional: false)
231
+ publish_request(Dispatcher::Event[execution_plan_id, step_id, event, nil, optional], done, false)
232
+ end
233
+
234
+ def plan_event(execution_plan_id, step_id, event, time, accepted = Concurrent::Promises.resolvable_future, optional: false)
235
+ publish_request(Dispatcher::Event[execution_plan_id, step_id, event, time, optional], accepted, false)
224
236
  end
225
237
 
226
- def plan_event(execution_plan_id, step_id, event, time, accepted = Concurrent::Promises.resolvable_future)
227
- publish_request(Dispatcher::Event[execution_plan_id, step_id, event, time], accepted, false)
238
+ def plan_request(execution_plan_id, done = Concurrent::Promises.resolvable_future)
239
+ publish_request(Dispatcher::Planning[execution_plan_id], done, false)
228
240
  end
229
241
 
230
242
  def ping(world_id, timeout, done = Concurrent::Promises.resolvable_future)
data/lib/dynflow.rb CHANGED
@@ -72,11 +72,12 @@ module Dynflow
72
72
  require 'dynflow/throttle_limiter'
73
73
  require 'dynflow/telemetry'
74
74
  require 'dynflow/config'
75
+ require 'dynflow/extensions'
75
76
 
76
77
  if defined? ::ActiveJob
77
78
  require 'dynflow/active_job/queue_adapter'
78
79
 
79
- class Railtie < Rails::Railtie
80
+ class Railtie < ::Rails::Railtie
80
81
  config.before_initialize do
81
82
  ::ActiveJob::QueueAdapters.send(
82
83
  :include,
@@ -49,6 +49,12 @@ module Dynflow
49
49
  plan = result.finished.value
50
50
  assert_equal('finish', plan.actions.first.output[:event])
51
51
  end
52
+
53
+ it 'does not error on dispatching an optional event' do
54
+ request = client_world.event('123', 1, nil, optional: true)
55
+ request.wait(20)
56
+ assert_match /Could not find an executor for optional .*, discarding/, request.reason.message
57
+ end
52
58
  end
53
59
  end
54
60
  end
@@ -60,6 +60,18 @@ module Dynflow
60
60
  execution_plan_hooks.use :raise_flag_root_only, :on => :stopped
61
61
  end
62
62
 
63
+ class PendingAction < ::Dynflow::Action
64
+ include FlagHook
65
+
66
+ execution_plan_hooks.use :raise_flag, :on => :pending
67
+ end
68
+
69
+ class AllTransitionsAction < ::Dynflow::Action
70
+ include FlagHook
71
+
72
+ execution_plan_hooks.use :raise_flag
73
+ end
74
+
63
75
  class ComposedAction < RootOnlyAction
64
76
  def plan
65
77
  plan_action(RootOnlyAction)
@@ -161,6 +173,30 @@ module Dynflow
161
173
  plan.finished.wait!
162
174
  _(Flag.raised_count).must_equal 1
163
175
  end
176
+
177
+ it 'runs the pending hooks when execution plan is created' do
178
+ refute Flag.raised?
179
+ plan = world.trigger(PendingAction)
180
+ plan.finished.wait!
181
+ _(Flag.raised_count).must_equal 1
182
+ end
183
+
184
+ it 'runs the pending hooks when execution plan is created' do
185
+ refute Flag.raised?
186
+ delay = world.delay(PendingAction, { :start_at => Time.now.utc + 180 })
187
+ delayed_plan = world.persistence.load_delayed_plan(delay.execution_plan_id)
188
+ delayed_plan.execution_plan.cancel.each(&:wait)
189
+ _(Flag.raised_count).must_equal 1
190
+ end
191
+
192
+ it 'runs the hook on every state transition' do
193
+ refute Flag.raised?
194
+ plan = world.trigger(AllTransitionsAction)
195
+ plan.finished.wait!
196
+ # There should be 5 transitions
197
+ # nothing -> pending -> planning -> planned -> running -> stopped
198
+ _(Flag.raised_count).must_equal 5
199
+ end
164
200
  end
165
201
  end
166
202
  end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+ require_relative 'test_helper'
3
+ require 'active_support/time'
4
+
5
+ module Dynflow
6
+ module ExtensionsTest
7
+ describe 'msgpack extensions' do
8
+ before do
9
+ Thread.current[:time_zone] = ActiveSupport::TimeZone['Europe/Prague']
10
+ end
11
+ after { Thread.current[:time_zone] = nil }
12
+
13
+ it 'allows {de,}serializing Time' do
14
+ time = Time.now
15
+ transformed = MessagePack.unpack(time.to_msgpack)
16
+ assert_equal transformed, time
17
+ assert_equal transformed.class, time.class
18
+ end
19
+
20
+ it 'allows {de,}serializing ActiveSupport::TimeWithZone' do
21
+ time = Time.zone.now
22
+ transformed = MessagePack.unpack(time.to_msgpack)
23
+ assert_equal transformed, time
24
+ assert_equal transformed.class, time.class
25
+ end
26
+
27
+ it 'allows {de,}serializing DateTime' do
28
+ time = DateTime.now
29
+ transformed = MessagePack.unpack(time.to_msgpack)
30
+ assert_equal transformed, time
31
+ assert_equal transformed.class, time.class
32
+ end
33
+
34
+ it 'allows {de,}serializing Date' do
35
+ date = DateTime.current
36
+ transformed = MessagePack.unpack(date.to_msgpack)
37
+ assert_equal transformed, date
38
+ assert_equal transformed.class, date.class
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+ require_relative 'test_helper'
3
+ require 'mocha/minitest'
4
+
5
+ module Dynflow
6
+ describe 'flow' do
7
+
8
+ class TestRegistry < Flows::Registry
9
+ class << self
10
+ def reset!
11
+ @serialization_map = {}
12
+ end
13
+ end
14
+ end
15
+
16
+ after do
17
+ TestRegistry.reset!
18
+ end
19
+
20
+ describe "registry" do
21
+ it "allows registering values" do
22
+ TestRegistry.register!(TestRegistry, 'TS')
23
+ TestRegistry.register!(Integer, 'I')
24
+ map = TestRegistry.instance_variable_get("@serialization_map")
25
+ _(map).must_equal({'TS' => TestRegistry, 'I' => Integer})
26
+ end
27
+
28
+ it "prevents overwriting values" do
29
+ TestRegistry.register!(Integer, 'I')
30
+ _(-> { TestRegistry.register!(Float, 'I') }).must_raise Flows::Registry::IdentifierTaken
31
+ end
32
+
33
+ it "encodes and decodes values" do
34
+ TestRegistry.register!(Integer, 'I')
35
+ _(TestRegistry.encode(Integer)).must_equal 'I'
36
+ end
37
+
38
+ it "raises an exception when unknown key is requested" do
39
+ _(-> { TestRegistry.encode(Float) }).must_raise Flows::Registry::UnknownIdentifier
40
+ _(-> { TestRegistry.decode('F') }).must_raise Flows::Registry::UnknownIdentifier
41
+ end
42
+ end
43
+ end
44
+ end
@@ -29,14 +29,17 @@ module Dynflow
29
29
  describe 'abstract executor' do
30
30
  let(:abstract_delayed_executor) { DelayedExecutors::AbstractCore.new(world) }
31
31
 
32
- it 'handles wrong plan state' do
32
+ it 'handles plan in planning state' do
33
33
  delayed_plan.execution_plan.state = :planning
34
34
  abstract_delayed_executor.send(:process, [delayed_plan], @start_at)
35
- _(delayed_plan.execution_plan.state).must_equal :planned
35
+ _(delayed_plan.execution_plan.state).must_equal :scheduled
36
+ end
36
37
 
38
+ it 'handles plan in running state' do
37
39
  delayed_plan.execution_plan.set_state(:running, true)
38
40
  abstract_delayed_executor.send(:process, [delayed_plan], @start_at)
39
41
  _(delayed_plan.execution_plan.state).must_equal :running
42
+ _(world.persistence.load_delayed_plan(delayed_plan.execution_plan_uuid)).must_be :nil?
40
43
  end
41
44
  end
42
45
 
@@ -55,7 +58,7 @@ module Dynflow
55
58
 
56
59
  it 'delays the action' do
57
60
  _(execution_plan.steps.count).must_equal 1
58
- _(delayed_plan.start_at.inspect).must_equal (@start_at).inspect
61
+ _(delayed_plan.start_at.to_i).must_equal(@start_at.to_i)
59
62
  _(history_names.call(execution_plan)).must_equal ['delay']
60
63
  end
61
64
 
@@ -86,7 +86,7 @@ module Dynflow
86
86
  original.each do |key, value|
87
87
  loaded_value = loaded[key.to_s]
88
88
  if value.is_a?(Time)
89
- _(loaded_value.inspect).must_equal value.inspect
89
+ _(loaded_value).must_be_within_delta(value, 0.5)
90
90
  elsif value.is_a?(Hash)
91
91
  assert_equal_attributes!(value, loaded_value)
92
92
  elsif value.nil?
@@ -348,7 +348,7 @@ module Dynflow
348
348
  if value.nil?
349
349
  assert_nil stored.fetch(name.to_sym)
350
350
  elsif value.is_a?(Time)
351
- _(stored.fetch(name.to_sym).inspect).must_equal value.inspect
351
+ _(stored.fetch(name.to_sym)).must_be_within_delta(value, 0.5)
352
352
  else
353
353
  _(stored.fetch(name.to_sym)).must_equal value
354
354
  end
@@ -31,6 +31,7 @@
31
31
  <% end %>
32
32
  <%= show_action_data("Input:", action.input) %>
33
33
  <%= show_action_data("Output:", action.output) %>
34
+ <%= show_action_data("Chunked output:", action.stored_output_chunks) %>
34
35
  <% if step.error %>
35
36
  <p>
36
37
  <b>Error:</b>
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dynflow
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.8
4
+ version: 1.6.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ivan Necas
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2021-05-13 00:00:00.000000000 Z
12
+ date: 2021-12-10 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: multi_json
@@ -25,6 +25,26 @@ dependencies:
25
25
  - - ">="
26
26
  - !ruby/object:Gem::Version
27
27
  version: '0'
28
+ - !ruby/object:Gem::Dependency
29
+ name: msgpack
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - "~>"
33
+ - !ruby/object:Gem::Version
34
+ version: '1.3'
35
+ - - ">="
36
+ - !ruby/object:Gem::Version
37
+ version: 1.3.3
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - "~>"
43
+ - !ruby/object:Gem::Version
44
+ version: '1.3'
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: 1.3.3
28
48
  - !ruby/object:Gem::Dependency
29
49
  name: apipie-params
30
50
  requirement: !ruby/object:Gem::Requirement
@@ -242,10 +262,11 @@ executables: []
242
262
  extensions: []
243
263
  extra_rdoc_files: []
244
264
  files:
265
+ - ".github/install_dependencies.sh"
266
+ - ".github/workflows/ruby.yml"
245
267
  - ".gitignore"
246
268
  - ".rubocop.yml"
247
269
  - ".rubocop_todo.yml"
248
- - ".travis.yml"
249
270
  - Dockerfile
250
271
  - Gemfile
251
272
  - MIT-LICENSE
@@ -386,6 +407,7 @@ files:
386
407
  - doc/pages/source/projects/index.md
387
408
  - docker-compose.yml
388
409
  - dynflow.gemspec
410
+ - examples/chunked_output_benchmark.rb
389
411
  - examples/clock_benchmark.rb
390
412
  - examples/example_helper.rb
391
413
  - examples/future_execution.rb
@@ -397,6 +419,7 @@ files:
397
419
  - examples/sub_plan_concurrency_control.rb
398
420
  - examples/sub_plans.rb
399
421
  - examples/termination.rb
422
+ - extras/expand/main.go
400
423
  - extras/statsd_mapping.conf
401
424
  - lib/dynflow.rb
402
425
  - lib/dynflow/action.rb
@@ -469,11 +492,14 @@ files:
469
492
  - lib/dynflow/executors/sidekiq/redis_locking.rb
470
493
  - lib/dynflow/executors/sidekiq/serialization.rb
471
494
  - lib/dynflow/executors/sidekiq/worker_jobs.rb
495
+ - lib/dynflow/extensions.rb
496
+ - lib/dynflow/extensions/msgpack.rb
472
497
  - lib/dynflow/flows.rb
473
498
  - lib/dynflow/flows/abstract.rb
474
499
  - lib/dynflow/flows/abstract_composed.rb
475
500
  - lib/dynflow/flows/atom.rb
476
501
  - lib/dynflow/flows/concurrence.rb
502
+ - lib/dynflow/flows/registry.rb
477
503
  - lib/dynflow/flows/sequence.rb
478
504
  - lib/dynflow/logger_adapters.rb
479
505
  - lib/dynflow/logger_adapters/abstract.rb
@@ -513,6 +539,9 @@ files:
513
539
  - lib/dynflow/persistence_adapters/sequel_migrations/018_add_uuid_column.rb
514
540
  - lib/dynflow/persistence_adapters/sequel_migrations/019_update_mysql_time_precision.rb
515
541
  - lib/dynflow/persistence_adapters/sequel_migrations/020_drop_duplicate_indices.rb
542
+ - lib/dynflow/persistence_adapters/sequel_migrations/021_create_output_chunks.rb
543
+ - lib/dynflow/persistence_adapters/sequel_migrations/022_store_flows_as_msgpack.rb
544
+ - lib/dynflow/persistence_adapters/sequel_migrations/023_sqlite_workarounds.rb
516
545
  - lib/dynflow/rails.rb
517
546
  - lib/dynflow/rails/configuration.rb
518
547
  - lib/dynflow/rails/daemon.rb
@@ -534,6 +563,7 @@ files:
534
563
  - lib/dynflow/telemetry_adapters/statsd.rb
535
564
  - lib/dynflow/testing.rb
536
565
  - lib/dynflow/testing/assertions.rb
566
+ - lib/dynflow/testing/dummy_coordinator.rb
537
567
  - lib/dynflow/testing/dummy_execution_plan.rb
538
568
  - lib/dynflow/testing/dummy_executor.rb
539
569
  - lib/dynflow/testing/dummy_planned_action.rb
@@ -576,11 +606,12 @@ files:
576
606
  - test/execution_plan_hooks_test.rb
577
607
  - test/execution_plan_test.rb
578
608
  - test/executor_test.rb
609
+ - test/extensions_test.rb
610
+ - test/flows_test.rb
579
611
  - test/future_execution_test.rb
580
612
  - test/memory_cosumption_watcher_test.rb
581
613
  - test/middleware_test.rb
582
614
  - test/persistence_test.rb
583
- - test/prepare_travis_env.sh
584
615
  - test/redis_locking_test.rb
585
616
  - test/rescue_test.rb
586
617
  - test/round_robin_test.rb
@@ -659,11 +690,12 @@ test_files:
659
690
  - test/execution_plan_hooks_test.rb
660
691
  - test/execution_plan_test.rb
661
692
  - test/executor_test.rb
693
+ - test/extensions_test.rb
694
+ - test/flows_test.rb
662
695
  - test/future_execution_test.rb
663
696
  - test/memory_cosumption_watcher_test.rb
664
697
  - test/middleware_test.rb
665
698
  - test/persistence_test.rb
666
- - test/prepare_travis_env.sh
667
699
  - test/redis_locking_test.rb
668
700
  - test/rescue_test.rb
669
701
  - test/round_robin_test.rb
data/.travis.yml DELETED
@@ -1,33 +0,0 @@
1
- language: ruby
2
-
3
- services:
4
- - postgresql
5
- - redis
6
-
7
- rvm:
8
- - "2.3.1"
9
- - "2.4.0"
10
- - "2.5.0"
11
-
12
- env:
13
- global:
14
- - "TESTOPTS=--verbose DB=postgresql DB_CONN_STRING=postgres://postgres@localhost/travis_ci_test"
15
-
16
- matrix:
17
- include:
18
- - rvm: "2.4.0"
19
- env: "DB=mysql DB_CONN_STRING=mysql2://root@localhost/travis_ci_test"
20
- services:
21
- - mysql
22
- - redis
23
- - rvm: "2.4.0"
24
- env: "DB=sqlite3 DB_CONN_STRING=sqlite:/"
25
- - rvm: "2.4.0"
26
- env: "CONCURRENT_RUBY_EXT=true"
27
-
28
- install:
29
- - test/prepare_travis_env.sh
30
-
31
- script:
32
- - bundle exec rubocop
33
- - bundle exec rake test