aws-flow 1.3.0 → 2.0.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 (48) hide show
  1. checksums.yaml +15 -0
  2. data/aws-flow.gemspec +1 -0
  3. data/lib/aws/decider/activity.rb +8 -6
  4. data/lib/aws/decider/async_decider.rb +1 -0
  5. data/lib/aws/decider/async_retrying_executor.rb +3 -3
  6. data/lib/aws/decider/decider.rb +16 -14
  7. data/lib/aws/decider/executor.rb +35 -22
  8. data/lib/aws/decider/flow_defaults.rb +28 -14
  9. data/lib/aws/decider/generic_client.rb +3 -4
  10. data/lib/aws/decider/options.rb +91 -117
  11. data/lib/aws/decider/state_machines.rb +1 -0
  12. data/lib/aws/decider/utilities.rb +15 -0
  13. data/lib/aws/decider/version.rb +1 -1
  14. data/lib/aws/decider/worker.rb +14 -8
  15. data/lib/aws/decider/workflow_client.rb +16 -11
  16. data/lib/aws/runner.rb +43 -39
  17. data/spec/aws/decider/integration/activity_spec.rb +345 -0
  18. data/spec/aws/{integration → decider/integration}/integration_spec.rb +818 -1183
  19. data/spec/aws/decider/integration/setup.rb +3 -0
  20. data/spec/aws/decider/unit/activity_spec.rb +233 -0
  21. data/spec/aws/decider/unit/async_retrying_executor_spec.rb +131 -0
  22. data/spec/aws/{unit → decider/unit}/decider_spec.rb +171 -718
  23. data/spec/aws/decider/unit/executor_spec.rb +123 -0
  24. data/spec/aws/decider/unit/flow_defaults_spec.rb +62 -0
  25. data/spec/aws/decider/unit/misc_spec.rb +101 -0
  26. data/spec/aws/decider/unit/options_spec.rb +289 -0
  27. data/spec/aws/decider/unit/retry_spec.rb +217 -0
  28. data/spec/aws/{unit → decider/unit}/rubyflow.rb +0 -0
  29. data/spec/aws/decider/unit/setup.rb +3 -0
  30. data/spec/aws/decider/unit/worker_spec.rb +325 -0
  31. data/spec/aws/decider/unit/workflow_client_spec.rb +83 -0
  32. data/spec/aws/{unit → flow}/async_backtrace_spec.rb +0 -0
  33. data/spec/aws/{unit → flow}/async_scope_spec.rb +0 -0
  34. data/spec/aws/{unit → flow}/begin_rescue_ensure_spec.rb +1 -0
  35. data/spec/aws/{unit → flow}/external_task_spec.rb +0 -0
  36. data/spec/aws/{unit → flow}/factories.rb +0 -0
  37. data/spec/aws/{unit → flow}/fiber_condition_variable_spec.rb +0 -0
  38. data/spec/aws/{unit → flow}/fiber_spec.rb +0 -0
  39. data/spec/aws/{unit → flow}/flow_spec.rb +0 -0
  40. data/spec/aws/{unit → flow}/future_spec.rb +0 -0
  41. data/spec/aws/{unit → flow}/simple_dfa_spec.rb +0 -0
  42. data/spec/aws/{integration → runner/integration}/runner_integration_spec.rb +16 -43
  43. data/spec/aws/{unit → runner/unit}/runner_unit_spec.rb +18 -18
  44. data/spec/spec_helper.rb +264 -2
  45. metadata +37 -28
  46. data/spec/aws/unit/executor_spec.rb +0 -49
  47. data/spec/aws/unit/options_spec.rb +0 -293
  48. data/spec/aws/unit/preinclude_tests.rb +0 -149
@@ -16,52 +16,7 @@
16
16
  require 'yaml'
17
17
  require 'aws-sdk'
18
18
  require 'logger'
19
-
20
- require 'aws/decider'
21
- include AWS::Flow
22
-
23
- $RUBYFLOW_DECIDER_TASK_LIST = 'test_task_list'
24
-
25
- def kill_executors
26
- return if ForkingExecutor.executors.nil?
27
- ForkingExecutor.executors.each do |executor|
28
- executor.shutdown(0) unless executor.is_shutdown rescue StandardError
29
- end
30
- #TODO Reinstate this, but it's useful to keep them around for debugging
31
- #ForkingExecutor.executors = []
32
- end
33
-
34
- def setup_swf
35
- current_date = Time.now.strftime("%d-%m-%Y")
36
- file_name = "/tmp/" + current_date
37
- if File.exists?(file_name)
38
- last_run = File.open(file_name, 'r').read.to_i
39
- else
40
- last_run = 0
41
- end
42
- last_run += 1
43
- File.open(file_name, 'w+') {|f| f.write(last_run)}
44
- current_date = Time.now.strftime("%d-%m-%Y")
45
- config_file = File.open('credentials.cfg') { |f| f.read }
46
- if config_file.include? ":Primary"
47
- yaml_config = YAML.load(config_file)
48
- swf = AWS::SimpleWorkflow.new(yaml_config[:Primary])
49
- secondary_swf = AWS::SimpleWorkflow.new(yaml_config[:Secondary])
50
- else
51
- config = YAML.load(config_file).first
52
- AWS.config(config)
53
- swf = AWS::SimpleWorkflow.new
54
- secondary_swf = nil
55
- end
56
- $RUBYFLOW_DECIDER_DOMAIN = "rubyflow_decider_domain_#{current_date}-#{last_run}"
57
- begin
58
- domain = swf.domains.create($RUBYFLOW_DECIDER_DOMAIN, "10")
59
- rescue AWS::SimpleWorkflow::Errors::DomainAlreadyExistsFault => e
60
- domain = swf.domains[$RUBYFLOW_DECIDER_DOMAIN]
61
- end
62
- return swf, domain, $RUBYFLOW_DECIDER_DOMAIN, secondary_swf
63
- end
64
-
19
+ require_relative 'setup'
65
20
 
66
21
 
67
22
  class SimpleTestHistoryEvent
@@ -78,21 +33,12 @@ end
78
33
  describe "RubyFlowDecider" do
79
34
  before(:all) do
80
35
  class MyWorkflow
81
- extend Decider
36
+ extend AWS::Flow::Workflows
82
37
  version "1"
83
38
  # TODO more of the stuff from the proposal
84
39
  end
85
- @swf, @domain, $RUBYFLOW_DECIDER_DOMAIN, @swf_secondary = setup_swf
86
- $swf, $domain, $swf_secondary = @swf, @domain, @swf_secondary
87
- # If there are any outstanding decision tasks before we start the test, that
88
- # could really mess things up, and make the tests non-idempotent. So lets
89
- # clear those out
90
40
 
91
- while @domain.decision_tasks.count($RUBYFLOW_DECIDER_TASK_LIST).count > 0
92
- @domain.decision_tasks.poll_for_single_task($RUBYFLOW_DECIDER_TASK_LIST) do |task|
93
- task.complete workflow_execution
94
- end
95
- end
41
+ @swf, @domain = setup_swf
96
42
  if @domain.workflow_executions.with_status(:open).count.count > 0
97
43
  @domain.workflow_executions.with_status(:open).each { |wf| wf.terminate }
98
44
  end
@@ -110,7 +56,7 @@ describe "RubyFlowDecider" do
110
56
  target_workflow = @domain.workflow_types.page(:per_page => 1000).select { |x| x.name == "blank_workflow_test"}
111
57
  if target_workflow.length == 0
112
58
  workflow_type = @domain.workflow_types.create("blank_workflow_test", '1',
113
- :default_task_list => $RUBYFLOW_DECIDER_TASK_LIST,
59
+ :default_task_list => "initial_test_tasklist",
114
60
  :default_child_policy => :request_cancel,
115
61
  :default_task_start_to_close_timeout => 3600,
116
62
  :default_execution_start_to_close_timeout => 24 * 3600)
@@ -121,314 +67,19 @@ describe "RubyFlowDecider" do
121
67
  workflow_execution.terminate
122
68
  end
123
69
 
124
-
125
- describe WorkflowTaskPoller do
126
- describe "Integration Tests" do
127
-
128
- end
129
-
130
- describe "Unit Tests" do
131
-
132
- end
133
- end
134
-
135
- describe WorkflowWorker do
136
- describe "Unit Tests" do
137
- end
138
-
139
-
140
- describe "Integration Tests" do
141
-
142
- end
143
- end
144
-
145
- describe DecisionTaskHandler do
146
-
147
- end
148
-
149
- describe "interface" do
150
- end
151
-
152
- describe Activities do
153
- it "ensures that a real activity will get scheduled" do
154
- task_list = "activity_task_list"
155
- class Blah
156
- extend Activity
157
- end
158
- class BasicActivity
159
- extend Activity
160
-
161
- activity :run_activity1 do |o|
162
- o.default_task_heartbeat_timeout = "3600"
163
- o.default_task_list = "activity_task_list"
164
- o.default_task_schedule_to_close_timeout = "3600"
165
- o.default_task_schedule_to_start_timeout = "3600"
166
- o.default_task_start_to_close_timeout = "3600"
167
- o.version = "1"
168
- end
169
- def run_activity1
170
- "first regular activity"
171
- end
172
- end
173
- class BasicWorkflow
174
- extend Decider
175
-
176
- entry_point :entry_point
177
- version "1"
178
- activity_client :activity do |options|
179
- options.prefix_name = "BasicActivity"
180
- end
181
- def entry_point
182
- activity.run_activity1
183
- end
184
- end
185
- worker = WorkflowWorker.new(@swf.client, @domain, task_list)
186
- worker.add_workflow_implementation(BasicWorkflow)
187
- activity_worker = ActivityWorker.new(@swf.client, @domain, task_list)
188
- activity_worker.add_activities_implementation(BasicActivity)
189
- workflow_type_name = "BasicWorkflow.entry_point"
190
- worker.register
191
- activity_worker.register
192
- sleep 3
193
- workflow_type, _ = @domain.workflow_types.page(:per_page => 1000).select {|x| x.name == workflow_type_name}
194
-
195
- workflow_execution = workflow_type.start_execution(
196
- :execution_start_to_close_timeout => 3600,
197
- :task_list => task_list,
198
- :task_start_to_close_timeout => 3600,
199
- :child_policy => :request_cancel
200
- )
201
- worker.run_once
202
- activity_worker.run_once
203
- worker.run_once
204
- workflow_execution.events.map(&:event_type).should ==
205
- ["WorkflowExecutionStarted", "DecisionTaskScheduled", "DecisionTaskStarted", "DecisionTaskCompleted", "ActivityTaskScheduled", "ActivityTaskStarted", "ActivityTaskCompleted", "DecisionTaskScheduled", "DecisionTaskStarted", "DecisionTaskCompleted", "WorkflowExecutionCompleted"]
206
- end
207
-
208
- it "tests to see what two activities look like" do
209
- task_list = "double_activity_task_list"
210
- class DoubleActivity
211
- extend Activity
212
- activity :run_activity1, :run_activity2 do |o|
213
- o.version = "1"
214
- o.default_task_heartbeat_timeout = "3600"
215
- o.default_task_list = "double_activity_task_list"
216
- o.default_task_schedule_to_close_timeout = "3600"
217
- o.default_task_schedule_to_start_timeout = "10"
218
- o.default_task_start_to_close_timeout = "10"
219
- o.exponential_retry do |retry_options|
220
- retry_options.retries_per_exception = {
221
- ActivityTaskTimedOutException => Float::INFINITY,
222
- }
223
- end
224
- end
225
- def run_activity1
226
- "first parallel activity"
227
- end
228
- def run_activity2
229
- "second parallel activity"
230
- end
231
- end
232
- class DoubleWorkflow
233
- extend Decider
234
- version "1"
235
- activity_client :activity do |options|
236
- options.prefix_name = "DoubleActivity"
237
- end
238
- entry_point :entry_point
239
- def entry_point
240
- activity.send_async(:run_activity1)
241
- activity.run_activity2
242
- end
243
- end
244
-
245
- worker = WorkflowWorker.new(@swf.client, @domain, task_list)
246
- worker.add_workflow_implementation(DoubleWorkflow)
247
- activity_worker = ActivityWorker.new(@swf.client, @domain, task_list)
248
- activity_worker.add_activities_implementation(DoubleActivity)
249
- workflow_type_name = "DoubleWorkflow.entry_point"
250
- worker.register
251
- activity_worker.register
252
- sleep 3
253
- workflow_id = "basic_activity_workflow"
254
- run_id = @swf.client.start_workflow_execution(
255
- :execution_start_to_close_timeout => "3600",
256
- :task_list => {:name => task_list},
257
- :task_start_to_close_timeout => "3600",
258
- :child_policy => "REQUEST_CANCEL",
259
- :workflow_type => {
260
- :name => workflow_type_name,
261
- :version => "1"
262
- },
263
- :workflow_id => workflow_id,
264
- :domain => @domain.name.to_s
265
- )
266
- workflow_execution = AWS::SimpleWorkflow::WorkflowExecution.new(@domain, workflow_id, run_id["runId"])
267
- @forking_executor = ForkingExecutor.new(:max_workers => 3)
268
- @forking_executor.execute { worker.start }
269
- sleep 5
270
- @forking_executor.execute { activity_worker.start }
271
- sleep 20
272
- @forking_executor.shutdown(1)
273
-
274
- workflow_history = workflow_execution.events.map(&:event_type)
275
- workflow_history.count("ActivityTaskCompleted").should == 2
276
- workflow_history.count("WorkflowExecutionCompleted").should == 1
277
- end
278
-
279
- it "tests to see that two subsequent activities are supported" do
280
- task_list = "subsequent_activity_task_list"
281
- class SubsequentActivity
282
- extend Activity
283
- activity :run_activity1, :run_activity2 do |o|
284
- o.default_task_heartbeat_timeout = "3600"
285
- o.version = "1"
286
- o.default_task_list = "subsequent_activity_task_list"
287
- o.default_task_schedule_to_close_timeout = "3600"
288
- o.default_task_schedule_to_start_timeout = "20"
289
- o.default_task_start_to_close_timeout = "20"
290
- end
291
- def run_activity1
292
- "First subsequent activity"
293
- end
294
- def run_activity2
295
- "Second subsequent activity"
296
- end
297
- end
298
- class SubsequentWorkflow
299
- extend Workflows
300
- workflow :entry_point do
301
- {
302
- :version => "1",
303
- }
304
- end
305
- version "1"
306
- activity_client :activity do |options|
307
- options.prefix_name = "SubsequentActivity"
308
- end
309
- def entry_point
310
- activity.run_activity1
311
- activity.run_activity2
312
- end
313
- end
314
-
315
- worker = WorkflowWorker.new(@swf.client, @domain, task_list)
316
- worker.add_workflow_implementation(SubsequentWorkflow)
317
- activity_worker = ActivityWorker.new(@swf.client, @domain, task_list)
318
- activity_worker.add_activities_implementation(SubsequentActivity)
319
- workflow_type_name = "SubsequentWorkflow.entry_point"
320
- worker.register
321
- activity_worker.register
322
- sleep 3
323
-
324
-
325
- my_workflow_client = workflow_client(@swf.client, @domain) do
326
- {
327
- :from_class => "SubsequentWorkflow",
328
- :execution_start_to_close_timeout => "3600",
329
- :task_list => task_list,
330
- :task_start_to_close_timeout => "3600",
331
- :child_policy => "REQUEST_CANCEL",
332
- }
333
- end
334
- workflow_execution = my_workflow_client.start_execution
335
- worker.run_once
336
- activity_worker.run_once
337
- worker.run_once
338
- activity_worker.run_once
339
- worker.run_once
340
- workflow_execution.events.map(&:event_type).count("WorkflowExecutionCompleted").should == 1
341
- end
342
-
343
- it "tests a much larger workflow" do
344
- task_list = "large_activity_task_list"
345
- class LargeActivity
346
- extend Activity
347
- activity :run_activity1, :run_activity2, :run_activity3, :run_activity4 do |o|
348
- o.default_task_heartbeat_timeout = "3600"
349
- o.default_task_list = "large_activity_task_list"
350
- o.default_task_schedule_to_close_timeout = "3600"
351
- o.default_task_schedule_to_start_timeout = "5"
352
- o.default_task_start_to_close_timeout = "5"
353
- o.version = "1"
354
- o.exponential_retry do |retry_options|
355
- retry_options.retries_per_exception = {
356
- ActivityTaskTimedOutException => Float::INFINITY,
357
- }
358
- end
359
- end
360
- def run_activity1
361
- "My name is Ozymandias - 1"
362
- end
363
- def run_activity2
364
- "King of Kings! - 2 "
365
- end
366
- def run_activity3
367
- "Look on my works, ye mighty - 3"
368
- end
369
- def run_activity4
370
- "And Despair! - 4"
371
- end
372
- end
373
- class LargeWorkflow
374
- extend Decider
375
- version "1"
376
- activity_client :activity do |options|
377
- options.prefix_name = "LargeActivity"
378
- end
379
- entry_point :entry_point
380
- def entry_point
381
- activity.send_async(:run_activity1)
382
- activity.send_async(:run_activity2)
383
- activity.send_async(:run_activity3)
384
- activity.run_activity4()
385
- end
386
- end
387
- worker = WorkflowWorker.new(@swf.client, @domain, task_list)
388
- worker.add_workflow_implementation(LargeWorkflow)
389
- activity_worker = ActivityWorker.new(@swf.client, @domain, task_list)
390
- activity_worker.add_activities_implementation(LargeActivity)
391
- worker.register
392
- activity_worker.register
393
- sleep 3
394
-
395
- workflow_type_name = "LargeWorkflow.entry_point"
396
- workflow_type, _ = @domain.workflow_types.page(:per_page => 1000).select {|x| x.name == workflow_type_name}
397
-
398
- workflow_execution = workflow_type.start_execution(
399
- :execution_start_to_close_timeout => 3600,
400
- :task_list => task_list,
401
- :task_start_to_close_timeout => 15,
402
- :child_policy => :request_cancel
403
- )
404
- @forking_executor = ForkingExecutor.new(:max_workers => 5)
405
- @forking_executor.execute { activity_worker.start }
406
-
407
-
408
- @forking_executor.execute { worker.start }
409
-
410
-
411
- sleep 50
412
-
413
- @forking_executor.shutdown(1)
414
- workflow_history = workflow_execution.events.map(&:event_type)
415
- workflow_history.count("WorkflowExecutionCompleted").should == 1
416
- workflow_history.count("ActivityTaskCompleted").should == 4
417
- end
418
- end
419
-
420
70
  describe WorkflowFactory do
421
71
  it "makes sure that you can use the basic workflow_factory" do
422
72
  task_list = "workflow_factory_task_list"
423
73
  class WorkflowFactoryActivity
424
- extend Activity
425
- activity :run_activity1 do |options|
426
- options.version = "1"
427
- options.default_task_heartbeat_timeout = "3600"
428
- options.default_task_list = "workflow_factory_task_list"
429
- options.default_task_schedule_to_close_timeout = "3600"
430
- options.default_task_schedule_to_start_timeout = "3600"
431
- options.default_task_start_to_close_timeout = "3600"
74
+ extend AWS::Flow::Activities
75
+ activity :run_activity1 do
76
+ {
77
+ version: "1.0",
78
+ default_task_list: "workflow_factory_task_list",
79
+ default_task_schedule_to_close_timeout: 60,
80
+ default_task_schedule_to_start_timeout: 30,
81
+ default_task_start_to_close_timeout: 30,
82
+ }
432
83
  end
433
84
  def run_activity1(arg)
434
85
  "#{arg} is what the activity recieved"
@@ -436,51 +87,36 @@ describe "RubyFlowDecider" do
436
87
  end
437
88
 
438
89
  class WorkflowFactoryWorkflow
439
-
440
- extend Decider
441
- version "1"
442
- entry_point :entry_point
443
- activity_client :activity do |options|
444
- options.prefix_name = "WorkflowFactoryActivity"
445
- options.default_task_heartbeat_timeout = "3600"
446
- options.default_task_list = "workflow_factory_task_list"
447
- options.default_task_schedule_to_close_timeout = "3600"
448
- options.default_task_schedule_to_start_timeout = "3600"
449
- options.default_task_start_to_close_timeout = "3600"
90
+ extend AWS::Flow::Workflows
91
+ workflow :entry_point do
92
+ {
93
+ version: "1.0",
94
+ default_execution_start_to_close_timeout: 600,
95
+ default_task_list: "workflow_factory_task_list",
96
+ default_task_start_to_close_timeout: 120,
97
+ default_child_policy: :request_cancel,
98
+ }
450
99
  end
100
+ activity_client(:activity) { { from_class: "WorkflowFactoryActivity" } }
451
101
  def entry_point(arg)
452
102
  activity.run_activity1("#{arg} recieved as input")
453
103
  end
454
104
  end
455
105
 
456
- worker = WorkflowWorker.new(@swf.client, @domain, task_list)
457
- worker.add_workflow_implementation(WorkflowFactoryWorkflow)
458
- activity_worker = ActivityWorker.new(@swf.client, @domain, task_list)
459
- activity_worker.add_activities_implementation(WorkflowFactoryActivity)
106
+ worker = WorkflowWorker.new(@domain.client, @domain, task_list, WorkflowFactoryWorkflow)
107
+ activity_worker = ActivityWorker.new(@domain.client, @domain, task_list, WorkflowFactoryActivity)
460
108
  worker.register
461
109
  activity_worker.register
462
110
 
463
- my_workflow_factory = workflow_factory(@swf.client, @domain) do |options|
464
- options.workflow_name = "WorkflowFactoryWorkflow"
465
- options.execution_start_to_close_timeout = 3600
466
- options.task_list = "workflow_factory_task_list"
467
- options.task_start_to_close_timeout = 3600
468
- options.task_list
469
- options.child_policy = :request_cancel
470
- end
471
- my_workflow = my_workflow_factory.get_client
111
+ client = AWS::Flow::workflow_client(@domain.client, @domain) { { from_class: "WorkflowFactoryWorkflow" } }
472
112
 
473
- workflow_execution = my_workflow.start_execution("some input")
113
+ workflow_execution = client.start_execution("some input")
474
114
 
475
115
  @forking_executor = ForkingExecutor.new(:max_workers => 3)
476
-
477
116
  @forking_executor.execute { worker.start }
478
-
479
- sleep 3
480
-
481
117
  @forking_executor.execute { activity_worker.start }
482
118
 
483
- sleep 5
119
+ wait_for_execution(workflow_execution)
484
120
 
485
121
  workflow_execution.events.map(&:event_type).should == ["WorkflowExecutionStarted", "DecisionTaskScheduled", "DecisionTaskStarted", "DecisionTaskCompleted", "ActivityTaskScheduled", "ActivityTaskStarted", "ActivityTaskCompleted", "DecisionTaskScheduled", "DecisionTaskStarted", "DecisionTaskCompleted", "WorkflowExecutionCompleted"]
486
122
  @forking_executor.shutdown(1)
@@ -511,30 +147,28 @@ describe "RubyFlowDecider" do
511
147
  class_name = attributes[:class_name] || "General"
512
148
 
513
149
  new_activity_class = Class.new(ParentActivity) do
514
- extend Activities
515
- activity :run_activity1, :run_activity2 do |options|
516
- options.default_task_heartbeat_timeout = "3600"
517
- options.default_task_list = task_list
518
- # options.default_task_schedule_to_close_timeout = "20"
519
- options.default_task_schedule_to_start_timeout = "20"
520
- options.default_task_start_to_close_timeout = "20"
521
- options.version = "1"
522
- options.prefix_name = "#{class_name}Activity"
523
- end
524
- def run_activity1
525
- end
526
- def run_activity2
150
+ extend AWS::Flow::Activities
151
+ activity :run_activity1, :run_activity2 do
152
+ {
153
+ default_task_list: task_list,
154
+ default_task_schedule_to_start_timeout: "60",
155
+ default_task_start_to_close_timeout: "60",
156
+ version: "1.0",
157
+ prefix_name: "#{class_name}Activity",
158
+ }
527
159
  end
160
+ def run_activity1; end
161
+ def run_activity2; end
528
162
  end
529
163
  @activity_class = Object.const_set("#{class_name}Activity", new_activity_class)
530
164
  new_workflow_class = Class.new(ParentWorkflow) do
531
- extend Workflows
165
+ extend AWS::Flow::Workflows
532
166
  workflow(:entry_point) {
533
167
  {
534
- :version => 1,
535
- :execution_start_to_close_timeout => 120,
536
- :task_list => task_list,
537
- :prefix_name => "#{class_name}Workflow"
168
+ version: "1.0",
169
+ default_execution_start_to_close_timeout: 300,
170
+ default_task_list: task_list,
171
+ prefix_name: "#{class_name}Workflow"
538
172
  }
539
173
  }
540
174
  def entry_point
@@ -547,14 +181,14 @@ describe "RubyFlowDecider" do
547
181
  @workflow_class.task_list = task_list
548
182
  @activity_class.task_list = task_list
549
183
  @workflow_class.class_eval do
550
- activity_client(:activity) { {:from_class => self.activity_class} }
184
+ activity_client(:activity) { { from_class: self.activity_class } }
551
185
  end
552
- @worker = WorkflowWorker.new(@swf.client, @domain, task_list, @workflow_class)
553
- @activity_worker = ActivityWorker.new(@swf.client, @domain, task_list, @activity_class)
186
+ @worker = WorkflowWorker.new(@domain.client, @domain, task_list, @workflow_class)
187
+ @activity_worker = ActivityWorker.new(@domain.client, @domain, task_list, @activity_class)
554
188
 
555
189
  @worker.register
556
190
  @activity_worker.register
557
- @my_workflow_client = workflow_client(@swf.client, @domain) { {:from_class => @workflow_class} }
191
+ @my_workflow_client = workflow_client(@domain.client, @domain) { { from_class: @workflow_class } }
558
192
  end
559
193
 
560
194
  it "ensures that an activity returning more than 32k data fails the activity" do
@@ -571,6 +205,7 @@ describe "RubyFlowDecider" do
571
205
  @worker.run_once
572
206
  @activity_worker.run_once
573
207
  @worker.run_once
208
+ wait_for_execution(workflow_execution)
574
209
  history_events = workflow_execution.events.map(&:event_type)
575
210
  # Previously, it would time out, as the failure would include the original
576
211
  # large output that killed the completion and failure call. Thus, we need to
@@ -586,7 +221,7 @@ describe "RubyFlowDecider" do
586
221
  extend Activities
587
222
  activity :run_activity1 do
588
223
  {
589
- :default_task_heartbeat_timeout => "3600",
224
+ :default_task_heartbeat_timeout => "600",
590
225
  :default_task_list => "TwoConfigTaskList",
591
226
  :default_task_schedule_to_start_timeout => 120,
592
227
  :default_task_start_to_close_timeout => 120,
@@ -615,8 +250,7 @@ describe "RubyFlowDecider" do
615
250
  end
616
251
  worker = WorkflowWorker.new(@swf.client, @domain, "TwoConfigTaskList", TwoConfigWorkflow)
617
252
  activity_worker = ActivityWorker.new(@swf.client, @domain, "TwoConfigTaskList", TwoConfigActivity) {{ :use_forking => false }}
618
- swf = AWS::SimpleWorkflow.new(access_key_id: "AWS_SWF_KEY", secret_access_key: "AWS_SWF_SECRET")
619
- activity_worker_different_config = ActivityWorker.new($swf_secondary.client, @domain, "other_config_task_list", TwoConfigActivity) {{ :use_forking => false }}
253
+ activity_worker_different_config = ActivityWorker.new(@swf.client, @domain, "other_config_task_list", TwoConfigActivity) {{ :use_forking => false }}
620
254
  my_workflow_client = workflow_client(@swf.client, @domain) {{:from_class => TwoConfigWorkflow}}
621
255
 
622
256
  worker.register
@@ -627,6 +261,7 @@ describe "RubyFlowDecider" do
627
261
  worker.run_once
628
262
  activity_worker_different_config.run_once
629
263
  worker.run_once
264
+ wait_for_execution(workflow_execution)
630
265
  workflow_execution.events.map(&:event_type).last == "WorkflowExecutionCompleted"
631
266
  end
632
267
 
@@ -637,7 +272,7 @@ describe "RubyFlowDecider" do
637
272
  @activity_class.class_eval do
638
273
  activity :run_activityManual do
639
274
  {
640
- :default_task_heartbeat_timeout => "3600",
275
+ :default_task_heartbeat_timeout => "600",
641
276
  :default_task_list => task_list,
642
277
  :default_task_schedule_to_start_timeout => 120,
643
278
  :default_task_start_to_close_timeout => 120,
@@ -667,9 +302,10 @@ describe "RubyFlowDecider" do
667
302
  @worker.run_once
668
303
  activity_worker.run_once
669
304
 
670
- $swf.client.respond_activity_task_failed(:task_token => $task_token)
305
+ @swf.client.respond_activity_task_failed(:task_token => $task_token)
671
306
 
672
307
  @worker.run_once
308
+ wait_for_execution(workflow_execution)
673
309
  workflow_execution.events.map(&:event_type).last.should == "WorkflowExecutionCompleted"
674
310
  end
675
311
 
@@ -687,19 +323,20 @@ describe "RubyFlowDecider" do
687
323
  end
688
324
  end
689
325
  @activity_class.class_eval do
690
- def run_activity1
691
- raise "Error!"
692
- end
326
+ def run_activity1; raise "Error!"; end
693
327
  end
328
+
329
+ @forking_executor = ForkingExecutor.new(:max_workers => 3)
330
+ @forking_executor.execute { @worker.start }
331
+ @forking_executor.execute { @activity_worker.start }
332
+ sleep 5
333
+
694
334
  workflow_execution = @my_workflow_client.start_execution
695
- @worker.run_once
696
- @activity_worker.run_once
697
- @worker.run_once
698
- @worker.run_once
699
- @activity_worker.run_once
700
- @worker.run_once
335
+
336
+ wait_for_execution(workflow_execution)
701
337
  workflow_execution.events.map(&:event_type).last.should == "WorkflowExecutionCompleted"
702
338
  workflow_execution.events.to_a[-1].attributes.result.should =~ /Error!/
339
+
703
340
  end
704
341
 
705
342
  it "ensures that backtraces are set correctly with yaml" do
@@ -724,6 +361,7 @@ describe "RubyFlowDecider" do
724
361
  @worker.run_once
725
362
  @activity_worker.run_once
726
363
  @worker.run_once
364
+ wait_for_execution(workflow_execution)
727
365
  workflow_execution.events.to_a[-1].attributes.result.should =~ /Error!/
728
366
  end
729
367
  describe "Handle_ tests" do
@@ -733,42 +371,49 @@ describe "RubyFlowDecider" do
733
371
  it "ensures that handle_child_workflow_execution_canceled is correct" do
734
372
  class OtherCancellationChildWorkflow
735
373
  extend Workflows
736
- workflow(:entry_point) { {:version => 1, :task_list => "new_child_cancelled_workflow", :execution_start_to_close_timeout => 3600} }
374
+ workflow(:entry_point) { {:version => 1, :task_list => "new_child_cancelled_workflow", :default_execution_start_to_close_timeout => 600} }
737
375
  def entry_point(arg)
738
- create_timer(5)
376
+ create_timer(20)
739
377
  end
740
378
  end
741
379
  class BadCancellationChildWorkflow
742
380
  extend Workflows
743
- workflow(:entry_point) { {:version => 1, :task_list => "new_parent_cancelled_workflow", :execution_start_to_close_timeout => 3600} }
381
+ workflow(:entry_point) { {:version => 1, :task_list => "new_parent_cancelled_workflow", :default_execution_start_to_close_timeout => 600} }
744
382
 
745
383
  def entry_point(arg)
746
- client = workflow_client($swf.client, $domain) { {:from_class => "OtherCancellationChildWorkflow"} }
384
+ domain = get_test_domain
385
+ client = workflow_client(domain.client, domain) { {:from_class => "OtherCancellationChildWorkflow"} }
747
386
  workflow_future = client.send_async(:start_execution, 5)
748
387
  client.request_cancel_workflow_execution(workflow_future)
749
388
  end
750
389
  end
751
- worker2 = WorkflowWorker.new(@swf.client, @domain, "new_child_cancelled_workflow", OtherCancellationChildWorkflow)
752
- worker2.register
753
- worker = WorkflowWorker.new(@swf.client, @domain, "new_parent_cancelled_workflow", BadCancellationChildWorkflow)
754
- worker.register
390
+ child_worker = WorkflowWorker.new(@swf.client, @domain, "new_child_cancelled_workflow", OtherCancellationChildWorkflow)
391
+ child_worker.register
392
+ parent_worker = WorkflowWorker.new(@swf.client, @domain, "new_parent_cancelled_workflow", BadCancellationChildWorkflow)
393
+ parent_worker.register
755
394
  client = workflow_client(@swf.client, @domain) { {:from_class => "BadCancellationChildWorkflow"} }
756
395
  workflow_execution = client.entry_point(5)
757
396
 
758
- worker.run_once
759
- worker2.run_once
760
- worker.run_once
397
+ parent_worker.run_once
398
+ child_worker.run_once
399
+ parent_worker.run_once
400
+
401
+ wait_for_decision(workflow_execution)
761
402
  workflow_execution.events.map(&:event_type).should include "ExternalWorkflowExecutionCancelRequested"
762
- worker2.run_once
403
+ child_worker.run_once
404
+
405
+ wait_for_decision(workflow_execution, "ChildWorkflowExecutionCanceled")
763
406
  workflow_execution.events.map(&:event_type).should include "ChildWorkflowExecutionCanceled"
764
- worker.run_once
407
+ parent_worker.run_once
408
+
409
+ wait_for_execution(workflow_execution)
765
410
  workflow_execution.events.to_a.last.attributes.details.should =~ /AWS::Flow::Core::Cancellation/
766
411
  end
767
412
 
768
413
  it "ensures that handle_child_workflow_terminated is handled correctly" do
769
414
  class OtherTerminationChildWorkflow
770
415
  extend Workflows
771
- workflow(:entry_point) { {:version => 1, :task_list => "new_child_terminated_workflow", :execution_start_to_close_timeout => 3600} }
416
+ workflow(:entry_point) { {:version => 1, :task_list => "new_child_terminated_workflow", :default_execution_start_to_close_timeout => 600} }
772
417
 
773
418
  def entry_point(arg)
774
419
  create_timer(5)
@@ -778,12 +423,13 @@ describe "RubyFlowDecider" do
778
423
  $workflow_id = nil
779
424
  class BadTerminationChildWorkflow
780
425
  extend Workflows
781
- workflow(:entry_point) { {:version => 1, :task_list => "new_parent_terminated_workflow", :execution_start_to_close_timeout => 3600} }
426
+ workflow(:entry_point) { {:version => 1, :task_list => "new_parent_terminated_workflow", :default_execution_start_to_close_timeout => 600} }
782
427
  def other_entry_point
783
428
  end
784
429
 
785
430
  def entry_point(arg)
786
- client = workflow_client($swf.client, $domain) { {:from_class => "OtherTerminationChildWorkflow"} }
431
+ domain = get_test_domain
432
+ client = workflow_client(domain.client, domain) { {:from_class => "OtherTerminationChildWorkflow"} }
787
433
  workflow_future = client.send_async(:start_execution, 5)
788
434
  $workflow_id = workflow_future.workflow_execution.workflow_id.get
789
435
  end
@@ -797,15 +443,19 @@ describe "RubyFlowDecider" do
797
443
 
798
444
  worker.run_once
799
445
  worker2.run_once
800
- $swf.client.terminate_workflow_execution({:workflow_id => $workflow_id, :domain => $domain.name})
446
+ wait_for_decision(workflow_execution)
447
+ @swf.client.terminate_workflow_execution({:workflow_id => $workflow_id, :domain => @domain.name})
448
+ wait_for_decision(workflow_execution, "ChildWorkflowExecutionTerminated")
801
449
  worker.run_once
450
+ wait_for_execution(workflow_execution)
451
+ validate_execution_failed(workflow_execution)
802
452
  workflow_execution.events.to_a.last.attributes.details.should =~ /AWS::Flow::ChildWorkflowTerminatedException/
803
453
  end
804
454
 
805
455
  it "ensures that handle_child_workflow_timed_out is handled correctly" do
806
456
  class OtherTimedOutChildWorkflow
807
457
  extend Workflows
808
- workflow(:entry_point) { {:version => 1, :task_list => "new_child_timed_out_workflow", :execution_start_to_close_timeout => 5} }
458
+ workflow(:entry_point) { {:version => 1, :task_list => "new_child_timed_out_workflow", :default_execution_start_to_close_timeout => 5} }
809
459
 
810
460
  def entry_point(arg)
811
461
  create_timer(5)
@@ -815,12 +465,13 @@ describe "RubyFlowDecider" do
815
465
  $workflow_id = nil
816
466
  class BadTimedOutChildWorkflow
817
467
  extend Workflows
818
- workflow(:entry_point) { {:version => 1, :task_list => "new_parent_timed_out_workflow", :execution_start_to_close_timeout => 3600} }
468
+ workflow(:entry_point) { {:version => 1, :task_list => "new_parent_timed_out_workflow", :default_execution_start_to_close_timeout => 600} }
819
469
  def other_entry_point
820
470
  end
821
471
 
822
472
  def entry_point(arg)
823
- client = workflow_client($swf.client, $domain) { {:from_class => "OtherTimedOutChildWorkflow"} }
473
+ domain = get_test_domain
474
+ client = workflow_client(domain.client, domain) { {:from_class => "OtherTimedOutChildWorkflow"} }
824
475
  workflow_future = client.send_async(:start_execution, 5)
825
476
  $workflow_id = workflow_future.workflow_execution.workflow_id.get
826
477
  end
@@ -834,6 +485,7 @@ describe "RubyFlowDecider" do
834
485
  worker.run_once
835
486
  sleep 8
836
487
  worker.run_once
488
+ wait_for_execution(workflow_execution)
837
489
  workflow_execution.events.to_a.last.attributes.details.should =~ /AWS::Flow::ChildWorkflowTimedOutException/
838
490
  end
839
491
 
@@ -843,9 +495,9 @@ describe "RubyFlowDecider" do
843
495
  extend Workflows
844
496
  workflow :bad_workflow do
845
497
  {
846
- :version => "1",
847
- :execution_start_to_close_timeout => 3600,
848
- :task_list => "handle_start_child_workflow_execution_failed_child"
498
+ version: "1.0",
499
+ default_execution_start_to_close_timeout: 600,
500
+ default_task_list: "handle_start_child_workflow_execution_failed_child"
849
501
  }
850
502
  end
851
503
  def bad_workflow
@@ -854,125 +506,129 @@ describe "RubyFlowDecider" do
854
506
  end
855
507
  @workflow_class.class_eval do
856
508
  def entry_point
857
- wf = AWS::Flow.workflow_client { { :prefix_name => "FooBar", :execution_method => 'bad_workflow', :version => "1", :execution_start_to_close_timeout => 3600, :task_list => "handle_start_child_workflow_execution_failed_child" } }
509
+ domain = get_test_domain
510
+ wf = AWS::Flow.workflow_client(domain.client, domain) { { from_class: "FooBar" } }
858
511
  wf.start_execution("foo")
859
512
  end
860
513
  end
861
514
  workflow_execution = @my_workflow_client.start_execution
862
- child_worker = WorkflowWorker.new($swf.client, $domain, "handle_start_child_workflow_execution_failed_child", FooBar)
515
+ child_worker = WorkflowWorker.new(@domain.client, @domain, "handle_start_child_workflow_execution_failed_child", FooBar)
863
516
  child_worker.register
864
517
  @worker.run_once
865
518
  child_worker.run_once
866
519
  @worker.run_once
520
+ wait_for_execution(workflow_execution)
867
521
  workflow_execution.events.map(&:event_type).last.should == "WorkflowExecutionFailed"
868
522
  # Make sure this is actually caused by a child workflow failed
869
523
  workflow_execution.events.to_a.last.attributes.details.should =~ /ChildWorkflowFailed/
870
524
  end
871
525
 
872
526
  it "ensures that handle_timer_canceled is fine" do
873
- general_test(:task_list => "handle_timer_canceled", :class_name => "HandleTimerCanceled")
874
- @workflow_class.class_eval do
875
- def entry_point
876
- bre = error_handler do |t|
877
- t.begin do
878
- create_timer(100)
879
- end
880
- t.rescue(CancellationException) {}
527
+ general_test(:task_list => "handle_timer_canceled", :class_name => "HandleTimerCanceled")
528
+ @workflow_class.class_eval do
529
+ def entry_point
530
+ bre = error_handler do |t|
531
+ t.begin do
532
+ create_timer(100)
881
533
  end
882
- create_timer(1)
883
- bre.cancel(CancellationException.new)
534
+ t.rescue(CancellationException) {}
884
535
  end
536
+ create_timer(1)
537
+ bre.cancel(CancellationException.new)
885
538
  end
886
- workflow_execution = @my_workflow_client.start_execution
887
- @worker.run_once
888
- @worker.run_once
889
- workflow_history = workflow_execution.events.map(&:event_type)
890
- workflow_history.count("TimerCanceled").should == 1
891
- workflow_history.count("WorkflowExecutionCompleted").should == 1
892
539
  end
540
+ workflow_execution = @my_workflow_client.start_execution
541
+ @worker.run_once
542
+ @worker.run_once
543
+ wait_for_execution(workflow_execution)
544
+ workflow_history = workflow_execution.events.map(&:event_type)
545
+ workflow_history.count("TimerCanceled").should == 1
546
+ workflow_history.count("WorkflowExecutionCompleted").should == 1
547
+ end
893
548
 
894
- it "ensures that activities under a bre get cancelled" do
895
- general_test(:task_list => "activite under bre", :class_name => "ActivitiesUnderBRE")
896
- @workflow_class.class_eval do
897
- def entry_point
898
- bre = error_handler do |t|
899
- t.begin { activity.send_async(:run_activity1) }
900
- end
901
- create_timer(1)
902
- bre.cancel(CancellationException.new)
549
+ it "ensures that activities under a bre get cancelled" do
550
+ general_test(:task_list => "activite under bre", :class_name => "ActivitiesUnderBRE")
551
+ @workflow_class.class_eval do
552
+ def entry_point
553
+ bre = error_handler do |t|
554
+ t.begin { activity.send_async(:run_activity1) }
903
555
  end
556
+ create_timer(1)
557
+ bre.cancel(CancellationException.new)
904
558
  end
905
- workflow_execution = @my_workflow_client.start_execution
906
- @worker.run_once
907
- @worker.run_once
908
- workflow_execution.events.map(&:event_type).count("ActivityTaskCancelRequested").should == 1
909
- @worker.run_once
910
- workflow_execution.events.to_a.last.attributes.reason.should == "AWS::Flow::Core::CancellationException"
911
559
  end
560
+ workflow_execution = @my_workflow_client.start_execution
561
+ @worker.run_once
562
+ @worker.run_once
563
+ workflow_execution.events.map(&:event_type).count("ActivityTaskCancelRequested").should == 1
564
+ @worker.run_once
565
+ wait_for_execution(workflow_execution)
566
+ workflow_execution.events.to_a.last.attributes.reason.should == "AWS::Flow::Core::CancellationException"
567
+ end
912
568
 
913
- it "ensures that start_timer_failed is handled correctly" do
914
- general_test(:task_list => "start_timer_failed", :class_name => "StartTimerFailed")
915
- end
569
+ it "ensures that start_timer_failed is handled correctly" do
570
+ general_test(:task_list => "start_timer_failed", :class_name => "StartTimerFailed")
571
+ end
916
572
 
917
- it "ensures that get_state_method works fine" do
918
- general_test(:task_list => "get_state_method", :class_name => "GetStateTest")
919
- @workflow_class.class_eval do
920
- get_state_method :get_state_test
921
- def get_state_test
922
- "This is the workflow state!"
923
- end
573
+ it "ensures that get_state_method works fine" do
574
+ general_test(:task_list => "get_state_method", :class_name => "GetStateTest")
575
+ @workflow_class.class_eval do
576
+ get_state_method :get_state_test
577
+ def get_state_test
578
+ "This is the workflow state!"
924
579
  end
925
- workflow_execution = @my_workflow_client.start_execution
926
- worker = WorkflowWorker.new(@swf.client, @domain, "get_state_method", @workflow_class)
927
- worker.run_once
928
- workflow_execution.events.to_a[3].attributes.execution_context.should =~ /This is the workflow state!/
929
- end
930
-
931
- it "ensures that handle_request_cancel_activity_task_failed works" do
932
- general_test(:task_list => "handle_request_cancel_activity_task_failed", :class_name => "HandleRCActivityTaskFailed")
933
- class AsyncDecider
934
- alias_method :old_handle_request_cancel_activity_task_failed, :handle_request_cancel_activity_task_failed
935
- # We have to replace this method, otherwise we'd fail on handling the
936
- # error because we can't find the decision in the decision_map. There
937
- # is similar behavior in javaflow
938
- def handle_request_cancel_activity_task_failed(event)
939
- event_double = SimpleTestHistoryEvent.new("Activity1")
940
- self.send(:old_handle_request_cancel_activity_task_failed, event_double)
941
- end
580
+ end
581
+ workflow_execution = @my_workflow_client.start_execution
582
+ worker = WorkflowWorker.new(@swf.client, @domain, "get_state_method", @workflow_class)
583
+ worker.run_once
584
+ workflow_execution.events.to_a[3].attributes.execution_context.should =~ /This is the workflow state!/
585
+ end
586
+
587
+ it "ensures that handle_request_cancel_activity_task_failed works" do
588
+ general_test(:task_list => "handle_request_cancel_activity_task_failed", :class_name => "HandleRCActivityTaskFailed")
589
+ class AsyncDecider
590
+ alias_method :old_handle_request_cancel_activity_task_failed, :handle_request_cancel_activity_task_failed
591
+ # We have to replace this method, otherwise we'd fail on handling the
592
+ # error because we can't find the decision in the decision_map. There
593
+ # is similar behavior in javaflow
594
+ def handle_request_cancel_activity_task_failed(event)
595
+ event_double = SimpleTestHistoryEvent.new("Activity1")
596
+ self.send(:old_handle_request_cancel_activity_task_failed, event_double)
942
597
  end
598
+ end
943
599
 
944
- class ActivityDecisionStateMachine
945
- alias_method :old_create_request_cancel_activity_task_decision, :create_request_cancel_activity_task_decision
946
- def create_request_cancel_activity_task_decision
947
- { :decision_type => "RequestCancelActivityTask",
948
- :request_cancel_activity_task_decision_attributes => {:activity_id => "bad_id"} }
949
- end
600
+ class ActivityDecisionStateMachine
601
+ alias_method :old_create_request_cancel_activity_task_decision, :create_request_cancel_activity_task_decision
602
+ def create_request_cancel_activity_task_decision
603
+ { :decision_type => "RequestCancelActivityTask",
604
+ :request_cancel_activity_task_decision_attributes => {:activity_id => "bad_id"} }
950
605
  end
606
+ end
951
607
 
952
- @workflow_class.class_eval do
953
- def entry_point
954
- future = activity.send_async(:run_activity1)
955
- create_timer(1)
956
- activity.request_cancel_activity_task(future)
957
- end
608
+ @workflow_class.class_eval do
609
+ def entry_point
610
+ future = activity.send_async(:run_activity1)
611
+ create_timer(1)
612
+ activity.request_cancel_activity_task(future)
958
613
  end
614
+ end
959
615
 
960
616
 
961
- workflow_execution = @my_workflow_client.start_execution
962
- @worker.run_once
963
- @worker.run_once
964
- @worker.run_once
617
+ workflow_execution = @my_workflow_client.start_execution
618
+ @worker.run_once
619
+ @worker.run_once
620
+ @worker.run_once
965
621
 
966
- # In the future, we might want to verify that it transitions the state
967
- # machine properly, but at a base, it should not fail the workflow.
968
- workflow_execution.events.map(&:event_type).last.should == "DecisionTaskCompleted"
969
- class AsyncDecider
970
- alias_method :handle_request_cancel_activity_task_failed, :old_handle_request_cancel_activity_task_failed
971
- end
972
- class ActivityDecisionStateMachine
973
- alias_method :create_request_cancel_activity_task_decision,:old_create_request_cancel_activity_task_decision
974
- end
622
+ # In the future, we might want to verify that it transitions the state
623
+ # machine properly, but at a base, it should not fail the workflow.
624
+ workflow_execution.events.map(&:event_type).last.should == "DecisionTaskCompleted"
625
+ class AsyncDecider
626
+ alias_method :handle_request_cancel_activity_task_failed, :old_handle_request_cancel_activity_task_failed
975
627
  end
628
+ class ActivityDecisionStateMachine
629
+ alias_method :create_request_cancel_activity_task_decision,:old_create_request_cancel_activity_task_decision
630
+ end
631
+ end
976
632
  end
977
633
 
978
634
 
@@ -1016,6 +672,7 @@ describe "RubyFlowDecider" do
1016
672
  @worker.run_once
1017
673
  @activity_worker.run_once
1018
674
  @worker.run_once
675
+ wait_for_execution(workflow_execution)
1019
676
  # TODO Kinda hacky, we should be using the workflow_class's data_converter
1020
677
  workflow_execution.events.to_a.last.attributes[:result].include? "false"
1021
678
  end
@@ -1038,21 +695,37 @@ describe "RubyFlowDecider" do
1038
695
 
1039
696
  end
1040
697
  end
698
+
699
+ @forking_executor = ForkingExecutor.new(:max_workers => 3)
700
+ @forking_executor.execute { @worker.start }
701
+ @forking_executor.execute { @activity_worker.start }
702
+
1041
703
  workflow_execution = @my_workflow_client.start_execution
1042
- @worker.run_once
1043
- @activity_worker.run_once
1044
- @worker.run_once
1045
- @worker.run_once
704
+
705
+ wait_for_execution(workflow_execution)
706
+
1046
707
  history = workflow_execution.events.map(&:event_type)
1047
708
  history.last.should == "WorkflowExecutionFailed"
1048
- # Should look something like: ["WorkflowExecutionStarted",
709
+
710
+ history.should include "ActivityTaskCancelRequested"
711
+ #@worker.run_once
712
+ #@activity_worker.run_once
713
+ #wait_for_decision(workflow_execution)
714
+ #@worker.run_once
715
+ #wait_for_decision(workflow_execution)
716
+ #@worker.run_once
717
+
718
+ #wait_for_execution(workflow_execution)
719
+ #history = workflow_execution.events.map(&:event_type)
720
+ #history.last.should == "WorkflowExecutionFailed"
721
+ ## Should look something like: ["WorkflowExecutionStarted",
1049
722
  # "DecisionTaskScheduled", "DecisionTaskStarted", "DecisionTaskCompleted",
1050
723
  # "ActivityTaskScheduled", "ActivityTaskScheduled", "ActivityTaskStarted",
1051
724
  # "ActivityTaskFailed", "DecisionTaskScheduled", "DecisionTaskStarted",
1052
725
  # "DecisionTaskCompleted", "ActivityTaskCancelRequested",
1053
726
  # "ActivityTaskCanceled", "DecisionTaskScheduled", "DecisionTaskStarted",
1054
727
  # "DecisionTaskCompleted", "WorkflowExecutionFailed"]
1055
- history.should include "ActivityTaskCancelRequested"
728
+ #history.should include "ActivityTaskCancelRequested"
1056
729
  end
1057
730
 
1058
731
  it "makes sure that you can use the :exponential_retry key" do
@@ -1069,6 +742,7 @@ describe "RubyFlowDecider" do
1069
742
  end
1070
743
  workflow_execution = @my_workflow_client.start_execution
1071
744
  4.times { @worker.run_once }
745
+ wait_for_execution(workflow_execution)
1072
746
  workflow_execution.events.to_a.last.event_type.should == "WorkflowExecutionFailed"
1073
747
  end
1074
748
 
@@ -1080,7 +754,7 @@ describe "RubyFlowDecider" do
1080
754
  logger.level = Logger::DEBUG
1081
755
  worker = WorkflowWorker.new(@swf.client, @domain, "arbitrary logger", @workflow_class) { {:logger => logger} }
1082
756
  activity_worker = ActivityWorker.new(@swf.client, @domain, "arbitrary logger", @activity_class) { { :logger => logger, :execution_workers => 20, :use_forking => false} }
1083
- execution = @my_workflow_client.start_execution
757
+ workflow_execution = @my_workflow_client.start_execution
1084
758
  worker.run_once
1085
759
  file = File.open(testing_file)
1086
760
  # The file should have something in it(i.e., not blank)
@@ -1097,9 +771,10 @@ describe "RubyFlowDecider" do
1097
771
  raise Exception
1098
772
  end
1099
773
  end
1100
- execution = @my_workflow_client.start_execution
774
+ workflow_execution = @my_workflow_client.start_execution
1101
775
  @worker.run_once
1102
- execution.events.map(&:event_type).last.should == "WorkflowExecutionFailed"
776
+ wait_for_execution(workflow_execution)
777
+ workflow_execution.events.map(&:event_type).last.should == "WorkflowExecutionFailed"
1103
778
  end
1104
779
  it "makes sure that the return value of an activity is directly useable" do
1105
780
  general_test(:task_list => "return value activity", :class_name => "ActivityReturn")
@@ -1114,7 +789,7 @@ describe "RubyFlowDecider" do
1114
789
  x.should == 5
1115
790
  end
1116
791
  end
1117
- execution = @my_workflow_client.start_execution
792
+ workflow_execution = @my_workflow_client.start_execution
1118
793
  @worker.run_once
1119
794
  @activity_worker.run_once
1120
795
  @worker.run_once
@@ -1126,87 +801,71 @@ describe "RubyFlowDecider" do
1126
801
  workflow_id
1127
802
  end
1128
803
  end
1129
- execution = @my_workflow_client.start_execution
804
+ workflow_execution = @my_workflow_client.start_execution
1130
805
  @worker.run_once
1131
- execution.events.map(&:event_type).last.should == "WorkflowExecutionCompleted"
806
+ wait_for_execution(workflow_execution)
807
+ workflow_execution.events.map(&:event_type).last.should == "WorkflowExecutionCompleted"
1132
808
  end
1133
809
  it "makes sure that arguments get passed correctly" do
1134
810
  task_list = "argument_task_list"
1135
- class ArgumentActivity
1136
- class << self; attr_accessor :task_list; end
1137
- end
1138
- class ArgumentWorkflow
811
+ class TaskListProvider
1139
812
  class << self; attr_accessor :task_list; end
1140
813
  end
814
+ TaskListProvider.task_list = task_list
1141
815
 
1142
- ArgumentActivity.task_list = task_list
1143
- ArgumentWorkflow.task_list = task_list
1144
- class ArgumentActivity
1145
- class << self
1146
- attr_accessor :task_list
1147
- end
1148
- extend Activity
1149
- activity :run_activity1 do |options|
1150
- options.default_task_heartbeat_timeout = "3600"
1151
- options.default_task_list = ArgumentActivity.task_list
1152
- options.default_task_schedule_to_close_timeout = "3600"
1153
- options.default_task_schedule_to_start_timeout = "3600"
1154
- options.default_task_start_to_close_timeout = "3600"
1155
- options.version = "1"
816
+ class ArgumentActivity < TaskListProvider
817
+ extend AWS::Flow::Activities
818
+ activity :run_activity1 do
819
+ {
820
+ version: "1.0",
821
+ default_task_list: self.task_list,
822
+ default_task_schedule_to_close_timeout: "120",
823
+ default_task_schedule_to_start_timeout: "60",
824
+ default_task_start_to_close_timeout: "60"
825
+ }
1156
826
  end
827
+
1157
828
  def run_activity1(arg)
1158
829
  arg.should == 5
1159
830
  arg + 1
1160
831
  end
1161
832
  end
1162
- class ArgumentWorkflow
1163
- class << self
1164
- attr_accessor :task_list, :entry_point_to_call
1165
- end
1166
- extend Decider
1167
- version "1"
1168
- entry_point :entry_point
1169
- activity_client :activity do |options|
1170
- options.prefix_name = "ArgumentActivity"
1171
- options.default_task_heartbeat_timeout = "3600"
1172
- options.default_task_list = ArgumentWorkflow.task_list
1173
- options.default_task_schedule_to_close_timeout = "3600"
1174
- options.default_task_schedule_to_start_timeout = "3600"
1175
- options.default_task_start_to_close_timeout = "3600"
1176
-
833
+ class ArgumentWorkflow < TaskListProvider
834
+ extend AWS::Flow::Workflows
835
+ workflow :entry_point do
836
+ {
837
+ version: "1.0",
838
+ default_execution_start_to_close_timeout: 600,
839
+ default_task_list: self.task_list,
840
+ default_task_start_to_close_timeout: 10,
841
+ default_child_policy: :request_cancel,
842
+ }
1177
843
  end
844
+ activity_client(:activity) { { from_class: "ArgumentActivity" } }
1178
845
  def entry_point(arg)
1179
846
  arg.should == 5
1180
847
  activity.run_activity1(arg)
1181
848
  end
1182
849
  end
1183
850
 
1184
- worker = WorkflowWorker.new(@swf.client, @domain, task_list)
1185
- worker.add_workflow_implementation(ArgumentWorkflow)
1186
- activity_worker = ActivityWorker.new(@swf.client, @domain, task_list)
1187
- activity_worker.add_activities_implementation(ArgumentActivity)
851
+ worker = WorkflowWorker.new(@domain.client, @domain, task_list, ArgumentWorkflow)
852
+ activity_worker = ActivityWorker.new(@domain.client, @domain, task_list, ArgumentActivity)
1188
853
  worker.register
1189
854
  activity_worker.register
1190
- my_workflow_factory = workflow_factory(@swf.client, @domain) do |options|
1191
- options.workflow_name = "ArgumentWorkflow"
1192
- options.execution_start_to_close_timeout = 3600
1193
- options.task_list = "argument_task_list"
1194
- options.task_start_to_close_timeout = 10
1195
- options.child_policy = :request_cancel
1196
- end
1197
- my_workflow = my_workflow_factory.get_client
1198
- workflow_execution = my_workflow.start_execution(5)
855
+ client = AWS::Flow::workflow_client(@domain.client, @domain) { { from_class: "ArgumentWorkflow" } }
856
+
857
+ workflow_execution = client.start_execution(5)
1199
858
  @forking_executor = ForkingExecutor.new(:max_workers => 3)
1200
859
  @forking_executor.execute { worker.start }
1201
- sleep 4
1202
860
  @forking_executor.execute { activity_worker.start }
1203
861
 
1204
- sleep 9
862
+ wait_for_execution(workflow_execution)
1205
863
  workflow_execution.events.map(&:event_type).should ==
1206
864
  ["WorkflowExecutionStarted", "DecisionTaskScheduled", "DecisionTaskStarted", "DecisionTaskCompleted", "ActivityTaskScheduled", "ActivityTaskStarted", "ActivityTaskCompleted", "DecisionTaskScheduled", "DecisionTaskStarted", "DecisionTaskCompleted", "WorkflowExecutionCompleted"]
1207
865
  workflow_execution.events.to_a.last.attributes[:result].should =~ /6/
1208
866
  @forking_executor.shutdown(1)
1209
867
  end
868
+
1210
869
  it "makes sure that a standard error works" do
1211
870
  general_test(:task_list => "regular error raise", :class_name => "StandardError")
1212
871
  @workflow_class.class_eval do
@@ -1225,6 +884,7 @@ describe "RubyFlowDecider" do
1225
884
  @worker.run_once
1226
885
  @activity_worker.run_once
1227
886
  @worker.run_once
887
+ wait_for_execution(workflow_execution)
1228
888
 
1229
889
  workflow_execution.events.map(&:event_type).count("WorkflowExecutionFailed").should == 1
1230
890
  end
@@ -1234,7 +894,7 @@ describe "RubyFlowDecider" do
1234
894
  general_test(:task_list => "exceptions_to_include", :class_name => "ExceptionsToInclude")
1235
895
  @workflow_class.class_eval do
1236
896
  def entry_point
1237
- activity.exponential_retry(:run_activity1) { {:exceptions_to_exclude => [SecurityError] } }
897
+ activity.exponential_retry(:run_activity1) { {:exceptions_to_exclude => [SecurityError] } }
1238
898
  end
1239
899
  end
1240
900
  @activity_class.class_eval do
@@ -1246,6 +906,7 @@ describe "RubyFlowDecider" do
1246
906
  @worker.run_once
1247
907
  @activity_worker.run_once
1248
908
  @worker.run_once
909
+ wait_for_execution(workflow_execution)
1249
910
  workflow_execution.events.map(&:event_type).last.should == "WorkflowExecutionFailed"
1250
911
  end
1251
912
  class YAMLPlusOne
@@ -1265,7 +926,7 @@ describe "RubyFlowDecider" do
1265
926
  :data_converter => YAMLPlusOne.new,
1266
927
  :default_task_list => "different converter activity",
1267
928
  :version => "1",
1268
- :default_task_heartbeat_timeout => "3600",
929
+ :default_task_heartbeat_timeout => "600",
1269
930
  :default_task_schedule_to_close_timeout => "60",
1270
931
  :default_task_schedule_to_start_timeout => "60",
1271
932
  :default_task_start_to_close_timeout => "60",
@@ -1278,7 +939,7 @@ describe "RubyFlowDecider" do
1278
939
  activity_worker = ActivityWorker.new(@swf.client, @domain,"different converter activity", DifferentActivityConverterActivity)
1279
940
  class DifferentActivityConverterWorkflow
1280
941
  extend Workflows
1281
- workflow(:entry_point) { {:version => "1", :execution_start_to_close_timeout => 3600, :task_list => "different converter activity"} }
942
+ workflow(:entry_point) { {:version => "1", :default_execution_start_to_close_timeout => 600, :task_list => "different converter activity"} }
1282
943
  activity_client(:activity) { { :from_class => DifferentActivityConverterActivity } }
1283
944
  def entry_point
1284
945
  activity.test_converter
@@ -1307,9 +968,8 @@ describe "RubyFlowDecider" do
1307
968
  workflow_execution = @my_workflow_client.start_execution
1308
969
  @forking_executor = ForkingExecutor.new(:max_workers => 3)
1309
970
  @forking_executor.execute { @worker.start }
1310
- sleep 10
1311
971
  @forking_executor.execute { @activity_worker.start }
1312
- sleep 30
972
+ wait_for_execution(workflow_execution)
1313
973
  workflow_execution.events.map(&:event_type).should ==
1314
974
  ["WorkflowExecutionStarted", "DecisionTaskScheduled", "DecisionTaskStarted", "DecisionTaskCompleted", "TimerStarted", "TimerFired", "DecisionTaskScheduled", "DecisionTaskStarted", "DecisionTaskCompleted", "ActivityTaskScheduled", "ActivityTaskStarted", "ActivityTaskCompleted", "DecisionTaskScheduled", "DecisionTaskStarted", "DecisionTaskCompleted", "WorkflowExecutionCompleted"]
1315
975
  @forking_executor.shutdown(1)
@@ -1326,9 +986,8 @@ describe "RubyFlowDecider" do
1326
986
  workflow_execution = @my_workflow_client.start_execution
1327
987
  @forking_executor = ForkingExecutor.new(:max_workers => 3)
1328
988
  @forking_executor.execute { @worker.start }
1329
- sleep 10
1330
989
  @forking_executor.execute { @activity_worker.start }
1331
- sleep 30
990
+ wait_for_execution(workflow_execution)
1332
991
  @forking_executor.shutdown(1)
1333
992
  workflow_execution.events.map(&:event_type).should ==
1334
993
  ["WorkflowExecutionStarted", "DecisionTaskScheduled", "DecisionTaskStarted", "DecisionTaskCompleted", "TimerStarted", "TimerFired", "DecisionTaskScheduled", "DecisionTaskStarted", "DecisionTaskCompleted", "ActivityTaskScheduled", "ActivityTaskStarted", "ActivityTaskCompleted", "DecisionTaskScheduled", "DecisionTaskStarted", "DecisionTaskCompleted", "WorkflowExecutionCompleted"]
@@ -1345,10 +1004,10 @@ describe "RubyFlowDecider" do
1345
1004
  workflow_execution = @my_workflow_client.start_execution
1346
1005
  @forking_executor = ForkingExecutor.new(:max_workers => 3)
1347
1006
  @forking_executor.execute { @worker.start }
1348
- sleep 5
1349
1007
  @forking_executor.execute { @activity_worker.start }
1350
1008
 
1351
- sleep 15
1009
+ wait_for_execution(workflow_execution)
1010
+
1352
1011
  @forking_executor.shutdown(1)
1353
1012
  after_first_decision = workflow_execution.events.to_a.slice(4, 2).map(&:event_type)
1354
1013
  after_first_decision.should include "TimerStarted"
@@ -1364,15 +1023,14 @@ describe "RubyFlowDecider" do
1364
1023
  end
1365
1024
  @activity_worker = ActivityWorker.new(@swf.client, @domain, "async timer with block", AsyncBlockActivity)
1366
1025
  @activity_worker.register
1367
- @workflow_execution = @my_workflow_client.start_execution
1026
+ workflow_execution = @my_workflow_client.start_execution
1368
1027
  @forking_executor = ForkingExecutor.new(:max_workers => 3)
1369
1028
  @forking_executor.execute { @worker.start }
1370
- sleep 5
1371
1029
  @forking_executor.execute { @activity_worker.start }
1372
- sleep 15
1030
+ wait_for_execution(workflow_execution)
1373
1031
  @forking_executor.shutdown(1)
1374
- activity_scheduled = @workflow_execution.events.to_a.each_with_index.map{|x, i| i if x.event_type == "ActivityTaskScheduled"}.compact
1375
- history_events = @workflow_execution.events.to_a
1032
+ activity_scheduled = workflow_execution.events.to_a.each_with_index.map{|x, i| i if x.event_type == "ActivityTaskScheduled"}.compact
1033
+ history_events = workflow_execution.events.to_a
1376
1034
  history_events[activity_scheduled.first - 1].event_type == "TimerStarted" ||
1377
1035
  history_events[activity_scheduled.first + 1].event_type == "TimerStarted"
1378
1036
  history_events[activity_scheduled.first].attributes[:activity_type].name.should == "AsyncBlockActivity.run_activity2"
@@ -1381,215 +1039,202 @@ describe "RubyFlowDecider" do
1381
1039
 
1382
1040
  describe "Child Workflows" do
1383
1041
 
1384
- it "is a basic child workflow test" do
1385
- class OtherChildWorkflow
1386
- extend Decider
1387
- version "1"
1388
- entry_point :entry_point
1389
- def entry_point(arg)
1390
- sleep 1
1391
- end
1042
+ it "is a basic child workflow test" do
1392
1043
 
1393
- end
1394
- class BadChildWorkflow
1395
- extend Decider
1396
- version "1"
1397
- def other_entry_point
1398
- end
1399
- entry_point :entry_point
1400
- def entry_point(arg)
1401
- client = workflow_client do |options|
1402
- options.workflow_name = "OtherChildWorkflow"
1403
- options.execution_method = "entry_point"
1404
- options.execution_start_to_close_timeout = 3600
1405
- options.task_start_to_close_timeout = 10
1406
- options.version = "1"
1407
- options.task_list = "test2"
1044
+ class ChildWorkflowsTestChildWorkflow
1045
+ extend AWS::Flow::Workflows
1046
+ workflow :child do
1047
+ {
1048
+ version: "1.0",
1049
+ default_execution_start_to_close_timeout: 600,
1050
+ default_task_start_to_close_timeout: 10,
1051
+ }
1408
1052
  end
1409
-
1410
- client.send_async(:start_execution, 5)
1411
- client.send_async(:start_execution, 5)
1053
+ def child; sleep 1; end
1412
1054
  end
1413
- end
1414
- my_workflow_factory = workflow_factory @swf.client, @domain do |options|
1415
- options.workflow_name = "BadChildWorkflow"
1416
- options.execution_start_to_close_timeout = 3600
1417
- options.task_list = "test"
1418
- options.version = "1"
1419
- end
1420
- worker2 = WorkflowWorker.new(@swf.client, @domain, "test2")
1421
- worker2.add_workflow_implementation(OtherChildWorkflow)
1422
- worker2.register
1423
- worker = WorkflowWorker.new(@swf.client, @domain, "test")
1424
- worker.add_workflow_implementation(BadChildWorkflow)
1425
- worker.register
1426
- sleep 5
1427
- my_workflow_client = my_workflow_factory.get_client
1428
- workflow_execution = my_workflow_client.entry_point(5)
1429
- # sleep 10
1430
1055
 
1431
- # Start, start off the child workflow
1432
- worker.run_once
1056
+ class ChildWorkflowsTestParentWorkflow
1057
+ extend AWS::Flow::Workflows
1058
+ workflow :parent do
1059
+ {
1060
+ version: "1.0",
1061
+ default_execution_start_to_close_timeout: 600,
1062
+ default_task_list: "test"
1063
+ }
1064
+ end
1065
+ def parent
1066
+ domain = get_test_domain
1067
+ client = AWS::Flow::workflow_client(domain.client, domain) { { from_class: "ChildWorkflowsTestChildWorkflow", task_list: "test2" } }
1068
+ client.send_async(:start_execution)
1069
+ client.send_async(:start_execution)
1070
+ end
1071
+ end
1433
1072
 
1434
- # Run Both child workflows
1435
- worker2.run_once
1436
- worker2.run_once
1437
- worker.run_once
1438
- # Appears to a case that happens sometimes where the history looks like
1439
- # ["WorkflowExecutionStarted", "DecisionTaskScheduled", "DecisionTaskStarted", "DecisionTaskCompleted", "StartChildWorkflowExecutionInitiated", "StartChildWorkflowExecutionInitiated", "ChildWorkflowExecutionStarted", "DecisionTaskScheduled", "ChildWorkflowExecutionStarted", "ChildWorkflowExecutionCompleted", "DecisionTaskStarted", "ChildWorkflowExecutionCompleted", "DecisionTaskScheduled", "DecisionTaskCompleted"]
1440
- # In order to deal with this, we have the following line below
1441
- worker.run_once if workflow_execution.events.map(&:event_type).last == "DecisionTaskCompleted"
1442
- events = workflow_execution.events.map(&:event_type)
1443
- workflow_execution.events.to_a.last.attributes.result.should_not =~ /secret_access_key/
1444
- events.should include "ChildWorkflowExecutionStarted"
1445
- events.should include "ChildWorkflowExecutionCompleted"
1446
- events.should include "WorkflowExecutionCompleted"
1447
- end
1073
+ parent_client = AWS::Flow::workflow_client(@domain.client, @domain) { { from_class: "ChildWorkflowsTestParentWorkflow" } }
1074
+ @child_worker = WorkflowWorker.new(@domain.client, @domain, "test2", ChildWorkflowsTestChildWorkflow)
1075
+ @parent_worker = WorkflowWorker.new(@domain.client, @domain, "test", ChildWorkflowsTestParentWorkflow)
1448
1076
 
1449
- it "ensures that workflow clock provides at least basic support for current_time_millis" do
1450
- general_test(:task_list => "workflow_clock_basic", :class_name => "WorkflowClockBasic")
1077
+ @forking_executor = ForkingExecutor.new(:max_workers => 3)
1078
+ @forking_executor.execute { @parent_worker.start }
1079
+ @forking_executor.execute { @child_worker.start }
1080
+ @forking_executor.execute { @child_worker.start }
1081
+ sleep 2
1451
1082
 
1452
- @workflow_class.class_eval do
1453
- class << self
1454
- attr_accessor :time_hash, :replaying_hash
1455
- end
1456
- def entry_point
1457
- def record_point(name)
1458
- self.class.replaying_hash[name] << decision_context.workflow_clock.replaying
1459
- self.class.time_hash[name] << decision_context.workflow_clock.current_time
1460
- end
1461
- record_point(:first)
1462
- create_timer(5)
1463
- record_point(:second)
1464
- create_timer(3)
1465
- record_point(:third)
1466
- end
1467
- end
1468
- @workflow_class.time_hash = Hash.new {|hash, key| hash[key] = []}
1469
- @workflow_class.replaying_hash = Hash.new {|hash, key| hash[key] = []}
1470
- workflow_execution = @my_workflow_client.start_execution
1471
- 3.times { @worker.run_once }
1472
- # Maintain the invariant that you should *not* be replaying only once
1473
- @workflow_class.replaying_hash.values.each {|x| x.count(false).should be 1}
1474
- # Maintain the invariant that at the same point in the code,
1475
- # replay_current_time_millis will return the same value
1476
- @workflow_class.time_hash.values.each do |array|
1477
- array.reduce {|first, second| first if first.should == second}
1083
+ workflow_execution = parent_client.start_execution
1084
+ wait_for_execution(workflow_execution)
1085
+
1086
+ events = workflow_execution.events.map(&:event_type)
1087
+ workflow_execution.events.to_a.last.attributes.result.should_not =~ /secret_access_key/
1088
+ events.should include("ChildWorkflowExecutionStarted", "ChildWorkflowExecutionCompleted", "WorkflowExecutionCompleted")
1478
1089
  end
1479
- end
1480
1090
 
1481
- it "ensures that a child workflow failing raises a ChildWorkflowExecutionFailed" do
1482
- class FailingChildChildWorkflow
1483
- extend Workflows
1484
- workflow(:entry_point) { {:version => 1, :task_list => "failing_child_workflow", :execution_start_to_close_timeout => 3600} }
1485
- def entry_point(arg)
1486
- raise "simulated error"
1091
+ it "ensures that workflow clock provides at least basic support for current_time_millis" do
1092
+ general_test(:task_list => "workflow_clock_basic", :class_name => "WorkflowClockBasic")
1093
+
1094
+ @workflow_class.class_eval do
1095
+ class << self
1096
+ attr_accessor :time_hash, :replaying_hash
1097
+ end
1098
+ def entry_point
1099
+ def record_point(name)
1100
+ self.class.replaying_hash[name] << decision_context.workflow_clock.replaying
1101
+ self.class.time_hash[name] << decision_context.workflow_clock.current_time
1102
+ end
1103
+ record_point(:first)
1104
+ create_timer(5)
1105
+ record_point(:second)
1106
+ create_timer(3)
1107
+ record_point(:third)
1108
+ end
1487
1109
  end
1488
- end
1489
- class FailingHostChildWorkflow
1490
- extend Workflows
1491
- workflow(:entry_point) { {:version => 1, :task_list => "failing_parent_workflow", :execution_start_to_close_timeout => 3600} }
1492
- def other_entry_point
1110
+ @workflow_class.time_hash = Hash.new {|hash, key| hash[key] = []}
1111
+ @workflow_class.replaying_hash = Hash.new {|hash, key| hash[key] = []}
1112
+ workflow_execution = @my_workflow_client.start_execution
1113
+ 3.times { @worker.run_once }
1114
+ # Maintain the invariant that you should *not* be replaying only once
1115
+ @workflow_class.replaying_hash.values.each {|x| x.count(false).should be 1}
1116
+ # Maintain the invariant that at the same point in the code,
1117
+ # replay_current_time_millis will return the same value
1118
+ @workflow_class.time_hash.values.each do |array|
1119
+ array.reduce {|first, second| first if first.should == second}
1120
+ end
1121
+ end
1122
+
1123
+ it "ensures that a child workflow failing raises a ChildWorkflowExecutionFailed" do
1124
+ class FailingChildChildWorkflow
1125
+ extend Workflows
1126
+ workflow(:entry_point) { {:version => 1, :task_list => "failing_child_workflow", :default_execution_start_to_close_timeout => 600} }
1127
+ def entry_point(arg)
1128
+ raise "simulated error"
1129
+ end
1493
1130
  end
1131
+ class FailingHostChildWorkflow
1132
+ extend Workflows
1133
+ workflow(:entry_point) { {:version => 1, :task_list => "failing_parent_workflow", :default_execution_start_to_close_timeout => 600} }
1134
+ def other_entry_point
1135
+ end
1494
1136
 
1495
- def entry_point(arg)
1496
- client = workflow_client($swf.client, $domain) { {:from_class => "FailingChildChildWorkflow"} }
1497
- begin
1498
- client.start_execution(5)
1499
- rescue Exception => e
1500
- #pass
1137
+ def entry_point(arg)
1138
+ domain = get_test_domain
1139
+ client = workflow_client(domain.client, domain) { {:from_class => "FailingChildChildWorkflow"} }
1140
+ begin
1141
+ client.start_execution(5)
1142
+ rescue Exception => e
1143
+ #pass
1144
+ end
1501
1145
  end
1502
1146
  end
1147
+ worker2 = WorkflowWorker.new(@swf.client, @domain, "failing_child_workflow", FailingChildChildWorkflow)
1148
+ worker2.register
1149
+ worker = WorkflowWorker.new(@swf.client, @domain, "failing_parent_workflow", FailingHostChildWorkflow)
1150
+ worker.register
1151
+ client = workflow_client(@swf.client, @domain) { {:from_class => "FailingHostChildWorkflow"} }
1152
+ workflow_execution = client.entry_point(5)
1153
+ worker.run_once
1154
+ worker2.run_once
1155
+ worker2.run_once
1156
+ worker.run_once
1157
+ events = workflow_execution.events.map(&:event_type)
1158
+ events.should include "ChildWorkflowExecutionFailed"
1159
+ events.should include "WorkflowExecutionCompleted"
1503
1160
  end
1504
- worker2 = WorkflowWorker.new(@swf.client, @domain, "failing_child_workflow", FailingChildChildWorkflow)
1505
- worker2.register
1506
- worker = WorkflowWorker.new(@swf.client, @domain, "failing_parent_workflow", FailingHostChildWorkflow)
1507
- worker.register
1508
- client = workflow_client(@swf.client, @domain) { {:from_class => "FailingHostChildWorkflow"} }
1509
- workflow_execution = client.entry_point(5)
1510
- worker.run_once
1511
- worker2.run_once
1512
- worker2.run_once
1513
- worker.run_once
1514
- events = workflow_execution.events.map(&:event_type)
1515
- events.should include "ChildWorkflowExecutionFailed"
1516
- events.should include "WorkflowExecutionCompleted"
1517
- end
1518
1161
 
1519
- it "ensures that a child workflow can use data_converter correctly" do
1520
- class DataConverterChildChildWorkflow
1521
- extend Workflows
1522
- workflow(:entry_point) { {:version => 1, :task_list => "data_converter_child_workflow", :execution_start_to_close_timeout => 3600, :data_converter => YAMLPlusOne.new} }
1523
- def entry_point(arg)
1524
- return arg + 1
1525
- end
1526
- end
1527
- class DataConverterHostChildWorkflow
1528
- extend Workflows
1529
- workflow(:entry_point) { {:version => 1, :task_list => "data_converter_parent_workflow", :execution_start_to_close_timeout => 3600} }
1530
- def other_entry_point
1162
+ it "ensures that a child workflow can use data_converter correctly" do
1163
+ class DataConverterChildChildWorkflow
1164
+ extend Workflows
1165
+ workflow(:entry_point) { {:version => 1, :task_list => "data_converter_child_workflow", :default_execution_start_to_close_timeout => 600, :data_converter => YAMLPlusOne.new} }
1166
+ def entry_point(arg)
1167
+ return arg + 1
1168
+ end
1531
1169
  end
1170
+ class DataConverterHostChildWorkflow
1171
+ extend Workflows
1172
+ workflow(:entry_point) { {:version => 1, :task_list => "data_converter_parent_workflow", :default_execution_start_to_close_timeout => 600} }
1173
+ def other_entry_point
1174
+ end
1532
1175
 
1533
- def entry_point(arg)
1534
- client = workflow_client($swf.client, $domain) { {:from_class => "DataConverterChildChildWorkflow"} }
1535
- task { client.start_execution(5) }
1176
+ def entry_point(arg)
1177
+ domain = get_test_domain
1178
+ client = workflow_client(domain.client, domain) { {:from_class => "DataConverterChildChildWorkflow"} }
1179
+ task { client.start_execution(5) }
1180
+ end
1536
1181
  end
1537
- end
1538
- worker2 = WorkflowWorker.new(@swf.client, @domain, "data_converter_child_workflow", DataConverterChildChildWorkflow)
1539
- worker2.register
1540
- worker = WorkflowWorker.new(@swf.client, @domain, "data_converter_parent_workflow", DataConverterHostChildWorkflow)
1541
- worker.register
1182
+ worker2 = WorkflowWorker.new(@swf.client, @domain, "data_converter_child_workflow", DataConverterChildChildWorkflow)
1183
+ worker2.register
1184
+ worker = WorkflowWorker.new(@swf.client, @domain, "data_converter_parent_workflow", DataConverterHostChildWorkflow)
1185
+ worker.register
1542
1186
 
1543
- client = workflow_client(@swf.client, @domain) { {:from_class => "DataConverterHostChildWorkflow"} }
1544
- workflow_execution = client.entry_point(5)
1545
- worker.run_once
1546
- worker2.run_once
1547
- worker.run_once
1548
- # We have to find the index dynamically, because due to how scheduled/starts work, it isn't necessarily in the same place in our history.
1549
- child_execution_completed_index = workflow_execution.events.map(&:event_type).index("ChildWorkflowExecutionCompleted")
1187
+ client = workflow_client(@swf.client, @domain) { {:from_class => "DataConverterHostChildWorkflow"} }
1188
+ workflow_execution = client.entry_point(5)
1189
+ worker.run_once
1190
+ worker2.run_once
1191
+ worker.run_once
1192
+ # We have to find the index dynamically, because due to how scheduled/starts work, it isn't necessarily in the same place in our history.
1193
+ child_execution_completed_index = workflow_execution.events.map(&:event_type).index("ChildWorkflowExecutionCompleted")
1550
1194
 
1551
- workflow_execution.events.to_a[child_execution_completed_index].attributes.result.should =~ /1\z/
1552
- end
1195
+ workflow_execution.events.to_a[child_execution_completed_index].attributes.result.should =~ /1\z/
1196
+ end
1553
1197
 
1554
- it "makes sure that the new way of doing child workflows works" do
1555
- class OtherNewChildWorkflow
1556
- extend Workflows
1557
- workflow(:entry_point) { {:version => 1, :task_list => "new_child_workflow", :execution_start_to_close_timeout => 3600} }
1558
- def entry_point(arg)
1559
- sleep 2
1560
- end
1198
+ it "makes sure that the new way of doing child workflows works" do
1199
+ class OtherNewChildWorkflow
1200
+ extend Workflows
1201
+ workflow(:entry_point) { {:version => 1, :task_list => "new_child_workflow", :default_execution_start_to_close_timeout => 600} }
1202
+ def entry_point(arg)
1203
+ sleep 2
1204
+ end
1561
1205
 
1562
- end
1563
- class BadNewChildWorkflow
1564
- extend Workflows
1565
- workflow(:entry_point) { {:version => 1, :task_list => "new_parent_workflow", :execution_start_to_close_timeout => 3600} }
1566
- def other_entry_point
1567
1206
  end
1207
+ class BadNewChildWorkflow
1208
+ extend Workflows
1209
+ workflow(:entry_point) { {:version => 1, :task_list => "new_parent_workflow", :default_execution_start_to_close_timeout => 600} }
1210
+ def other_entry_point
1211
+ end
1568
1212
 
1569
- def entry_point(arg)
1570
- client = workflow_client($swf.client, $domain) { {:from_class => "OtherNewChildWorkflow"} }
1571
- task { client.start_execution(5) }
1572
- task { client.start_execution(5) }
1213
+ def entry_point(arg)
1214
+ domain = get_test_domain
1215
+ client = workflow_client(domain.client, domain) { {:from_class => "OtherNewChildWorkflow"} }
1216
+ task { client.start_execution(5) }
1217
+ task { client.start_execution(5) }
1218
+ end
1573
1219
  end
1220
+ worker2 = WorkflowWorker.new(@swf.client, @domain, "new_child_workflow", OtherNewChildWorkflow)
1221
+ worker2.register
1222
+ worker = WorkflowWorker.new(@swf.client, @domain, "new_parent_workflow", BadNewChildWorkflow)
1223
+ worker.register
1224
+ client = workflow_client(@swf.client, @domain) { {:from_class => "BadNewChildWorkflow"} }
1225
+ workflow_execution = client.entry_point(5)
1226
+ worker.run_once
1227
+ worker2.run_once
1228
+ worker2.run_once
1229
+ worker.run_once
1230
+ worker.run_once if workflow_execution.events.map(&:event_type).last == "DecisionTaskCompleted"
1231
+ events = workflow_execution.events.map(&:event_type)
1232
+ events.should include "ChildWorkflowExecutionStarted"
1233
+ events.should include "ChildWorkflowExecutionCompleted"
1234
+ events.should include "WorkflowExecutionCompleted"
1574
1235
  end
1575
- worker2 = WorkflowWorker.new(@swf.client, @domain, "new_child_workflow", OtherNewChildWorkflow)
1576
- worker2.register
1577
- worker = WorkflowWorker.new(@swf.client, @domain, "new_parent_workflow", BadNewChildWorkflow)
1578
- worker.register
1579
- client = workflow_client(@swf.client, @domain) { {:from_class => "BadNewChildWorkflow"} }
1580
- workflow_execution = client.entry_point(5)
1581
- worker.run_once
1582
- worker2.run_once
1583
- worker2.run_once
1584
- worker.run_once
1585
- worker.run_once if workflow_execution.events.map(&:event_type).last == "DecisionTaskCompleted"
1586
- events = workflow_execution.events.map(&:event_type)
1587
- events.should include "ChildWorkflowExecutionStarted"
1588
- events.should include "ChildWorkflowExecutionCompleted"
1589
- events.should include "WorkflowExecutionCompleted"
1590
1236
  end
1591
- end
1592
- it "makes sure that you can use retries_per_exception" do
1237
+ it "makes sure that you can use retries_per_exception" do
1593
1238
  general_test(:task_list => "retries_per_exception", :class_name => "RetriesPerException")
1594
1239
  @activity_class.class_eval do
1595
1240
  def run_activity1
@@ -1598,7 +1243,7 @@ describe "RubyFlowDecider" do
1598
1243
  end
1599
1244
  @workflow_class.class_eval do
1600
1245
  activity_client :activity do |options|
1601
- options.default_task_heartbeat_timeout = "3600"
1246
+ options.default_task_heartbeat_timeout = "600"
1602
1247
  options.default_task_list = self.task_list
1603
1248
  options.default_task_schedule_to_close_timeout = "5"
1604
1249
  options.default_task_schedule_to_start_timeout = "5"
@@ -1629,6 +1274,7 @@ describe "RubyFlowDecider" do
1629
1274
 
1630
1275
  @worker.run_once
1631
1276
 
1277
+ wait_for_execution(workflow_execution)
1632
1278
  workflow_history = workflow_execution.events.map(&:event_type)
1633
1279
  workflow_history.count("ActivityTaskFailed").should == 3
1634
1280
 
@@ -1641,7 +1287,7 @@ describe "RubyFlowDecider" do
1641
1287
  def entry_point
1642
1288
  create_timer(5) do
1643
1289
  continue_as_new do |options|
1644
- options.execution_start_to_close_timeout = 3600
1290
+ options.execution_start_to_close_timeout = 600
1645
1291
  options.task_list = "continue_as_new_timer"
1646
1292
  options.tag_list = []
1647
1293
  options.version = "1"
@@ -1677,7 +1323,7 @@ describe "RubyFlowDecider" do
1677
1323
  continue_as_new do |options|
1678
1324
  options.workflow_name = @workflow_class.to_s
1679
1325
  options.execution_method = :entry_point
1680
- options.execution_start_to_close_timeout = 3600
1326
+ options.execution_start_to_close_timeout = 600
1681
1327
  options.task_list = "continue_as_new"
1682
1328
  options.tag_list = []
1683
1329
  options.task_start_to_close_timeout = 30
@@ -1697,14 +1343,15 @@ describe "RubyFlowDecider" do
1697
1343
 
1698
1344
  it "makes sure that exponential retry returns values correctly" do
1699
1345
  class ExponentialActivity
1700
- extend Activity
1701
- activity :run_activity1 do |options|
1702
- options.version = "1"
1703
- options.default_task_list = "exponential_test_return_task_list"
1704
- options.default_task_schedule_to_close_timeout = "15"
1705
- options.default_task_schedule_to_start_timeout = "15"
1706
- options.default_task_start_to_close_timeout = "15"
1707
- options.default_task_heartbeat_timeout = "3600"
1346
+ extend AWS::Flow::Activity
1347
+ activity :run_activity1 do
1348
+ {
1349
+ version: "1.0",
1350
+ default_task_list: "exponential_test_return_task_list",
1351
+ default_task_schedule_to_close_timeout: "30",
1352
+ default_task_schedule_to_start_timeout: "15",
1353
+ default_task_start_to_close_timeout: "15",
1354
+ }
1708
1355
  end
1709
1356
  def run_activity1
1710
1357
  return 5
@@ -1712,106 +1359,98 @@ describe "RubyFlowDecider" do
1712
1359
  end
1713
1360
 
1714
1361
  class ExponentialWorkflow
1715
- extend Decider
1716
- version "1"
1717
-
1718
- activity_client :activity do |options|
1719
- options.prefix_name = "ExponentialActivity"
1720
-
1721
- options.default_task_list = "exponential_test_return_task_list"
1722
-
1723
- options.version = "1"
1362
+ extend AWS::Flow::Workflows
1363
+ workflow :start do
1364
+ {
1365
+ version: "1.0",
1366
+ default_task_list: "exponential_test_return_task_list",
1367
+ default_execution_start_to_close_timeout: 600,
1368
+ default_task_start_to_close_timeout: 60,
1369
+ default_child_policy: "REQUEST_CANCEL"
1370
+ }
1724
1371
  end
1725
- entry_point :entry_point
1726
- def entry_point
1727
- x = activity.exponential_retry(:run_activity1) do |o|
1728
- o.retries_per_exception = {
1729
- ActivityTaskTimedOutException => Float::INFINITY,
1730
- ActivityTaskFailedException => 3
1372
+ activity_client(:activity) { { from_class: "ExponentialActivity" } }
1373
+ def start
1374
+ x = activity.exponential_retry(:run_activity1) {
1375
+ {
1376
+ retries_per_exception: {
1377
+ ActivityTaskTimedOutException => Float::INFINITY,
1378
+ ActivityTaskFailedException => 3
1379
+ }
1731
1380
  }
1732
- end
1381
+ }
1733
1382
  x.should == 5
1734
1383
  end
1735
1384
  end
1736
1385
 
1737
1386
  task_list = "exponential_test_return_task_list"
1738
- # @swf and @domain are set beforehand with the aws ruby sdk
1739
1387
 
1740
- worker = WorkflowWorker.new(@swf.client, @domain, task_list, ExponentialWorkflow)
1741
- activity_worker = ActivityWorker.new(@swf.client, @domain, task_list, ExponentialActivity)
1388
+ worker = WorkflowWorker.new(@domain.client, @domain, task_list, ExponentialWorkflow)
1389
+ activity_worker = ActivityWorker.new(@domain.client, @domain, task_list, ExponentialActivity)
1742
1390
  worker.register
1743
-
1744
1391
  activity_worker.register
1745
- my_workflow_factory = workflow_factory(@swf.client, @domain) do |options|
1746
- options.workflow_name = "ExponentialWorkflow"
1747
- options.execution_start_to_close_timeout = 3600
1748
- options.task_list = task_list
1749
- options.task_start_to_close_timeout = 120
1750
- options.child_policy = :request_cancel
1751
- end
1752
-
1753
- sleep 5
1754
- client = my_workflow_factory.get_client
1392
+ client = AWS::Flow::workflow_client(@domain.client, @domain) { { from_class: "ExponentialWorkflow" } }
1755
1393
  workflow_execution = client.start_execution
1756
1394
  worker.run_once
1757
1395
  activity_worker.run_once
1758
1396
  activity_worker.run_once unless workflow_execution.events.map(&:event_type).include? "ActivityTaskCompleted"
1759
1397
  worker.run_once
1398
+ wait_for_execution(workflow_execution)
1760
1399
  workflow_execution.events.map(&:event_type).count("WorkflowExecutionCompleted").should == 1
1761
1400
  end
1762
1401
 
1763
1402
  it "makes sure that signals work correctly" do
1403
+
1764
1404
  class SignalWorkflow
1765
- extend Workflows
1405
+ extend AWS::Flow::Workflows
1766
1406
  workflow :entry_point do
1767
1407
  {
1768
- :version => "1"
1408
+ version: "1.0",
1409
+ default_execution_start_to_close_timeout: 600,
1769
1410
  }
1770
1411
  end
1412
+
1413
+ signal :this_signal
1771
1414
  def this_signal(input)
1772
1415
  @wait.broadcast
1773
1416
  @input = input
1774
1417
  end
1775
- signal :this_signal
1418
+
1776
1419
  def entry_point
1777
1420
  @input = "bad_input"
1778
1421
  @wait ||= FiberConditionVariable.new
1779
1422
  @wait.wait
1780
1423
  @input.should =~ /new input!/
1781
1424
  end
1425
+
1782
1426
  end
1783
- task_list = "SignalWorkflow_tasklist"
1784
- worker = WorkflowWorker.new(@swf.client, @domain, task_list)
1785
- worker.add_workflow_implementation(SignalWorkflow)
1427
+
1428
+ worker = build_worker(SignalWorkflow, "SignalWorkflow_tasklist")
1786
1429
  worker.register
1787
- my_workflow_client = workflow_client(@swf.client, @domain) do |options|
1788
- options.workflow_name = "SignalWorkflow"
1789
- options.execution_start_to_close_timeout = 3600
1790
- options.task_list = task_list
1791
- options.task_start_to_close_timeout = 10
1792
- options.child_policy = :request_cancel
1793
- end
1794
- sleep 3
1795
- workflow_execution = my_workflow_client.start_execution
1796
- forking_executor = ForkingExecutor.new(:max_workers => 2)
1797
- worker.run_once
1430
+ client = build_client(from_class: "SignalWorkflow")
1431
+
1432
+ workflow_execution = client.start_execution
1798
1433
 
1799
- my_workflow_client.signal_workflow_execution("this_signal", workflow_execution) { {:input => "new input!"}}
1800
1434
  worker.run_once
1801
- forking_executor.shutdown(1)
1435
+ client.signal_workflow_execution("this_signal", workflow_execution) { {:input => "new input!"}}
1436
+ worker.run_once
1437
+
1438
+ wait_for_execution(workflow_execution)
1802
1439
  workflow_execution.events.map(&:event_type).count("WorkflowExecutionCompleted").should == 1
1803
1440
  end
1804
1441
 
1805
1442
  it "makes sure that internal signalling works" do
1443
+
1806
1444
  class SignallingActivity
1807
- extend Activity
1808
- activity :run_activity1 do |options|
1809
- options.default_task_heartbeat_timeout = "3600"
1810
- options.default_task_list = "SignalWorker_activity_task_task"
1811
- options.default_task_schedule_to_close_timeout = "10"
1812
- options.default_task_schedule_to_start_timeout = "10"
1813
- options.default_task_start_to_close_timeout = "8"
1814
- options.version = "1"
1445
+ extend AWS::Flow::Activities
1446
+ activity :run_activity1 do
1447
+ {
1448
+ version: "1.0",
1449
+ default_task_list: "SignalWorker_activity_tasklist",
1450
+ default_task_schedule_to_close_timeout: "10",
1451
+ default_task_schedule_to_start_timeout: "10",
1452
+ default_task_start_to_close_timeout: "8",
1453
+ }
1815
1454
  end
1816
1455
  def run_activity1
1817
1456
  return 5
@@ -1819,76 +1458,75 @@ describe "RubyFlowDecider" do
1819
1458
  end
1820
1459
 
1821
1460
  class SignalInternalWorkflow
1822
- extend Decider
1823
- version "1"
1824
- activity_client :activity do |options|
1825
- options.prefix_name = "SignallingActivity"
1826
- options.version = "1"
1827
- options.default_task_list = "SignalWorker_activity_task_task"
1828
- options.default_task_schedule_to_start_timeout = "3600"
1829
- options.default_task_start_to_close_timeout = "3600"
1461
+ extend AWS::Flow::Workflows
1462
+
1463
+ workflow :entry_point do
1464
+ {
1465
+ version: "1.0",
1466
+ default_task_list: "SignalWorkflow_tasklist",
1467
+ default_execution_start_to_close_timeout: 600,
1468
+ default_child_policy: :request_cancel,
1469
+ }
1830
1470
  end
1831
- entry_point :entry_point
1471
+
1472
+ activity_client(:activity) { { from_class: "SignallingActivity" } }
1473
+
1832
1474
  def entry_point
1833
- my_workflow_factory = workflow_factory($swf, $domain) do |options|
1834
- options.workflow_name = "SignalWorkflow"
1835
- options.execution_method = "entry_point"
1836
- options.execution_start_to_close_timeout = 3600
1837
- options.task_start_to_close_timeout = 3600
1838
- options.child_policy = :request_cancel
1839
- options.version = "1"
1840
- options.task_list = "WorkflowSignalee_tasklist"
1841
- end
1842
- client = my_workflow_factory.get_client
1475
+ client = build_client(from_class: "SignaleeWorkflow")
1843
1476
  workflow_future = client.send_async(:start_execution)
1844
1477
  activity.run_activity1
1845
1478
  client.signal_workflow_execution(:this_signal, workflow_future)
1846
1479
  end
1847
1480
  end
1848
- class SignalWorkflow
1849
- class << self
1850
- attr_accessor :task_list, :trace
1851
- end
1852
- @trace = []
1853
- extend Decider
1854
- version "1"
1855
- def this_signal
1856
- @wait.broadcast
1481
+
1482
+ class SignaleeWorkflow
1483
+ extend AWS::Flow::Workflows
1484
+
1485
+ workflow :entry_point do
1486
+ {
1487
+ version: "1.0",
1488
+ default_task_list: "WorkflowSignalee_tasklist",
1489
+ default_execution_start_to_close_timeout: 600,
1490
+ default_child_policy: :request_cancel,
1491
+ }
1857
1492
  end
1858
1493
  signal :this_signal
1859
- entry_point :entry_point
1494
+
1860
1495
  def entry_point
1861
1496
  @wait ||= FiberConditionVariable.new
1862
1497
  @wait.wait
1863
1498
  end
1499
+ def this_signal
1500
+ @wait.broadcast
1501
+ end
1864
1502
  end
1865
- task_list = "SignalWorkflow_tasklist"
1866
- worker_signalee = WorkflowWorker.new(@swf.client, @domain, "WorkflowSignalee_tasklist")
1867
- worker_signalee.add_workflow_implementation(SignalWorkflow)
1868
- worker_signaler = WorkflowWorker.new(@swf.client, @domain, task_list)
1869
- worker_signaler.add_workflow_implementation(SignalInternalWorkflow)
1870
- activity_worker = ActivityWorker.new(@swf.client, @domain, "SignalWorker_activity_task_task", SignallingActivity)
1503
+
1504
+ worker_signalee = build_worker(SignaleeWorkflow, "WorkflowSignalee_tasklist")
1505
+ worker_signaler = build_worker(SignalInternalWorkflow, "SignalWorkflow_tasklist")
1506
+ activity_worker = build_worker(SignallingActivity, "SignalWorker_activity_tasklist")
1871
1507
  worker_signaler.register
1872
1508
  worker_signalee.register
1873
1509
  activity_worker.register
1874
- my_workflow_factory = workflow_factory(@swf.client, @domain) do |options|
1875
- options.workflow_name = "SignalInternalWorkflow"
1876
- options.execution_start_to_close_timeout = 3600
1877
- options.task_list = task_list
1878
- options.task_start_to_close_timeout = 600
1879
- options.child_policy = :request_cancel
1880
- end
1881
- my_workflow = my_workflow_factory.get_client
1882
- workflow_execution = my_workflow.start_execution
1510
+
1511
+ client = build_client(from_class: "SignalInternalWorkflow")
1512
+ workflow_execution = client.start_execution
1513
+
1883
1514
  worker_signaler.run_once
1884
1515
  worker_signalee.run_once
1885
1516
  activity_worker.run_once
1886
- # Sleep a bit so that the activity execution completes before we decide, so we don't decide on the ChildWorkflowExecutionInitiated before the ActivityTaskCompleted schedules anothe DecisionTaskScheduled
1887
- sleep 10
1517
+ wait_for_decision(workflow_execution, "ActivityTaskCompleted")
1518
+
1888
1519
  worker_signaler.run_once
1520
+ wait_for_decision(workflow_execution)
1521
+
1889
1522
  worker_signalee.run_once
1523
+ wait_for_decision(workflow_execution, "ChildWorkflowExecutionCompleted")
1524
+
1890
1525
  worker_signaler.run_once
1526
+ wait_for_execution(workflow_execution)
1527
+
1891
1528
  workflow_execution.events.map(&:event_type).count("WorkflowExecutionCompleted").should == 1
1529
+
1892
1530
  end
1893
1531
  end
1894
1532
 
@@ -1903,8 +1541,8 @@ describe "RubyFlowDecider" do
1903
1541
  extend Activity
1904
1542
  activity :run_activity1 do |options|
1905
1543
  options.default_task_list = GeneralActivity.task_list
1906
- options.default_task_schedule_to_start_timeout = "3600"
1907
- options.default_task_start_to_close_timeout = "3600"
1544
+ options.default_task_schedule_to_start_timeout = "600"
1545
+ options.default_task_start_to_close_timeout = "600"
1908
1546
  options.version = "1"
1909
1547
  end
1910
1548
  def run_activity1
@@ -1915,14 +1553,14 @@ describe "RubyFlowDecider" do
1915
1553
  class << self
1916
1554
  attr_accessor :task_list
1917
1555
  end
1918
- extend Decider
1556
+ extend AWS::Flow::Workflows
1919
1557
  version "1"
1920
1558
  activity_client :activity do |options|
1921
1559
  options.prefix_name = "GeneralActivity"
1922
1560
  options.version = "1"
1923
1561
  options.default_task_list = MyWorkflow.task_list
1924
- options.default_task_schedule_to_start_timeout = "3600"
1925
- options.default_task_start_to_close_timeout = "3600"
1562
+ options.default_task_schedule_to_start_timeout = "60"
1563
+ options.default_task_start_to_close_timeout = "60"
1926
1564
  end
1927
1565
  entry_point :entry_point
1928
1566
  def entry_point(arg)
@@ -1938,24 +1576,21 @@ describe "RubyFlowDecider" do
1938
1576
  activity_worker.register
1939
1577
  my_workflow_factory = workflow_factory(@swf.client, @domain) do |options|
1940
1578
  options.workflow_name = "MyWorkflow"
1941
- options.execution_start_to_close_timeout = 3600
1579
+ options.execution_start_to_close_timeout = 600
1942
1580
  options.task_list = task_list
1943
- options.task_start_to_close_timeout = 3600
1581
+ options.task_start_to_close_timeout = 120
1944
1582
  options.child_policy = :request_cancel
1945
1583
  end
1946
1584
  my_workflow = my_workflow_factory.get_client
1947
1585
 
1948
- workflow_execution = my_workflow.start_execution(5)
1949
1586
 
1950
- sleep 10
1951
1587
  @forking_executor = ForkingExecutor.new(:max_workers => 3)
1952
1588
  @forking_executor.execute { worker.start }
1953
- sleep 5
1954
1589
  @forking_executor.execute { activity_worker.start }
1955
-
1956
- sleep 20
1590
+ workflow_execution = my_workflow.start_execution(5)
1591
+ wait_for_execution(workflow_execution)
1957
1592
  @forking_executor.shutdown(1)
1958
- workflow_execution.events.map(&:event_type)
1593
+ workflow_execution.events.map(&:event_type).count("ActivityTaskFailed").should == 1
1959
1594
  end
1960
1595
 
1961
1596
  it "is a good example of the service" do
@@ -1965,7 +1600,7 @@ describe "RubyFlowDecider" do
1965
1600
  activity :run_activity1 do |options|
1966
1601
  options.default_task_list = "add_one_task_list"
1967
1602
  options.version = "1"
1968
- options.default_task_heartbeat_timeout = "3600"
1603
+ options.default_task_heartbeat_timeout = "600"
1969
1604
  options.default_task_schedule_to_close_timeout = "30"
1970
1605
  options.default_task_schedule_to_start_timeout = "30"
1971
1606
  options.default_task_start_to_close_timeout = "30"
@@ -1977,7 +1612,7 @@ describe "RubyFlowDecider" do
1977
1612
  end
1978
1613
  # Definition of the workflow logic
1979
1614
  class MyWorkflow
1980
- extend Decider
1615
+ extend AWS::Flow::Workflows
1981
1616
  version "1"
1982
1617
  activity_client :activity do |options|
1983
1618
  options.prefix_name = "AddOneActivity"
@@ -1985,11 +1620,11 @@ describe "RubyFlowDecider" do
1985
1620
  # to have the lines below, but since the have access to the activity, we
1986
1621
  # can simply "peek" at its configuration, and use those
1987
1622
 
1988
- # options.default_task_heartbeat_timeout = "3600"
1623
+ # options.default_task_heartbeat_timeout = "600"
1989
1624
  # options.default_task_list = "add_one_task_list"
1990
- # options.default_task_schedule_to_close_timeout = "3600"
1991
- # options.default_task_schedule_to_start_timeout = "3600"
1992
- # options.default_task_start_to_close_timeout = "3600"
1625
+ # options.default_task_schedule_to_close_timeout = "600"
1626
+ # options.default_task_schedule_to_start_timeout = "600"
1627
+ # options.default_task_start_to_close_timeout = "600"
1993
1628
  end
1994
1629
 
1995
1630
  # The default place to start the execution of a workflow is "entry_point",
@@ -2020,9 +1655,9 @@ describe "RubyFlowDecider" do
2020
1655
  # Get a workflow client to start the workflow
2021
1656
  my_workflow_factory = workflow_factory @swf.client, @domain do |options|
2022
1657
  options.workflow_name = "MyWorkflow"
2023
- options.execution_start_to_close_timeout = 3600
1658
+ options.execution_start_to_close_timeout = 600
2024
1659
  options.task_list = task_list
2025
- options.task_start_to_close_timeout = 3600
1660
+ options.task_start_to_close_timeout = 120
2026
1661
  options.child_policy = :request_cancel
2027
1662
  end
2028
1663
  # Forking executors have some possibility of race conditions, so we will
@@ -2040,7 +1675,7 @@ describe "RubyFlowDecider" do
2040
1675
 
2041
1676
  # Sleep to give the threads some time to compute, as we'll run right out of
2042
1677
  # the test before they can run otherwise
2043
- sleep 40
1678
+ wait_for_execution(workflow_execution)
2044
1679
  workflow_execution.events.map(&:event_type).count("WorkflowExecutionCompleted").should == 1
2045
1680
  end
2046
1681
 
@@ -2051,10 +1686,10 @@ describe "RubyFlowDecider" do
2051
1686
  activity :run_activity1, :run_activity2, :run_activity3 do |options|
2052
1687
  options.default_task_list = "parallel_split_task_list"
2053
1688
  options.version = "1"
2054
- options.default_task_heartbeat_timeout = "3600"
2055
- options.default_task_schedule_to_close_timeout = "3600"
2056
- options.default_task_schedule_to_start_timeout = "3600"
2057
- options.default_task_start_to_close_timeout = "3600"
1689
+ options.default_task_heartbeat_timeout = "600"
1690
+ options.default_task_schedule_to_close_timeout = "120"
1691
+ options.default_task_schedule_to_start_timeout = "120"
1692
+ options.default_task_start_to_close_timeout = "120"
2058
1693
  end
2059
1694
  def run_activity1(arg)
2060
1695
  arg + 1
@@ -2068,7 +1703,7 @@ describe "RubyFlowDecider" do
2068
1703
  end
2069
1704
  # Definition of the workflow logic
2070
1705
  class ParallelWorkflow
2071
- extend Decider
1706
+ extend AWS::Flow::Workflows
2072
1707
  version "1"
2073
1708
  activity_client :activity do |options|
2074
1709
  options.prefix_name = "ParallelSplitActivity"
@@ -2076,11 +1711,11 @@ describe "RubyFlowDecider" do
2076
1711
  # to have the lines below, but since the have access to the activity, we
2077
1712
  # can simply "peek" at its configuration, and use those
2078
1713
 
2079
- # options.default_task_heartbeat_timeout = "3600"
1714
+ # options.default_task_heartbeat_timeout = "600"
2080
1715
  # options.default_task_list = "parallel_split_task_list"
2081
- # options.default_task_schedule_to_close_timeout = "3600"
2082
- # options.default_task_schedule_to_start_timeout = "3600"
2083
- # options.default_task_start_to_close_timeout = "3600"
1716
+ # options.default_task_schedule_to_close_timeout = "120"
1717
+ # options.default_task_schedule_to_start_timeout = "120"
1718
+ # options.default_task_start_to_close_timeout = "120"
2084
1719
  end
2085
1720
 
2086
1721
  # The default place to start the execution of a workflow is "entry_point",
@@ -2117,7 +1752,7 @@ describe "RubyFlowDecider" do
2117
1752
  # Get a workflow client to start the workflow
2118
1753
  my_workflow_factory = workflow_factory @swf.client, @domain do |options|
2119
1754
  options.workflow_name = "ParallelWorkflow"
2120
- options.execution_start_to_close_timeout = 3600
1755
+ options.execution_start_to_close_timeout = 600
2121
1756
  options.task_list = task_list
2122
1757
  options.task_start_to_close_timeout = 10
2123
1758
  options.child_policy = :request_cancel
@@ -2126,24 +1761,11 @@ describe "RubyFlowDecider" do
2126
1761
  my_workflow_client = my_workflow_factory.get_client
2127
1762
  workflow_execution = my_workflow_client.start_execution(5)
2128
1763
 
2129
- # We use an executor here so as to be able to test this feature within one
2130
- # working process, as activity_worker.start and worker.start will block
2131
- # otherwise
2132
-
2133
- # Forking executors have some possibility of race conditions, so we will
2134
- # avoid them by putting in a small sleep. There is no plan to fix at current, as
2135
- # we don't expect forking executor to be used by most customers.
2136
- sleep 5
2137
1764
  forking_executor = ForkingExecutor.new(:max_workers => 2)
2138
-
2139
1765
  forking_executor.execute { activity_worker.start }
2140
- sleep 5
2141
1766
  forking_executor.execute { worker.start }
2142
1767
 
2143
-
2144
- # Sleep to give the threads some time to compute, as we'll run right out of
2145
- # the test before they can run otherwise
2146
- sleep 50
1768
+ wait_for_execution(workflow_execution)
2147
1769
  workflow_execution.events.map(&:event_type).count("WorkflowExecutionCompleted").should == 1
2148
1770
  end
2149
1771
 
@@ -2153,7 +1775,7 @@ describe "RubyFlowDecider" do
2153
1775
  activity :run_activity1, :run_activity2 do |options|
2154
1776
  options.default_task_list = "error_handling_task_list"
2155
1777
  options.version = "1"
2156
- options.default_task_heartbeat_timeout = "3600"
1778
+ options.default_task_heartbeat_timeout = "600"
2157
1779
  options.default_task_schedule_to_close_timeout = "10"
2158
1780
  options.default_task_schedule_to_start_timeout = "10"
2159
1781
  options.default_task_start_to_close_timeout = "10"
@@ -2167,7 +1789,7 @@ describe "RubyFlowDecider" do
2167
1789
  end
2168
1790
  # Definition of the workflow logic
2169
1791
  class MyWorkflow
2170
- extend Decider
1792
+ extend AWS::Flow::Workflows
2171
1793
  version "1"
2172
1794
  activity_client :activity do |options|
2173
1795
  options.prefix_name = "ErrorHandlingActivity"
@@ -2175,11 +1797,11 @@ describe "RubyFlowDecider" do
2175
1797
  # to have the lines below, but since the have access to the activity, we
2176
1798
  # can simply "peek" at its configuration, and use those
2177
1799
 
2178
- # options.default_task_heartbeat_timeout = "3600"
1800
+ # options.default_task_heartbeat_timeout = "600"
2179
1801
  # options.default_task_list = "error_handling_task_list"
2180
- # options.default_task_schedule_to_close_timeout = "3600"
2181
- # options.default_task_schedule_to_start_timeout = "3600"
2182
- # options.default_task_start_to_close_timeout = "3600"
1802
+ # options.default_task_schedule_to_close_timeout = "120"
1803
+ # options.default_task_schedule_to_start_timeout = "120"
1804
+ # options.default_task_start_to_close_timeout = "120"
2183
1805
  end
2184
1806
 
2185
1807
  # The default place to start the execution of a workflow is "entry_point",
@@ -2215,7 +1837,7 @@ describe "RubyFlowDecider" do
2215
1837
  error_seen.should == ActivityTaskFailedException
2216
1838
  # Do something to clean up after
2217
1839
  end
2218
- end
1840
+ end
2219
1841
  5
2220
1842
  end
2221
1843
  end
@@ -2233,7 +1855,7 @@ describe "RubyFlowDecider" do
2233
1855
  # Get a workflow client to start the workflow
2234
1856
  my_workflow_factory = workflow_factory @swf.client, @domain do |options|
2235
1857
  options.workflow_name = "MyWorkflow"
2236
- options.execution_start_to_close_timeout = 3600
1858
+ options.execution_start_to_close_timeout = 600
2237
1859
  options.task_list = task_list
2238
1860
  options.task_start_to_close_timeout = 20
2239
1861
  options.child_policy = :request_cancel
@@ -2264,6 +1886,7 @@ describe "RubyFlowDecider" do
2264
1886
  worker.run_once
2265
1887
  # worker.start
2266
1888
 
1889
+ wait_for_execution(workflow_execution)
2267
1890
 
2268
1891
  workflow_execution.events.map(&:event_type).count("WorkflowExecutionCompleted").should == 1
2269
1892
  end
@@ -2305,135 +1928,137 @@ describe "RubyFlowDecider" do
2305
1928
 
2306
1929
  describe "ensures that you can specify the {workflow_id,execution_method} to be used for an external client" do
2307
1930
  {:workflow_id => ["blah", "workflow_id"] ,
2308
- :execution_method => ["entry_point", "workflow_type.name.split('.').last" ]
1931
+ :execution_method => ["start", "workflow_type.name.split('.').last" ]
2309
1932
  }.each_pair do |method, value_and_method_to_check|
2310
1933
  value, method_to_check = value_and_method_to_check
2311
- swf, domain, _ = setup_swf
1934
+
2312
1935
  it "makes sure that #{method} can be specified correctly" do
2313
1936
  class WorkflowIDWorkflow
2314
- extend Decider
2315
- version "1"
2316
- entry_point :entry_point
2317
- def entry_point
1937
+ extend Workflows
1938
+ workflow :start do
1939
+ {
1940
+ version: "1.0",
1941
+ default_execution_start_to_close_timeout: 600,
1942
+ default_task_list: "timeout_test"
1943
+ }
2318
1944
  end
1945
+ def start; end
2319
1946
  end
2320
- worker = WorkflowWorker.new(swf.client, domain, "timeout_test", WorkflowIDWorkflow)
1947
+
1948
+ worker = WorkflowWorker.new(@domain.client, @domain, "timeout_test", WorkflowIDWorkflow)
2321
1949
  worker.register
2322
- my_workflow_factory = workflow_factory swf.client, domain do |options|
2323
- options.workflow_name = "WorkflowIDWorkflow"
2324
- options.execution_start_to_close_timeout = 3600
2325
- options.task_list = "timeout_test"
2326
- end
2327
- my_workflow_client = my_workflow_factory.get_client
2328
- execution = my_workflow_client.entry_point do |opt|
2329
- opt.send("#{method}=", value)
2330
- opt.tag_list = ["stuff"]
1950
+ client = AWS::Flow::workflow_client(@domain.client, @domain) { { from_class: "WorkflowIDWorkflow" } }
1951
+
1952
+ workflow_execution = client.start do {
1953
+ method.to_sym => value,
1954
+ tag_list: ["stuff"]
1955
+ }
2331
1956
  end
2332
- return_value = eval "execution.#{method_to_check}"
1957
+
1958
+ return_value = eval "workflow_execution.#{method_to_check}"
2333
1959
  return_value.should == value
2334
- execution.tags.should == ["stuff"]
1960
+ workflow_execution.tags.should == ["stuff"]
2335
1961
  end
2336
1962
  end
2337
1963
  end
2338
1964
  describe "making sure that timeouts are infrequent" do
2339
1965
  it "is a basic repro case" do
2340
1966
  class TimeoutActivity
2341
- extend Activity
2342
- activity :run_activity1 do |options|
2343
- options.default_task_list = "timeout_test"
2344
- options.version = "1"
2345
- options.default_task_heartbeat_timeout = "3600"
2346
- options.default_task_schedule_to_close_timeout = "60"
2347
- options.default_task_schedule_to_start_timeout = "60"
2348
- options.default_task_start_to_close_timeout = "60"
1967
+ extend AWS::Flow::Activities
1968
+ activity :run_activity1 do
1969
+ {
1970
+ default_task_list: "timeout_test_activity",
1971
+ version: "1.0",
1972
+ default_task_schedule_to_close_timeout: "60",
1973
+ default_task_schedule_to_start_timeout: "30",
1974
+ default_task_start_to_close_timeout: "30",
1975
+ }
2349
1976
  end
2350
1977
  def run_activity1
2351
1978
  "did some work in run_activity1"
2352
1979
  end
2353
1980
  end
2354
1981
  class TimeoutWorkflow
2355
- extend Decider
2356
- version "1"
2357
- activity_client :activity do |options|
2358
- options.prefix_name = "TimeoutActivity"
1982
+ extend AWS::Flow::Workflows
1983
+ workflow :entry_point do
1984
+ {
1985
+ version: "1.0",
1986
+ default_execution_start_to_close_timeout: 600,
1987
+ default_task_list: "timeout_test_workflow"
1988
+ }
2359
1989
  end
2360
- entry_point :entry_point
1990
+ activity_client (:activity) { { from_class: "TimeoutActivity" } }
2361
1991
  def entry_point
2362
1992
  activity.run_activity1
2363
1993
  end
2364
1994
  end
2365
- worker = WorkflowWorker.new(@swf.client, @domain, "timeout_test", TimeoutWorkflow)
2366
- activity_worker = ActivityWorker.new(@swf.client, @domain, "timeout_test", TimeoutActivity)
2367
- worker.register
2368
- activity_worker.register
2369
- my_workflow_factory = workflow_factory @swf.client, @domain do |options|
2370
- options.workflow_name = "TimeoutWorkflow"
2371
- options.execution_start_to_close_timeout = 3600
2372
- options.task_start_to_close_timeout = 5
2373
- options.task_list = "timeout_test"
2374
- end
2375
- my_workflow_client = my_workflow_factory.get_client
1995
+ @worker = WorkflowWorker.new(@domain.client, @domain, "timeout_test_workflow", TimeoutWorkflow)
1996
+ @activity_workers = []
1997
+
2376
1998
  num_tests = 15
1999
+ 1.upto(num_tests) { @activity_workers << ActivityWorker.new(@domain.client, @domain, "timeout_test_activity", TimeoutActivity) }
2000
+
2001
+ @worker.register
2002
+ @activity_workers.first.register
2003
+
2004
+ my_workflow_client = AWS::Flow::workflow_client(@domain.client, @domain) { { from_class: "TimeoutWorkflow" } }
2005
+
2377
2006
  workflow_executions = []
2007
+
2008
+ @forking_executor = ForkingExecutor.new(max_workers: 20)
2009
+ @forking_executor.execute { @worker.start }
2010
+ @activity_workers.each { |x| @forking_executor.execute { x.start } }
2011
+ sleep 10
2012
+
2378
2013
  1.upto(num_tests) { |i| workflow_executions << my_workflow_client.entry_point }
2379
- forking_executor = ForkingExecutor.new(:max_workers => 3)
2380
- forking_executor.execute { worker.start }
2381
- forking_executor.execute { activity_worker.start }
2382
- sleep 60
2383
- failed_executions = workflow_executions.each{|x| x.events.to_a.last.event_type.should == "WorkflowExecutionCompleted" }
2014
+
2015
+ workflow_executions.each { |x| wait_for_execution(x) }
2016
+ workflow_executions.each{|x| x.events.to_a.last.event_type.should == "WorkflowExecutionCompleted" }
2017
+ @forking_executor.shutdown(1)
2384
2018
 
2385
2019
  end
2386
2020
  end
2387
2021
 
2388
2022
  describe "makes sure that workflow clients expose the same client api and do the right thing" do
2389
2023
  it "makes sure that send_async works" do
2390
- class SendAsyncWorkflow
2391
- extend Decider
2392
- version "1"
2393
- entry_point :entry_point
2394
- def entry_point(arg)
2024
+ class SendAsyncChildWorkflow
2025
+ extend AWS::Flow::Workflows
2026
+ workflow :start do
2027
+ {
2028
+ version: "1.0",
2029
+ default_execution_start_to_close_timeout: "600"
2030
+ }
2395
2031
  end
2032
+ def start; end
2396
2033
  end
2397
- class SendAsyncBadWorkflow
2398
- class << self
2399
- attr_accessor :task_list, :trace
2400
- end
2401
- @trace = []
2402
- extend Decider
2403
- version "1"
2404
- entry_point :entry_point
2405
- def entry_point(arg)
2406
- client = workflow_client(@swf_client, @domain) do |options|
2407
- options.workflow_name = "SendAsyncWorkflow"
2408
- options.execution_method = "entry_point"
2409
- options.execution_start_to_close_timeout = 3600
2410
- options.task_start_to_close_timeout = 10
2411
- options.version = "1"
2412
- options.task_list = "client_test_async2"
2413
- end
2414
- client.send_async(:start_execution, arg) {
2415
- { :task_start_to_close_timeout => 35 }
2034
+ class SendAsyncParentWorkflow
2035
+ extend AWS::Flow::Workflows
2036
+ workflow :start do
2037
+ {
2038
+ version: "1.0",
2039
+ default_execution_start_to_close_timeout: "600",
2416
2040
  }
2417
- client.send_async(:start_execution, arg)
2041
+ end
2042
+ def start
2043
+ domain = get_test_domain
2044
+ client = AWS::Flow::workflow_client(domain.client, domain) { { from_class: "SendAsyncChildWorkflow" } }
2045
+ client.send_async(:start_execution) { { task_list: "client_test_async2" } }
2046
+ client.send_async(:start_execution) { { task_list: "client_test_async2" } }
2418
2047
  end
2419
2048
  end
2420
- worker = WorkflowWorker.new(@swf.client, @domain, "client_test_async", SendAsyncBadWorkflow)
2421
- internal_worker = WorkflowWorker.new(@swf.client, @domain, "client_test_async2", SendAsyncWorkflow)
2422
- worker.register
2423
- internal_worker.register
2424
- my_workflow_factory = workflow_factory @swf.client, @domain do |options|
2425
- options.workflow_name = "SendAsyncBadWorkflow"
2426
- options.execution_start_to_close_timeout = 3600
2427
- options.task_list = "client_test_async"
2428
- end
2429
- my_workflow_client = my_workflow_factory.get_client
2430
- workflow_execution = my_workflow_client.entry_point(5)
2431
- worker.run_once
2049
+ @parent_worker = WorkflowWorker.new(@domain.client, @domain, "client_test_async", SendAsyncParentWorkflow)
2050
+ @child_worker = WorkflowWorker.new(@domain.client, @domain, "client_test_async2", SendAsyncChildWorkflow)
2051
+ @parent_worker.register
2052
+ @child_worker.register
2053
+ @forking_executor = ForkingExecutor.new(:max_workers => 3)
2054
+ @forking_executor.execute { @parent_worker.start }
2055
+ @forking_executor.execute { @child_worker.start }
2056
+
2057
+ my_workflow_client = AWS::Flow::workflow_client(@domain.client, @domain) { { from_class: "SendAsyncParentWorkflow" } }
2058
+ workflow_execution = my_workflow_client.start_execution
2059
+
2060
+ wait_for_execution(workflow_execution)
2432
2061
 
2433
- internal_worker.run_once
2434
- internal_worker.run_once
2435
- worker.run_once
2436
- worker.run_once if workflow_execution.events.map(&:event_type).last == "DecisionTaskCompleted"
2437
2062
  history_events = workflow_execution.events.map(&:event_type)
2438
2063
  history_events.count("ChildWorkflowExecutionCompleted").should == 2
2439
2064
  history_events.count("WorkflowExecutionCompleted").should == 1
@@ -2441,58 +2066,48 @@ describe "RubyFlowDecider" do
2441
2066
 
2442
2067
  it "makes sure that retry works" do
2443
2068
  class OtherWorkflow
2444
- extend Decider
2445
- version "1"
2446
- entry_point :entry_point
2447
- def entry_point(arg)
2069
+ extend AWS::Flow::Workflows
2070
+ workflow :other_workflow do
2071
+ {
2072
+ version: "1.0",
2073
+ default_execution_start_to_close_timeout: 120,
2074
+ default_task_start_to_close_timeout: 10
2075
+ }
2076
+
2077
+ end
2078
+ def other_workflow
2448
2079
  raise "Simulated error"
2449
2080
  end
2450
2081
  end
2451
2082
  class BadWorkflow
2452
- class << self
2453
- attr_accessor :task_list, :trace
2083
+ extend AWS::Flow::Workflows
2084
+ workflow :bad_workflow do
2085
+ {
2086
+ version: "1.0",
2087
+ default_execution_start_to_close_timeout: 600,
2088
+ default_task_start_to_close_timeout: 30
2089
+ }
2454
2090
  end
2455
- @trace = []
2456
- extend Decider
2457
- version "1"
2458
- entry_point :entry_point
2459
- def entry_point(arg)
2460
- my_workflow_factory = workflow_factory($swf_client, $domain) do |options|
2461
- options.workflow_name = "OtherWorkflow"
2462
- options.execution_method = "entry_point"
2463
- options.execution_start_to_close_timeout = 3600
2464
- options.task_start_to_close_timeout = 10
2465
- options.version = "1"
2466
- options.task_list = "client_test_retry2"
2467
- end
2468
- client = my_workflow_factory.get_client
2469
- client.exponential_retry(:start_execution, arg) do |opt|
2470
- opt.maximum_attempts = 1
2471
- end
2091
+
2092
+ def bad_workflow
2093
+ domain = get_test_domain
2094
+ child_client = AWS::Flow::workflow_client(domain.client, domain) { { from_class: "OtherWorkflow" } }
2095
+ child_client.exponential_retry(:start_execution) { { maximum_attempts: 1 }}
2472
2096
  end
2473
2097
  end
2474
- worker = WorkflowWorker.new(@swf.client, @domain, "client_test_retry", BadWorkflow)
2475
- internal_worker = WorkflowWorker.new(@swf.client, @domain, "client_test_retry2", OtherWorkflow)
2476
- worker.register
2477
- internal_worker.register
2478
- my_workflow_factory = workflow_factory @swf.client, @domain do |options|
2479
- options.workflow_name = "BadWorkflow"
2480
- options.execution_start_to_close_timeout = 3600
2481
- options.task_list = "client_test_retry"
2482
- end
2483
- my_workflow_client = my_workflow_factory.get_client
2484
- workflow_execution = my_workflow_client.entry_point(5)
2098
+ @parent_worker = WorkflowWorker.new(@domain.client, @domain, "client_test_retry", BadWorkflow)
2099
+ @child_worker = WorkflowWorker.new(@domain.client, @domain, "client_test_retry2", OtherWorkflow)
2100
+ @parent_worker.register
2101
+ @child_worker.register
2485
2102
 
2486
- worker.run_once
2487
- internal_worker.run_once
2103
+ forking_executor = ForkingExecutor.new(:max_workers => 3)
2104
+ forking_executor.execute { @parent_worker.start }
2105
+ forking_executor.execute { @child_worker.start }
2488
2106
 
2489
- # Make sure that we finish the execution and fail before reporting ack
2490
- sleep 10
2491
- worker.run_once
2492
- worker.run_once
2493
- internal_worker.run_once
2494
- sleep 10
2495
- worker.run_once
2107
+ parent_client = AWS::Flow::workflow_client(@domain.client, @domain) { { from_class: "BadWorkflow" } }
2108
+ workflow_execution = parent_client.start_execution
2109
+
2110
+ wait_for_execution(workflow_execution)
2496
2111
  history_events = workflow_execution.events.map(&:event_type)
2497
2112
  history_events.count("ChildWorkflowExecutionFailed").should == 2
2498
2113
  history_events.count("WorkflowExecutionFailed").should == 1
@@ -2513,12 +2128,12 @@ describe "RubyFlowDecider" do
2513
2128
  end
2514
2129
  end
2515
2130
 
2516
- @workflow_execution = @my_workflow_client.entry_point
2131
+ workflow_execution = @my_workflow_client.entry_point
2517
2132
  @worker.run_once
2518
2133
  sleep 20
2519
2134
  @worker.run_once
2520
2135
  @worker.run_once
2521
- @workflow_execution.events.map(&:event_type).last.should == "ActivityTaskScheduled"
2136
+ workflow_execution.events.map(&:event_type).last.should == "ActivityTaskScheduled"
2522
2137
  end
2523
2138
 
2524
2139
  it "ensures that with_retry does synchronous blocking by default" do
@@ -2555,18 +2170,20 @@ describe "RubyFlowDecider" do
2555
2170
 
2556
2171
 
2557
2172
  it "makes sure that option inheritance doesn't override set values" do
2558
- class OptionsWorkflow
2173
+ class InheritanceOptionsWorkflow
2559
2174
  extend Workflows
2560
- version "1"
2561
- entry_point :entry_point
2562
- def entry_point
2175
+ workflow :entry_point do
2176
+ {
2177
+ version: "1.0",
2178
+ }
2563
2179
  end
2180
+ def entry_point ; end
2564
2181
  end
2565
- worker = WorkflowWorker.new(@swf.client, @domain, "client_test_inheritance", OptionsWorkflow)
2182
+ worker = WorkflowWorker.new(@swf.client, @domain, "client_test_inheritance", InheritanceOptionsWorkflow)
2566
2183
  worker.register
2567
2184
  my_workflow_factory = workflow_factory @swf.client, @domain do |options|
2568
- options.workflow_name = "OptionsWorkflow"
2569
- options.execution_start_to_close_timeout = 3600
2185
+ options.workflow_name = "InheritanceOptionsWorkflow"
2186
+ options.execution_start_to_close_timeout = 600
2570
2187
  options.task_start_to_close_timeout = 10
2571
2188
  options.child_policy = :REQUEST_CANCEL
2572
2189
  options.task_list = "client_test_inheritance"
@@ -2577,25 +2194,24 @@ describe "RubyFlowDecider" do
2577
2194
  end
2578
2195
 
2579
2196
  it "makes sure that option inheritance gives you defaults" do
2580
- class OptionsWorkflow
2197
+ class InheritanceOptionsWorkflow2
2581
2198
  extend Workflows
2582
- version "1"
2583
- entry_point :entry_point
2584
- def entry_point
2199
+ workflow :options_workflow do
2200
+ {
2201
+ version: "1.0",
2202
+ default_execution_start_to_close_timeout: 600,
2203
+ default_task_list: "client_test_inheritance"
2204
+ }
2585
2205
  end
2206
+ def options_workflow ; end
2586
2207
  end
2587
- worker = WorkflowWorker.new(@swf.client, @domain, "client_test_inheritance", OptionsWorkflow)
2208
+ worker = WorkflowWorker.new(@domain.client, @domain, "client_test_inheritance", InheritanceOptionsWorkflow2)
2588
2209
  worker.register
2589
- my_workflow_factory = workflow_factory @swf.client, @domain do |options|
2590
- options.workflow_name = "OptionsWorkflow"
2591
- options.execution_start_to_close_timeout = 3600
2592
- options.child_policy = :REQUEST_CANCEL
2593
- options.task_list = "client_test_inheritance"
2594
- end
2595
2210
 
2596
- workflow_execution = my_workflow_factory.get_client.entry_point
2597
- workflow_execution.terminate
2211
+ client = AWS::Flow::workflow_client(@domain.client, @domain) { { from_class: "InheritanceOptionsWorkflow2", child_policy: "REQUEST_CANCEL" } }
2598
2212
 
2213
+ workflow_execution = client.start_execution
2214
+ workflow_execution.terminate
2599
2215
  workflow_execution.child_policy.should == :request_cancel
2600
2216
  end
2601
2217
 
@@ -2604,11 +2220,11 @@ describe "RubyFlowDecider" do
2604
2220
  extend Activity
2605
2221
  activity :run_activity1 do
2606
2222
  {
2607
- :default_task_list => "options_test", :version => "1",
2608
- :default_task_heartbeat_timeout => "3600",
2609
- :default_task_schedule_to_close_timeout => "60",
2610
- :default_task_schedule_to_start_timeout => "60",
2611
- :default_task_start_to_close_timeout => "60",
2223
+ :default_task_list => "options_test", :version => "1",
2224
+ :default_task_heartbeat_timeout => "600",
2225
+ :default_task_schedule_to_close_timeout => "60",
2226
+ :default_task_schedule_to_start_timeout => "60",
2227
+ :default_task_start_to_close_timeout => "60",
2612
2228
  }
2613
2229
  end
2614
2230
  def run_activity1
@@ -2634,7 +2250,7 @@ describe "RubyFlowDecider" do
2634
2250
  activity_worker.register
2635
2251
  my_workflow_factory = workflow_factory @swf.client, @domain do |options|
2636
2252
  options.workflow_name = "NewOptionsWorkflow"
2637
- options.execution_start_to_close_timeout = 3600
2253
+ options.execution_start_to_close_timeout = 600
2638
2254
  options.task_start_to_close_timeout = 10
2639
2255
  options.child_policy = :REQUEST_CANCEL
2640
2256
  options.task_list = "options_test"
@@ -2654,7 +2270,7 @@ describe "RubyFlowDecider" do
2654
2270
  activity :run_activity1 do
2655
2271
  {
2656
2272
  :default_task_list => "options_test", :version => "1",
2657
- :default_task_heartbeat_timeout => "3600",
2273
+ :default_task_heartbeat_timeout => "600",
2658
2274
  :default_task_schedule_to_close_timeout => "60",
2659
2275
  :default_task_schedule_to_start_timeout => "60",
2660
2276
  :default_task_start_to_close_timeout => "60",
@@ -2683,7 +2299,7 @@ describe "RubyFlowDecider" do
2683
2299
  activity_worker.register
2684
2300
  my_workflow_factory = workflow_factory @swf.client, @domain do |options|
2685
2301
  options.workflow_name = "WithRetryWorkflow"
2686
- options.execution_start_to_close_timeout = 3600
2302
+ options.execution_start_to_close_timeout = 600
2687
2303
  options.task_start_to_close_timeout = 10
2688
2304
  options.child_policy = :REQUEST_CANCEL
2689
2305
  options.task_list = "options_test"
@@ -2727,7 +2343,7 @@ describe "RubyFlowDecider" do
2727
2343
  activity :run_activity1 do |options|
2728
2344
  options.default_task_list = "options_test"
2729
2345
  options.version = "1"
2730
- options.default_task_heartbeat_timeout = "3600"
2346
+ options.default_task_heartbeat_timeout = "600"
2731
2347
  options.default_task_schedule_to_close_timeout = "60"
2732
2348
  options.default_task_schedule_to_start_timeout = "60"
2733
2349
  options.default_task_start_to_close_timeout = "60"
@@ -2755,7 +2371,7 @@ describe "RubyFlowDecider" do
2755
2371
  activity_worker.register
2756
2372
  my_workflow_factory = workflow_factory @swf.client, @domain do |options|
2757
2373
  options.workflow_name = "OptionsWorkflow"
2758
- options.execution_start_to_close_timeout = 3600
2374
+ options.execution_start_to_close_timeout = 600
2759
2375
  options.task_start_to_close_timeout = 10
2760
2376
  options.child_policy = :REQUEST_CANCEL
2761
2377
  options.task_list = "options_test"
@@ -2770,28 +2386,30 @@ describe "RubyFlowDecider" do
2770
2386
  it "makes sure that you can create a workflow in the new way" do
2771
2387
  class WorkflowWorkflow
2772
2388
  extend Workflows
2773
- workflow(:entry_point) { {:version => "1", :execution_start_to_close_timeout => 3600, :task_list => "test"} }
2389
+ workflow(:entry_point) { {:version => "1", :default_execution_start_to_close_timeout => 600, :task_list => "test"} }
2774
2390
  def entry_point; ;end
2775
2391
  end
2776
2392
  worker = WorkflowWorker.new(@swf.client, @domain, "test", WorkflowWorkflow)
2777
2393
  worker.register
2778
2394
  client = workflow_client(@swf.client, @domain) { {:from_class => "WorkflowWorkflow"} }
2779
- execution = client.start_execution
2395
+ workflow_execution = client.start_execution
2780
2396
  worker.run_once
2781
- execution.events.map(&:event_type).last.should == "WorkflowExecutionCompleted"
2397
+ wait_for_execution(workflow_execution)
2398
+ workflow_execution.events.map(&:event_type).last.should == "WorkflowExecutionCompleted"
2782
2399
  end
2783
2400
  it "makes sure that you can use with_opts with workflow_client" do
2784
2401
  class WorkflowWorkflow
2785
2402
  extend Workflows
2786
- workflow(:entry_point) { {:version => "1", :execution_start_to_close_timeout => 3600, :task_list => "test"} }
2403
+ workflow(:entry_point) { {:version => "1", :default_execution_start_to_close_timeout => 600, :task_list => "test"} }
2787
2404
  def entry_point; ;end
2788
2405
  end
2789
2406
  worker = WorkflowWorker.new(@swf.client, @domain, "Foobarbaz", WorkflowWorkflow)
2790
2407
  worker.register
2791
2408
  client = workflow_client(@swf.client, @domain) { {:from_class => "WorkflowWorkflow"} }
2792
- execution = client.with_opts(:task_list => "Foobarbaz").start_execution
2409
+ workflow_execution = client.with_opts(:task_list => "Foobarbaz").start_execution
2793
2410
  worker.run_once
2794
- execution.events.map(&:event_type).last.should == "WorkflowExecutionCompleted"
2411
+ wait_for_execution(workflow_execution)
2412
+ workflow_execution.events.map(&:event_type).last.should == "WorkflowExecutionCompleted"
2795
2413
  end
2796
2414
 
2797
2415
  it "makes sure you can use with_opts with activity_client" do
@@ -2801,7 +2419,7 @@ describe "RubyFlowDecider" do
2801
2419
  {
2802
2420
  :version => 1,
2803
2421
  :default_task_list => "options_test",
2804
- :default_task_heartbeat_timeout => "3600",
2422
+ :default_task_heartbeat_timeout => "600",
2805
2423
  :default_task_schedule_to_close_timeout => "60",
2806
2424
  :default_task_schedule_to_start_timeout => "60",
2807
2425
  :default_task_start_to_close_timeout => "60",
@@ -2810,16 +2428,17 @@ describe "RubyFlowDecider" do
2810
2428
  end
2811
2429
  class WorkflowWorkflow
2812
2430
  extend Workflows
2813
- workflow(:entry_point) { {:version => "1", :execution_start_to_close_timeout => 3600, :task_list => "test"} }
2431
+ workflow(:entry_point) { {:version => "1", :default_execution_start_to_close_timeout => 600, :task_list => "test"} }
2814
2432
 
2815
2433
  def entry_point; ;end
2816
2434
  end
2817
2435
  worker = WorkflowWorker.new(@swf.client, @domain, "Foobarbaz", WorkflowWorkflow)
2818
2436
  worker.register
2819
2437
  client = workflow_client(@swf.client, @domain) { {:from_class => "WorkflowWorkflow"} }
2820
- execution = client.with_opts(:task_list => "Foobarbaz").start_execution
2438
+ workflow_execution = client.with_opts(:task_list => "Foobarbaz").start_execution
2821
2439
  worker.run_once
2822
- execution.events.map(&:event_type).last.should == "WorkflowExecutionCompleted"
2440
+ wait_for_execution(workflow_execution)
2441
+ workflow_execution.events.map(&:event_type).last.should == "WorkflowExecutionCompleted"
2823
2442
  end
2824
2443
 
2825
2444
  it "makes sure that workflow errors out on schedule_activity_task_failed" do
@@ -2833,17 +2452,18 @@ describe "RubyFlowDecider" do
2833
2452
  end
2834
2453
  class WorkflowWorkflow
2835
2454
  extend Workflows
2836
- workflow(:entry_point) { {:version => "1", :execution_start_to_close_timeout => 3600, :task_list => "test"} }
2455
+ workflow(:entry_point) { {:version => "1", :default_execution_start_to_close_timeout => 600, :task_list => "test"} }
2837
2456
  activity_client(:client) { {:version => "1", :from_class => "BadActivityActivity"} }
2838
2457
  def entry_point; client.run_activity1; end
2839
2458
  end
2840
2459
  worker = WorkflowWorker.new(@swf.client, @domain, "Foobarbaz", WorkflowWorkflow)
2841
2460
  worker.register
2842
2461
  client = workflow_client(@swf.client, @domain) { {:from_class => "WorkflowWorkflow"} }
2843
- execution = client.with_opts(:task_list => "Foobarbaz").start_execution
2462
+ workflow_execution = client.with_opts(:task_list => "Foobarbaz").start_execution
2844
2463
  worker.run_once
2845
2464
  worker.run_once
2846
- execution.events.map(&:event_type).last.should == "WorkflowExecutionFailed"
2465
+ wait_for_execution(workflow_execution)
2466
+ workflow_execution.events.map(&:event_type).last.should == "WorkflowExecutionFailed"
2847
2467
  end
2848
2468
 
2849
2469
  it "makes sure that you can have arbitrary activity names with from_class" do
@@ -2851,7 +2471,7 @@ describe "RubyFlowDecider" do
2851
2471
  @activity_class.class_eval do
2852
2472
  activity :test do
2853
2473
  {
2854
- :default_task_heartbeat_timeout => "3600",
2474
+ :default_task_heartbeat_timeout => "600",
2855
2475
  :default_task_list => task_list,
2856
2476
  :default_task_schedule_to_close_timeout => "20",
2857
2477
  :default_task_schedule_to_start_timeout => "20",
@@ -2863,7 +2483,7 @@ describe "RubyFlowDecider" do
2863
2483
  def test; end
2864
2484
  end
2865
2485
  $activity_class = @activity_class
2866
- execution = @my_workflow_client.start_execution
2486
+ workflow_execution = @my_workflow_client.start_execution
2867
2487
  @activity_worker = ActivityWorker.new(@swf.client, @domain, "arbitrary_with_from_class", @activity_class)
2868
2488
  @activity_worker.register
2869
2489
  @workflow_class.class_eval do
@@ -2875,7 +2495,8 @@ describe "RubyFlowDecider" do
2875
2495
  @worker.run_once
2876
2496
  @activity_worker.run_once
2877
2497
  @worker.run_once
2878
- execution.events.map(&:event_type).last.should == "WorkflowExecutionCompleted"
2498
+ wait_for_execution(workflow_execution)
2499
+ workflow_execution.events.map(&:event_type).last.should == "WorkflowExecutionCompleted"
2879
2500
  end
2880
2501
 
2881
2502
  it "makes sure that you can have arbitrary activity names" do
@@ -2887,7 +2508,7 @@ describe "RubyFlowDecider" do
2887
2508
  {
2888
2509
  :default_task_list => "arbitrary_test",
2889
2510
  :version => "1",
2890
- :default_task_heartbeat_timeout => "3600",
2511
+ :default_task_heartbeat_timeout => "600",
2891
2512
  :default_task_schedule_to_close_timeout => "60",
2892
2513
  :default_task_schedule_to_start_timeout => "60",
2893
2514
  :default_task_start_to_close_timeout => "60",
@@ -2908,17 +2529,18 @@ describe "RubyFlowDecider" do
2908
2529
  activity_worker = ActivityWorker.new(@swf.client, @domain, "arbitrary_test", ArbitraryActivity)
2909
2530
  activity_worker.register
2910
2531
  my_workflow_factory = workflow_factory @swf.client, @domain do |options|
2911
- options.workflow_name = "ArbitraryWorkflow"
2912
- options.execution_start_to_close_timeout = 3600
2913
- options.task_start_to_close_timeout = 10
2914
- options.child_policy = :REQUEST_CANCEL
2915
- options.task_list = "arbitrary_test"
2532
+ options.workflow_name = "ArbitraryWorkflow"
2533
+ options.execution_start_to_close_timeout = 600
2534
+ options.task_start_to_close_timeout = 10
2535
+ options.child_policy = :REQUEST_CANCEL
2536
+ options.task_list = "arbitrary_test"
2916
2537
  end
2917
- execution = my_workflow_factory.get_client.start_execution
2538
+ workflow_execution = my_workflow_factory.get_client.start_execution
2918
2539
  worker.run_once
2919
2540
  activity_worker.run_once
2920
2541
  worker.run_once
2921
- execution.events.map(&:event_type).last.should == "WorkflowExecutionCompleted"
2542
+ wait_for_execution(workflow_execution)
2543
+ workflow_execution.events.map(&:event_type).last.should == "WorkflowExecutionCompleted"
2922
2544
  end
2923
2545
  it "makes sure that exponential_retry's max_attempts works correctly" do
2924
2546
  general_test(:task_list => "exponential_retry_test_max_attempts", :class_name => "ExponentialRetryMaxAttempts")
@@ -2951,6 +2573,7 @@ describe "RubyFlowDecider" do
2951
2573
  # Finally, fail
2952
2574
  @worker.run_once
2953
2575
 
2576
+ wait_for_execution(workflow_execution)
2954
2577
  events = workflow_execution.events.map(&:event_type)
2955
2578
  events.count("WorkflowExecutionFailed").should == 1
2956
2579
  (events.count("ActivityTaskFailed") + events.count("ActivityTaskTimedOut")).should >= 3
@@ -2989,6 +2612,7 @@ describe "RubyFlowDecider" do
2989
2612
 
2990
2613
  @worker.run_once
2991
2614
 
2615
+ wait_for_execution(workflow_execution)
2992
2616
  events = workflow_execution.events.map(&:event_type)
2993
2617
  events.count("WorkflowExecutionFailed").should == 1
2994
2618
  (events.count("ActivityTaskFailed") + events.count("ActivityTaskTimedOut")).should >= 3
@@ -3028,6 +2652,7 @@ describe "RubyFlowDecider" do
3028
2652
  # Finally, fail, catch, and succeed
3029
2653
  @worker.run_once
3030
2654
 
2655
+ wait_for_execution(workflow_execution)
3031
2656
  events = workflow_execution.events.map(&:event_type)
3032
2657
  events.count("WorkflowExecutionCompleted").should == 1
3033
2658
  (events.count("ActivityTaskFailed") + events.count("ActivityTaskTimedOut")).should >= 3
@@ -3042,6 +2667,9 @@ describe "RubyFlowDecider" do
3042
2667
  end
3043
2668
  workflow_execution = @my_workflow_client.start_execution
3044
2669
  @worker.run_once
2670
+ @activity_worker.run_once
2671
+ @worker.run_once
2672
+ wait_for_execution(workflow_execution)
3045
2673
  # The default registered is 20, we want to make sure we overrode it
3046
2674
  workflow_execution.events.to_a[4].attributes[:start_to_close_timeout].should == 120
3047
2675
  end
@@ -3068,6 +2696,7 @@ describe "RubyFlowDecider" do
3068
2696
  @worker.run_once
3069
2697
  @activity_worker.run_once
3070
2698
  @worker.run_once
2699
+ wait_for_execution(workflow_execution)
3071
2700
  workflow_execution.events.map(&:event_type).last.should == "WorkflowExecutionCompleted"
3072
2701
  end
3073
2702
 
@@ -3103,6 +2732,8 @@ describe "RubyFlowDecider" do
3103
2732
  @worker.run_once
3104
2733
  sleep 10
3105
2734
  @worker.run_once
2735
+ wait_for_execution(workflow_execution)
2736
+ forking_executor.shutdown(1)
3106
2737
  # If we didn't cancel, the activity would fail
3107
2738
  workflow_execution.events.map(&:event_type).last.should == "WorkflowExecutionCompleted"
3108
2739
  end
@@ -3124,7 +2755,7 @@ describe "RubyFlowDecider" do
3124
2755
  workflow_execution = @my_workflow_client.start_execution
3125
2756
  @worker.run_once
3126
2757
  activity_worker.run_once
3127
- workflow_execution.events.map(&:event_type).last.should == "ActivityTaskStarted"
2758
+ workflow_execution.events.map(&:event_type).should include("ActivityTaskStarted")
3128
2759
  end
3129
2760
 
3130
2761
  it "makes sure that exponential_retry allows you to capture the error" do
@@ -3164,6 +2795,7 @@ describe "RubyFlowDecider" do
3164
2795
  # Finally, fail
3165
2796
  @worker.run_once
3166
2797
 
2798
+ wait_for_execution(workflow_execution)
3167
2799
  events = workflow_execution.events.map(&:event_type)
3168
2800
  events.count("WorkflowExecutionCompleted").should == 1
3169
2801
  (events.count("ActivityTaskFailed") + events.count("ActivityTaskTimedOut")).should >= 3
@@ -3178,7 +2810,7 @@ describe "RubyFlowDecider" do
3178
2810
  {
3179
2811
  :default_task_list => "arbitrary_test",
3180
2812
  :version => "1",
3181
- :default_task_heartbeat_timeout => "3600",
2813
+ :default_task_heartbeat_timeout => "600",
3182
2814
  :default_task_schedule_to_close_timeout => "60",
3183
2815
  :default_task_schedule_to_start_timeout => "60",
3184
2816
  :default_task_start_to_close_timeout => "60",
@@ -3199,17 +2831,18 @@ describe "RubyFlowDecider" do
3199
2831
  activity_worker = ActivityWorker.new(@swf.client, @domain, "arbitrary_test", ActivitiesActivity)
3200
2832
  activity_worker.register
3201
2833
  my_workflow_factory = workflow_factory @swf.client, @domain do |options|
3202
- options.workflow_name = "ActivitiesWorkflow"
3203
- options.execution_start_to_close_timeout = 3600
3204
- options.task_start_to_close_timeout = 10
3205
- options.child_policy = :REQUEST_CANCEL
3206
- options.task_list = "arbitrary_test"
2834
+ options.workflow_name = "ActivitiesWorkflow"
2835
+ options.execution_start_to_close_timeout = 600
2836
+ options.task_start_to_close_timeout = 10
2837
+ options.child_policy = :REQUEST_CANCEL
2838
+ options.task_list = "arbitrary_test"
3207
2839
  end
3208
- execution = my_workflow_factory.get_client.start_execution
2840
+ workflow_execution = my_workflow_factory.get_client.start_execution
3209
2841
  worker.run_once
3210
2842
  activity_worker.run_once
3211
2843
  worker.run_once
3212
- execution.events.map(&:event_type).last.should == "WorkflowExecutionCompleted"
2844
+ wait_for_execution(workflow_execution)
2845
+ workflow_execution.events.map(&:event_type).last.should == "WorkflowExecutionCompleted"
3213
2846
  end
3214
2847
 
3215
2848
  it "makes sure that you can't have a '.' in prefix name" do
@@ -3224,15 +2857,16 @@ describe "RubyFlowDecider" do
3224
2857
  worker = WorkflowWorker.new(@swf.client, @domain, "arbitrary_test", ArbitraryWorkflow)
3225
2858
  worker.register
3226
2859
  my_workflow_factory = workflow_factory @swf.client, @domain do |options|
3227
- options.workflow_name = "ArbitraryWorkflow"
3228
- options.execution_start_to_close_timeout = 3600
3229
- options.task_start_to_close_timeout = 10
3230
- options.child_policy = :REQUEST_CANCEL
3231
- options.task_list = "arbitrary_test"
2860
+ options.workflow_name = "ArbitraryWorkflow"
2861
+ options.execution_start_to_close_timeout = 600
2862
+ options.task_start_to_close_timeout = 10
2863
+ options.child_policy = :REQUEST_CANCEL
2864
+ options.task_list = "arbitrary_test"
3232
2865
  end
3233
- execution = my_workflow_factory.get_client.start_execution
2866
+ workflow_execution = my_workflow_factory.get_client.start_execution
3234
2867
  worker.run_once
3235
- execution.events.map(&:event_type).last.should == "WorkflowExecutionFailed"
2868
+ wait_for_execution(workflow_execution)
2869
+ workflow_execution.events.map(&:event_type).last.should == "WorkflowExecutionFailed"
3236
2870
  end
3237
2871
 
3238
2872
  it "ensures that reregistering with different values without changing the version will alert you" do
@@ -3265,7 +2899,7 @@ describe "RubyFlowDecider" do
3265
2899
  activity :foo do |opt|
3266
2900
  opt.default_task_list = "arbitrary_test"
3267
2901
  opt.version = "1"
3268
- opt.default_task_heartbeat_timeout = "3600"
2902
+ opt.default_task_heartbeat_timeout = "600"
3269
2903
  opt.default_task_schedule_to_close_timeout = "60"
3270
2904
  opt.default_task_schedule_to_start_timeout = "60"
3271
2905
  opt.default_task_start_to_close_timeout = "60"
@@ -3285,33 +2919,34 @@ describe "RubyFlowDecider" do
3285
2919
  activity_worker = ActivityWorker.new(@swf.client, @domain, "arbitrary_test", ArbitraryActivity)
3286
2920
  activity_worker.register
3287
2921
  my_workflow_factory = workflow_factory @swf.client, @domain do |options|
3288
- options.workflow_name = "ArbitraryWorkflow"
3289
- options.execution_start_to_close_timeout = 3600
3290
- options.task_start_to_close_timeout = 10
3291
- options.child_policy = :REQUEST_CANCEL
3292
- options.task_list = "arbitrary_test"
2922
+ options.workflow_name = "ArbitraryWorkflow"
2923
+ options.execution_start_to_close_timeout = 600
2924
+ options.task_start_to_close_timeout = 10
2925
+ options.child_policy = :REQUEST_CANCEL
2926
+ options.task_list = "arbitrary_test"
3293
2927
  end
3294
- execution = my_workflow_factory.get_client.start_execution
2928
+ workflow_execution = my_workflow_factory.get_client.start_execution
3295
2929
  worker.run_once
3296
2930
  activity_worker.run_once
3297
2931
  worker.run_once
3298
- execution.events.map(&:event_type).last.should == "WorkflowExecutionCompleted"
2932
+ wait_for_execution(workflow_execution)
2933
+ workflow_execution.events.map(&:event_type).last.should == "WorkflowExecutionCompleted"
3299
2934
  end
3300
2935
 
3301
2936
  describe "Miscellaneous tests" do
3302
2937
  it "will test whether the service client uses the correct user-agent-prefix" do
3303
2938
 
3304
- swf, domain, _ = setup_swf
3305
- swf.client.config.user_agent_prefix.should == "ruby-flow"
2939
+ domain = get_test_domain
2940
+ domain.client.config.user_agent_prefix.should == "ruby-flow"
3306
2941
 
3307
- response = swf.client.list_domains({:registration_status => "REGISTERED"})
2942
+ response = domain.client.list_domains({:registration_status => "REGISTERED"})
3308
2943
  result = response.http_request.headers["user-agent"]
3309
2944
 
3310
2945
  result.should match(/^ruby-flow/)
3311
2946
  end
3312
2947
 
3313
2948
  it "will test whether from_class can take in non-strings" do
3314
- swf, domain, _ = setup_swf
2949
+ domain = get_test_domain
3315
2950
 
3316
2951
  class ActivityActivity
3317
2952
  extend Activity
@@ -3323,18 +2958,18 @@ describe "RubyFlowDecider" do
3323
2958
  end
3324
2959
  class WorkflowWorkflow
3325
2960
  extend Workflows
3326
- workflow(:entry_point) { {:version => "1", :execution_start_to_close_timeout => 3600, :task_list => "test"} }
2961
+ workflow(:entry_point) { {:version => "1", :default_execution_start_to_close_timeout => 600, :task_list => "test"} }
3327
2962
  activity_client(:activity) { {:version => "1", :from_class => ActivityActivity} }
3328
2963
  def entry_point
3329
2964
  activity.activity1
3330
2965
  end
3331
2966
  end
3332
2967
 
3333
- client = workflow_client(swf.client, domain) { {:from_class => WorkflowWorkflow} }
2968
+ client = workflow_client(domain.client, domain) { {:from_class => WorkflowWorkflow} }
3334
2969
  client.is_execution_method(:entry_point).should == true
3335
2970
  end
3336
2971
  it "tests whether a forking executor will not accept work when it has no free workers" do
3337
- swf, domain, _ = setup_swf
2972
+ domain = get_test_domain
3338
2973
 
3339
2974
  class ForkingTestActivity
3340
2975
  extend Activity
@@ -3344,33 +2979,33 @@ describe "RubyFlowDecider" do
3344
2979
  :default_task_list => "forking_executor_test",
3345
2980
  :default_task_schedule_to_start_timeout => 120,
3346
2981
  :default_task_start_to_close_timeout => 120,
3347
- :default_task_heartbeat_timeout => "3600"
2982
+ :default_task_heartbeat_timeout => "600"
3348
2983
  }
3349
2984
  end
3350
2985
  def activity1; sleep 10; end
3351
2986
  end
3352
2987
  class ForkingTestWorkflow
3353
2988
  extend Workflows
3354
- workflow(:entry_point) { {:version => "1", :execution_start_to_close_timeout => 3600, :task_list => "forking_executor_test"} }
2989
+ workflow(:entry_point) { {:version => "1", :default_execution_start_to_close_timeout => 600, :task_list => "forking_executor_test"} }
3355
2990
  activity_client(:activity) { {:version => "1", :from_class => ForkingTestActivity} }
3356
2991
  def entry_point
3357
2992
  3.times { activity.send_async(:activity1) }
3358
2993
  end
3359
2994
  end
3360
2995
 
3361
- worker = WorkflowWorker.new(swf.client, domain, "forking_executor_test", ForkingTestWorkflow)
2996
+ worker = WorkflowWorker.new(domain.client, domain, "forking_executor_test", ForkingTestWorkflow)
3362
2997
  worker.register
3363
2998
 
3364
- activity_worker = ActivityWorker.new(swf.client, domain, "forking_executor_test", ForkingTestActivity) { { :execution_workers => 1 } }
2999
+ activity_worker = ActivityWorker.new(domain.client, domain, "forking_executor_test", ForkingTestActivity) { { :execution_workers => 1 } }
3365
3000
  activity_worker.register
3366
3001
 
3367
- client = workflow_client(swf.client, domain) { {:from_class => ForkingTestWorkflow} }
3002
+ client = workflow_client(domain.client, domain) { {:from_class => ForkingTestWorkflow} }
3368
3003
 
3369
3004
  workflow_execution = client.start_execution
3370
3005
  forking_executor = ForkingExecutor.new(:max_workers => 3)
3371
3006
  forking_executor.execute { worker.start }
3372
3007
  forking_executor.execute { activity_worker.start }
3373
- sleep 20
3008
+ wait_for_execution(workflow_execution)
3374
3009
  history = workflow_execution.events.map(&:event_type)
3375
3010
  current_depth = 0
3376
3011
  0.upto(history.length) do |i|