burstflow 0.1.1 → 0.2.0

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 (43) hide show
  1. checksums.yaml +5 -5
  2. data/Gemfile +1 -3
  3. data/Gemfile.lock +119 -0
  4. data/burstflow.gemspec +10 -6
  5. data/config/database.yml +4 -3
  6. data/db/migrate/20180101000001_create_workflow.rb +1 -0
  7. data/db/schema.rb +13 -7
  8. data/lib/burstflow.rb +11 -0
  9. data/lib/burstflow/job.rb +102 -0
  10. data/lib/burstflow/job/callbacks.rb +55 -0
  11. data/lib/burstflow/job/exception.rb +8 -0
  12. data/lib/burstflow/job/initialization.rb +35 -0
  13. data/lib/{burst → burstflow/job}/model.rb +1 -3
  14. data/lib/burstflow/job/state.rb +125 -0
  15. data/lib/burstflow/manager.rb +123 -0
  16. data/lib/burstflow/railtie.rb +6 -0
  17. data/lib/burstflow/version.rb +3 -0
  18. data/lib/burstflow/worker.rb +59 -0
  19. data/lib/burstflow/workflow.rb +207 -0
  20. data/lib/burstflow/workflow/builder.rb +91 -0
  21. data/lib/burstflow/workflow/callbacks.rb +66 -0
  22. data/lib/{burst/workflow_helper.rb → burstflow/workflow/configuration.rb} +8 -39
  23. data/lib/burstflow/workflow/exception.rb +8 -0
  24. data/lib/generators/burstflow/install/install_generator.rb +22 -0
  25. data/lib/generators/burstflow/install/templates/create_workflow.rb +15 -0
  26. data/spec/builder_spec.rb +63 -0
  27. data/spec/{burst_spec.rb → burstflow_spec.rb} +1 -1
  28. data/spec/generators/install_generator_spec.rb +27 -0
  29. data/spec/job_spec.rb +18 -8
  30. data/spec/spec_helper.rb +4 -1
  31. data/spec/support/database_clean.rb +4 -1
  32. data/spec/workflow_spec.rb +397 -147
  33. metadata +45 -21
  34. data/db/migrate/20180101000001_create_workflow.rb +0 -13
  35. data/db/seeds.rb +0 -1
  36. data/lib/burst.rb +0 -37
  37. data/lib/burst/builder.rb +0 -48
  38. data/lib/burst/configuration.rb +0 -27
  39. data/lib/burst/job.rb +0 -187
  40. data/lib/burst/manager.rb +0 -79
  41. data/lib/burst/worker.rb +0 -42
  42. data/lib/burst/workflow.rb +0 -148
  43. data/spec/cases_spec.rb +0 -180
@@ -3,7 +3,8 @@ require 'bundler'
3
3
  require 'bundler/setup'
4
4
  Bundler.require(:default)
5
5
 
6
- require 'burst'
6
+ require 'awesome_print'
7
+ require 'burstflow'
7
8
 
8
9
 
9
10
  ActiveJob::Base.queue_adapter = :test
@@ -12,6 +13,8 @@ ActiveJob::Base.logger = nil
12
13
  $root = File.join(File.dirname(__dir__), 'spec')
13
14
  Dir[File.join($root, 'support', '**', '*.rb')].each {|f| require f }
14
15
 
16
+ #ActiveJob::Base.logger = ActiveSupport::TaggedLogging.new(ActiveSupport::Logger.new(STDOUT))
17
+ ActiveJob::Base.logger = ActiveSupport::Logger.new('/dev/null')
15
18
 
16
19
 
17
20
 
@@ -7,7 +7,10 @@ RSpec.configure do |config|
7
7
 
8
8
  config.before(:each) do
9
9
  DatabaseCleaner.strategy = :transaction
10
- DatabaseCleaner.start
10
+ end
11
+
12
+ config.before(:each, threads: true) do
13
+ DatabaseCleaner.strategy = :truncation
11
14
  end
12
15
 
13
16
  config.after(:each) do
@@ -1,185 +1,435 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe Burst::Workflow do
4
- class TestJob < Burst::Job
5
-
6
- def perform
7
- # puts "#{self.class} perform"
3
+ describe Burstflow::Workflow do
4
+ WfJob1 = Class.new(Burstflow::Job)
5
+ WfJob2 = Class.new(Burstflow::Job)
6
+ WfJob3 = Class.new(Burstflow::Job)
7
+
8
+ class Workflow1 < Burstflow::Workflow
9
+ $conf1 = configure do |arg1, arg2|
10
+ $jobid1 = run WfJob1, params: { param1: true, arg: arg1}
11
+ $jobid2 = run WfJob2, params: { param2: true, arg: arg2}, after: WfJob1
12
+ $jobid3 = run WfJob3, before: WfJob2, after: $jobid1
13
+ $jobid4 = run WfJob3, after: $jobid3
8
14
  end
9
-
10
- end
11
-
12
- class WfJob1 < TestJob
13
15
  end
14
16
 
15
- class WfJob2 < TestJob
16
- end
17
-
18
- class WfJob3 < TestJob
17
+ class Workflow2 < Burstflow::Workflow
18
+ $conf2 = configure do |arg1, arg2|
19
+ $jobid1 = run WfJob1, params: { param1: true, arg: arg1}
20
+ $jobid2 = run WfJob2, params: { param2: true, arg: arg2}, after: WfJob1
21
+ $jobid3 = run WfJob3, before: WfJob2, after: $jobid1
22
+ $jobid4 = run WfJob3, after: $jobid3
23
+ end
19
24
  end
20
25
 
26
+ describe "initializing" do
27
+ it "class level configuration" do
28
+ expect(Burstflow::Workflow.configuration).to eq nil
29
+ expect(Workflow1.configuration).to eq $conf1
30
+ expect(Workflow2.configuration).to eq $conf2
31
+ expect($conf1).not_to eq $conf2
32
+ end
21
33
 
22
- class W1 < Burst::Workflow
23
-
24
- configure do |*_args|
25
- id1 = run WfJob1, id: 'job1'
26
- run WfJob2, id: 'job2', after: id1
27
- run WfJob3, after: [WfJob1, 'job2']
34
+ it "build" do
35
+ Workflow1.build(:arg1, :arg2).save!
36
+ wf1 = Workflow1.first
37
+ jobs = wf1.flow['jobs_config']
38
+
39
+ expect(jobs.count).to eq 4
40
+ expect(wf1.initial_jobs.count).to eq 1
41
+
42
+ expect(jobs[$jobid1]).to include(:id,
43
+ klass: WfJob1.to_s,
44
+ incoming: [],
45
+ outgoing: [$jobid2, $jobid3],
46
+ workflow_id: wf1.id,
47
+ params: {'param1' => true, 'arg' => 'arg1'})
48
+
49
+ expect(jobs[$jobid2]).to include(:id,
50
+ klass: WfJob2.to_s,
51
+ incoming: [$jobid1, $jobid3],
52
+ outgoing: [],
53
+ workflow_id: wf1.id,
54
+ params: {'param2' => true, 'arg' => 'arg2'})
55
+
56
+ expect(jobs[$jobid3]).to include(:id,
57
+ klass: WfJob3.to_s,
58
+ incoming: [$jobid1],
59
+ outgoing: [$jobid2, $jobid4],
60
+ workflow_id: wf1.id,
61
+ params: nil)
62
+
63
+ expect(jobs[$jobid4]).to include(:id,
64
+ klass: WfJob3.to_s,
65
+ incoming: [$jobid3],
66
+ outgoing: [],
67
+ workflow_id: wf1.id,
68
+ params: nil)
28
69
  end
29
70
 
30
71
  end
31
72
 
32
- def expect_jobs(*jobs)
33
- j1, j2, j3 = *jobs
73
+ describe "executing" do
34
74
 
35
- expect(j1.finished?).to eq false
36
- expect(j2.finished?).to eq false
75
+ def perform_enqueued_job wf, enqueued_job
76
+ enqueued_job[:job].new(*enqueued_job[:args]).perform_now
37
77
 
38
- expect(j1.klass).to eq 'WfJob1'
39
- expect(j2.klass).to eq 'WfJob2'
40
- expect(j3.klass).to eq 'WfJob3'
78
+ queue_adapter.performed_jobs << enqueued_job
79
+ queue_adapter.enqueued_jobs.delete(enqueued_job)
80
+
81
+ wf.reload
82
+ end
41
83
 
42
- expect(j1.outgoing).to include(j2.id, j3.id)
43
- expect(j2.outgoing).to include(j3.id)
44
- expect(j3.outgoing).to include
84
+ def perform_enqueued_jobs_async
45
85
 
46
- expect(j1.incoming).to include
47
- expect(j2.incoming).to include(j1.id)
48
- expect(j3.incoming).to include(j1.id, j2.id)
86
+ jobs = Enumerator.new do |y|
87
+ while queue_adapter.enqueued_jobs.count > 0
88
+ y << queue_adapter.enqueued_jobs.shift
89
+ end
90
+ end
49
91
 
50
- expect(j1.initial?).to eq true
51
- expect(j2.initial?).to eq false
52
- expect(j3.initial?).to eq false
53
- end
54
-
55
- context 'model' do
56
- it 'default store' do
57
- w = Burst::Workflow.new
92
+ result = yield
93
+ while queue_adapter.enqueued_jobs.count > 0 do
58
94
 
59
- expect(w.attributes).to include(:id, jobs: {}, klass: Burst::Workflow.to_s)
95
+ threads = jobs.map do |job|
96
+ Thread.new(job) do |job|
97
+ job[:job].new(*job[:args]).perform_now
98
+ queue_adapter.performed_jobs << job
99
+ end
100
+ end
60
101
 
61
- expect(w.started?).to eq false
62
- expect(w.failed?).to eq false
63
- expect(w.finished?).to eq true
64
- expect(w.running?).to eq false
65
- expect(w.status).to eq Burst::Workflow::FINISHED
102
+ threads.each(&:join)
103
+ end
104
+ result
66
105
  end
67
106
 
68
- it 'store persistance' do
69
- w = Burst::Workflow.new
70
- w.save!
71
-
72
- w2 = Burst::Workflow.find(w.id)
73
- expect(w2.attributes).to include(w.attributes)
107
+ describe "complex" do
108
+ let(:wf){Workflow1.build(:arg1, :arg2)}
109
+
110
+ before do
111
+ wf.start!
112
+ end
113
+
114
+ it "success story one by one" do
115
+ expect(Burstflow::Worker).to have_jobs(wf.id, [$jobid1])
116
+
117
+ expect(queue_adapter.enqueued_jobs.count).to eq 1
118
+ expect(queue_adapter.enqueued_jobs.first).to include(args: [wf.id, $jobid1])
119
+ expect(wf.jobs.count(&:enqueued?)).to eq 1
120
+ expect(wf.jobs.count(&:started?)).to eq 0
121
+ expect(wf.jobs.count(&:finished?)).to eq 0
122
+ expect(wf.jobs.count(&:ready_to_start?)).to eq 0
123
+
124
+ perform_enqueued_job(wf, queue_adapter.enqueued_jobs.first)
125
+ expect(queue_adapter.enqueued_jobs.count).to eq 1
126
+ expect(queue_adapter.enqueued_jobs.first).to include(args: [wf.id, $jobid3])
127
+ expect(wf.jobs.count(&:enqueued?)).to eq 2
128
+ expect(wf.jobs.count(&:started?)).to eq 1
129
+ expect(wf.jobs.count(&:finished?)).to eq 1
130
+ expect(wf.jobs.count(&:ready_to_start?)).to eq 0
131
+
132
+ perform_enqueued_job(wf, queue_adapter.enqueued_jobs.first)
133
+ expect(queue_adapter.enqueued_jobs.count).to eq 2
134
+ expect(queue_adapter.enqueued_jobs.first).to include(args: [wf.id, $jobid2])
135
+ expect(queue_adapter.enqueued_jobs.last).to include(args: [wf.id, $jobid4])
136
+ expect(wf.jobs.count(&:enqueued?)).to eq 4
137
+ expect(wf.jobs.count(&:started?)).to eq 2
138
+ expect(wf.jobs.count(&:finished?)).to eq 2
139
+ expect(wf.jobs.count(&:ready_to_start?)).to eq 0
140
+
141
+ perform_enqueued_job(wf, queue_adapter.enqueued_jobs.first)
142
+ expect(queue_adapter.enqueued_jobs.last).to include(args: [wf.id, $jobid4])
143
+ expect(queue_adapter.enqueued_jobs.count).to eq 1
144
+ expect(wf.jobs.count(&:enqueued?)).to eq 4
145
+ expect(wf.jobs.count(&:started?)).to eq 3
146
+ expect(wf.jobs.count(&:finished?)).to eq 3
147
+ expect(wf.jobs.count(&:ready_to_start?)).to eq 0
148
+
149
+ perform_enqueued_job(wf, queue_adapter.enqueued_jobs.first)
150
+ expect(queue_adapter.enqueued_jobs.count).to eq 0
151
+ expect(wf.jobs.count(&:enqueued?)).to eq 4
152
+ expect(wf.jobs.count(&:started?)).to eq 4
153
+ expect(wf.jobs.count(&:finished?)).to eq 4
154
+ expect(wf.jobs.count(&:ready_to_start?)).to eq 0
155
+
156
+ end
157
+
158
+ it "success story all at once sync" do
159
+ perform_enqueued_jobs do
160
+ perform_enqueued_job(wf, queue_adapter.enqueued_jobs.first)
161
+ end
162
+
163
+ expect(queue_adapter.enqueued_jobs.count).to eq 0
164
+ expect(wf.jobs.count(&:enqueued?)).to eq 4
165
+ expect(wf.jobs.count(&:started?)).to eq 4
166
+ expect(wf.jobs.count(&:finished?)).to eq 4
167
+ expect(wf.jobs.count(&:ready_to_start?)).to eq 0
168
+ end
169
+
170
+ it "success story all at once async", threads: true do
171
+ perform_enqueued_jobs_async do
172
+ perform_enqueued_job(wf, queue_adapter.enqueued_jobs.first)
173
+ end
174
+
175
+ wf.reload
176
+ expect(queue_adapter.enqueued_jobs.count).to eq 0
177
+ expect(wf.jobs.count(&:enqueued?)).to eq 4
178
+ expect(wf.jobs.count(&:started?)).to eq 4
179
+ expect(wf.jobs.count(&:finished?)).to eq 4
180
+ expect(wf.jobs.count(&:ready_to_start?)).to eq 0
181
+ end
74
182
  end
75
183
 
76
- it 'builded store' do
77
- w = W1.build
78
-
79
- jobs = w.jobs
80
- expect_jobs(*jobs.values.map{|json| Burst::Job.new(w, json) })
81
-
82
- expect(w.attributes).to include(:id, jobs: jobs, klass: W1.to_s)
184
+ describe "concurrency" do
185
+ class MapJob1 < Burstflow::Job
186
+ def perform
187
+ set_output(params['i'])
188
+ end
189
+ end
190
+
191
+ class ReduceJob1 < Burstflow::Job
192
+ def perform
193
+ set_output(payloads.map{|p| p[:value]}.sum)
194
+ end
195
+ end
196
+
197
+ class ConcWorkflow < Burstflow::Workflow
198
+ configure do |size|
199
+ size.to_i.times.to_a.shuffle.each do |i|
200
+ run MapJob1, params: {i: i}, before: ReduceJob1
201
+ end
202
+
203
+ $jobid = run ReduceJob1
204
+ end
205
+ end
206
+
207
+ let(:count){50}
208
+ let(:expected_result){count.times.sum}
209
+
210
+ it "sync" do
211
+ wf = perform_enqueued_jobs do
212
+ ConcWorkflow.build(count).start!
213
+ end.reload
214
+
215
+ expect(wf.job($jobid).output).to eq expected_result
216
+ end
217
+
218
+ it "threaded", threads: true do
219
+ wf = perform_enqueued_jobs_async do
220
+ ConcWorkflow.build(count).start!
221
+ end.reload
222
+
223
+ expect(wf.job($jobid).output).to eq expected_result
224
+ end
83
225
  end
84
226
 
85
- it 'builded persistance' do
86
- w = W1.build
87
- w.save!
227
+ describe "simple" do
228
+ WfSimpleJob = Class.new(Burstflow::Job)
229
+ WfFailureJob = Class.new(Burstflow::Job) do
230
+ def perform
231
+ raise "ex"
232
+ end
233
+ end
234
+
235
+ WfSuspendJob = Class.new(Burstflow::Job) do
236
+ def perform
237
+ return Burstflow::Job::SUSPEND
238
+ end
239
+ end
240
+
241
+ describe "parallel failure" do
242
+ class Workflow3 < Burstflow::Workflow
243
+ configure do |arg1, arg2|
244
+ $jobid1 = run WfSimpleJob
245
+ $jobid2 = run WfFailureJob
246
+ $jobid3 = run WfSimpleJob, after: $jobid2
247
+ end
248
+ end
249
+
250
+ it "run" do
251
+ wf = perform_enqueued_jobs do
252
+ Workflow3.build.start!
253
+ end.reload
254
+
255
+ expect(wf.status).to eq Burstflow::Workflow::FAILED
256
+ expect(wf.failures.first).to include(:created_at, job: $jobid2)
257
+
258
+ expect(wf.job($jobid1).succeeded?).to eq true
259
+
260
+ expect(wf.job($jobid2).succeeded?).to eq false
261
+ expect(wf.job($jobid2).failed?).to eq true
262
+ expect(wf.job($jobid2).failure).to include(klass: 'RuntimeError', message: 'ex')
263
+
264
+ expect(wf.job($jobid3).enqueued?).to eq false
265
+ end
266
+ end
267
+
268
+ describe "parallel suspend" do
269
+ class Workflow4 < Burstflow::Workflow
270
+ configure do |arg1, arg2|
271
+ $jobid1 = run WfSimpleJob
272
+ $jobid2 = run WfSuspendJob
273
+ $jobid3 = run WfSimpleJob, after: $jobid2
274
+ end
275
+ end
276
+
277
+ it "run" do
278
+ wf = perform_enqueued_jobs do
279
+ Workflow4.build.start!
280
+ end.reload
281
+
282
+ expect(wf.status).to eq Burstflow::Workflow::SUSPENDED
283
+
284
+ expect(wf.job($jobid1).succeeded?).to eq true
285
+ expect(wf.job($jobid2).suspended?).to eq true
286
+ expect(wf.job($jobid3).enqueued?).to eq false
287
+
288
+ wf = perform_enqueued_jobs do
289
+ wf.resume!($jobid2, "gogogo")
290
+ end.reload
291
+
292
+ expect(wf.status).to eq Burstflow::Workflow::FINISHED
293
+
294
+ expect(wf.job($jobid1).succeeded?).to eq true
295
+ expect(wf.job($jobid2).succeeded?).to eq true
296
+ expect(wf.job($jobid3).succeeded?).to eq true
297
+ end
298
+ end
299
+
300
+ describe "dynamic job creation" do
301
+ let(:count) {10}
302
+ let(:expected_result) {(count + 1).times.sum}
303
+
304
+ WfDynamicJob = Class.new(Burstflow::Job) do
305
+ def perform
306
+ if params['i'] > 0
307
+ configure(self.id, params) do |id, params|
308
+ $lasjobid = run WfDynamicJob, params: {i: params['i'] - 1}, after: id
309
+ end
310
+ end
311
+
312
+ output = if payload = payloads.first
313
+ payload[:value] + params['i']
314
+ else
315
+ params['i']
316
+ end
317
+
318
+ set_output(output)
319
+ end
320
+ end
321
+
322
+ class WorkflowDynamic < Burstflow::Workflow
323
+ configure do |count|
324
+ run WfDynamicJob, params: {i: count}
325
+ end
326
+ end
327
+
328
+ it "run" do
329
+ wf = WorkflowDynamic.build(count)
330
+ wf.save!
331
+
332
+ expect(wf.jobs.count).to eq 1
333
+
334
+ wf = perform_enqueued_jobs do
335
+ WorkflowDynamic.build(count).start!
336
+ end.reload
337
+
338
+ expect(wf.jobs.count).to eq 11
339
+ expect(wf.job($lasjobid).output).to eq expected_result
340
+ end
341
+
342
+ end
343
+
344
+ describe "callbacks" do
345
+
346
+ WfCallJob = Class.new(Burstflow::Job) do
347
+ before_enqueue :be
348
+ before_perform :bp
349
+ before_suspend :bs
350
+ before_resume :br
351
+ before_failure :bf
352
+
353
+ def be;$be = true;end
354
+ def bp;$bp = true;end
355
+ def bs;$bs = true;end
356
+ def br;$br = true;end
357
+ def bf;$bf = true;end
358
+
359
+ def perform
360
+ suspend()
361
+ end
362
+
363
+ def resume data
364
+ raise "ex"
365
+ end
366
+ end
367
+
368
+ class WorkflowCall < Burstflow::Workflow
369
+ before_suspend :wbs
370
+ before_resume :wbr
371
+ before_failure :wbf
372
+
373
+ def wbs;$wbs = true;end
374
+ def wbr;$wbr = true;end
375
+ def wbf;$wbf = true;end
376
+
377
+ configure do
378
+ $jobid1 = run WfCallJob
379
+ end
380
+ end
381
+
382
+ it "run" do
383
+ expect([$be, $bp, $bs, $br, $bf].any?).to eq false
384
+ expect([$wbs, $wbr, $wbf].any?).to eq false
385
+
386
+ wf = perform_enqueued_jobs do
387
+ WorkflowCall.build.start!
388
+ end.reload
389
+
390
+ wf = perform_enqueued_jobs do
391
+ wf.resume!($jobid1, '123123123')
392
+ end.reload
393
+
394
+ expect(wf.status).to eq Burstflow::Workflow::FAILED
395
+ expect(wf.failures.first).to include(:created_at, job: $jobid1)
396
+
397
+ expect(wf.job($jobid1).succeeded?).to eq false
398
+ expect(wf.job($jobid1).failed?).to eq true
399
+ expect(wf.job($jobid1).failure).to include(klass: 'RuntimeError', message: 'ex')
400
+
401
+ expect([$be, $bp, $bs, $br, $bf].all?).to eq true
402
+ expect([$wbs, $wbr, $wbf].all?).to eq true
403
+ end
404
+ end
88
405
 
89
- jobs = w.jobs
90
- expect_jobs(*jobs.values.map{|json| Burst::Job.new(w, json) })
91
406
 
92
- w2 = Burst::Workflow.find(w.id)
93
- expect(w2.attributes).to include(w.attributes)
94
407
  end
95
- end
96
-
97
- def expect_wf(w)
98
- j1 = w.find_job('job1')
99
- j2 = w.find_job('job2')
100
- j3 = w.find_job(WfJob3)
101
-
102
- expect(j1.finished?).to eq false
103
- expect(j2.finished?).to eq false
104
408
 
105
- expect(j1.klass).to eq 'WfJob1'
106
- expect(j2.klass).to eq 'WfJob2'
107
- expect(j3.klass).to eq 'WfJob3'
108
-
109
- expect(j1.outgoing).to include(j2.id, j3.id)
110
- expect(j2.outgoing).to include(j3.id)
111
- expect(j3.outgoing).to include
112
-
113
- expect(j1.incoming).to include
114
- expect(j2.incoming).to include(j1.id)
115
- expect(j3.incoming).to include(j1.id, j2.id)
116
-
117
- expect(j1.initial?).to eq true
118
- expect(j2.initial?).to eq false
119
- expect(j3.initial?).to eq false
120
-
121
- expect(w.initial_jobs).to include(j1)
122
- end
123
-
124
- it 'check builder' do
125
- w = W1.build
126
- expect_wf(w)
127
-
128
- expect(w.status)
129
409
  end
410
+
411
+ context 'model' do
412
+ it 'default store' do
413
+ w = Burstflow::Workflow.new
130
414
 
131
- it 'check persistance' do
132
- w = W1.build
133
- w.save!
134
-
135
- w2 = W1.find(w.id)
136
- expect_wf(w2)
137
- end
138
-
139
- it 'start without perform' do
140
- w = W1.build
141
- w.save!
142
-
143
- expect(w.started?).to eq false
144
- expect(w.failed?).to eq false
145
- expect(w.finished?).to eq false
146
- expect(w.running?).to eq false
147
- expect(w.status).to eq Burst::Workflow::INITIAL
148
-
149
- w.start!
150
-
151
- expect(Burst::Worker).to have_jobs(w.id, ['job1'])
152
- expect(Burst::Worker).not_to have_jobs(w.id, ['job2'])
153
-
154
- w = W1.find(w.id)
415
+ expect(w.attributes).to include(:id, jobs_config: {}, type: Burstflow::Workflow.to_s)
155
416
 
156
- expect(w.started?).to eq false
157
- expect(w.failed?).to eq false
158
- expect(w.finished?).to eq false
159
- expect(w.running?).to eq false
160
- expect(w.status).to eq Burst::Workflow::INITIAL
161
- end
162
-
163
- it 'start with perform' do
164
- w = W1.build
165
- w.save!
417
+ expect(w.initial?).to eq true
418
+ expect(w.failed?).to eq false
419
+ expect(w.finished?).to eq false
420
+ expect(w.running?).to eq false
421
+ expect(w.suspended?).to eq false
422
+ expect(w.status).to eq Burstflow::Workflow::INITIAL
423
+ end
166
424
 
167
- expect(w.started?).to eq false
168
- expect(w.failed?).to eq false
169
- expect(w.finished?).to eq false
170
- expect(w.running?).to eq false
171
- expect(w.status).to eq Burst::Workflow::INITIAL
425
+ it 'store persistance' do
426
+ w = Burstflow::Workflow.new
427
+ w.save!
172
428
 
173
- perform_enqueued_jobs do
174
- w.start!
429
+ w2 = Burstflow::Workflow.find(w.id)
430
+ expect(w2.attributes).to include(w.attributes)
175
431
  end
176
432
 
177
- w = W1.find(w.id)
178
-
179
- expect(w.started?).to eq true
180
- expect(w.failed?).to eq false
181
- expect(w.finished?).to eq true
182
- expect(w.running?).to eq false
183
- expect(w.status).to eq Burst::Workflow::FINISHED
184
433
  end
434
+
185
435
  end