aws-flow 2.3.1 → 2.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. checksums.yaml +8 -8
  2. data/aws-flow.gemspec +3 -2
  3. data/bin/aws-flow-ruby +1 -1
  4. data/bin/aws-flow-utils +5 -0
  5. data/lib/aws/decider.rb +7 -0
  6. data/lib/aws/decider/async_retrying_executor.rb +1 -1
  7. data/lib/aws/decider/data_converter.rb +161 -0
  8. data/lib/aws/decider/decider.rb +27 -14
  9. data/lib/aws/decider/flow_defaults.rb +28 -0
  10. data/lib/aws/decider/implementation.rb +0 -1
  11. data/lib/aws/decider/options.rb +2 -2
  12. data/lib/aws/decider/starter.rb +207 -0
  13. data/lib/aws/decider/task_poller.rb +4 -4
  14. data/lib/aws/decider/utilities.rb +38 -0
  15. data/lib/aws/decider/version.rb +1 -1
  16. data/lib/aws/decider/worker.rb +8 -7
  17. data/lib/aws/decider/workflow_definition_factory.rb +1 -1
  18. data/lib/aws/runner.rb +146 -65
  19. data/lib/aws/templates.rb +4 -0
  20. data/lib/aws/templates/activity.rb +69 -0
  21. data/lib/aws/templates/base.rb +87 -0
  22. data/lib/aws/templates/default.rb +146 -0
  23. data/lib/aws/templates/starter.rb +256 -0
  24. data/lib/aws/utils.rb +270 -0
  25. data/spec/aws/decider/integration/activity_spec.rb +7 -1
  26. data/spec/aws/decider/integration/data_converter_spec.rb +39 -0
  27. data/spec/aws/decider/integration/integration_spec.rb +12 -5
  28. data/spec/aws/decider/integration/options_spec.rb +23 -9
  29. data/spec/aws/decider/integration/starter_spec.rb +209 -0
  30. data/spec/aws/decider/unit/data_converter_spec.rb +276 -0
  31. data/spec/aws/decider/unit/decider_spec.rb +1360 -1386
  32. data/spec/aws/decider/unit/options_spec.rb +21 -22
  33. data/spec/aws/decider/unit/retry_spec.rb +8 -0
  34. data/spec/aws/decider/unit/starter_spec.rb +159 -0
  35. data/spec/aws/runner/integration/runner_integration_spec.rb +2 -3
  36. data/spec/aws/runner/unit/runner_unit_spec.rb +128 -38
  37. data/spec/aws/templates/unit/activity_spec.rb +89 -0
  38. data/spec/aws/templates/unit/base_spec.rb +72 -0
  39. data/spec/aws/templates/unit/default_spec.rb +141 -0
  40. data/spec/aws/templates/unit/starter_spec.rb +271 -0
  41. data/spec/spec_helper.rb +9 -11
  42. metadata +41 -4
@@ -16,1569 +16,1543 @@
16
16
  require 'yaml'
17
17
  require_relative 'setup'
18
18
 
19
- describe ActivityDefinition do
20
- class MyActivity
21
- extend Activity
22
- def test_three_arguments(a, b, c)
23
- a + b + c
24
- end
25
- def test_no_arguments()
26
- :no_arguments
27
- end
28
- def test_one_argument(arg)
29
- arg
30
- end
31
- def test_getting_context
32
- self.activity_execution_context
33
- end
34
- activity :test_three_arguments, :test_no_arguments, :test_one_argument
35
- end
36
- it "ensures that an activity definition can handle one argument" do
37
- activity_definition = ActivityDefinition.new(MyActivity.new, :test_one_argument, nil , nil, TrivialConverter.new)
38
- activity_definition.execute(5, nil).first.should == 5
39
- end
40
- it "ensures that you can get the activity context " do
41
- activity_definition = ActivityDefinition.new(MyActivity.new, :test_getting_context, nil , nil, TrivialConverter.new)
42
- (activity_definition.execute(nil, ActivityExecutionContext.new(nil, nil, nil)).first.is_a? ActivityExecutionContext).should == true
43
- end
44
- it "ensures that the activity context gets unset after the execute" do
45
- activity_definition = ActivityDefinition.new(MyActivity.new, :test_getting_context, nil , nil, TrivialConverter.new)
46
- activity_definition.execute(nil, ActivityExecutionContext.new(nil, nil, nil))
47
- begin
48
- activity_definition.execute(nil, nil)
49
- rescue Exception => e
50
- e.backtrace.should include "No activity execution context"
51
- end
52
- end
53
- it "ensures that an activity definition can handle multiple arguments" do
54
- activity_definition = ActivityDefinition.new(MyActivity.new, :test_three_arguments, nil , nil, TrivialConverter.new)
19
+ describe "DeciderSpec" do
55
20
 
56
- activity_definition.execute([1,2,3], nil).first.should == 6
21
+ before(:all) do
22
+ @bucket = ENV['AWS_SWF_BUCKET_NAME']
23
+ ENV['AWS_SWF_BUCKET_NAME'] = nil
57
24
  end
58
- it "ensures that an activity definition can handle no arguments" do
59
- activity_definition = ActivityDefinition.new(MyActivity.new, :test_no_arguments, nil , nil, TrivialConverter.new)
60
- activity_definition.execute(nil, nil).first.should == :no_arguments
25
+ after(:all) do
26
+ ENV['AWS_SWF_BUCKET_NAME'] = @bucket
61
27
  end
62
- end
63
28
 
64
- describe WorkflowDefinitionFactory do
65
- before(:each) do
66
- class MyWorkflow
67
- extend Decider
68
- version "1"
69
- def no_arguments
29
+ describe ActivityDefinition do
30
+ class MyActivity
31
+ extend Activity
32
+ def test_three_arguments(a, b, c)
33
+ a + b + c
34
+ end
35
+ def test_no_arguments()
70
36
  :no_arguments
71
37
  end
72
- def one_argument(arg)
38
+ def test_one_argument(arg)
73
39
  arg
74
40
  end
75
- def multiple_arguments(arg1, arg2, arg3)
76
- arg3
41
+ def test_getting_context
42
+ self.activity_execution_context
77
43
  end
78
-
44
+ activity :test_three_arguments, :test_no_arguments, :test_one_argument
79
45
  end
80
- class WorkflowDefinition
81
- attr_accessor :decision_helper, :workflow_method, :converter
46
+ it "ensures that an activity definition can handle one argument" do
47
+ activity_definition = ActivityDefinition.new(MyActivity.new, :test_one_argument, nil , nil, TrivialConverter.new)
48
+ activity_definition.execute(5, nil).first.should == 5
82
49
  end
83
- end
84
- let(:fake_decision_context) { stub(:decision_helper => nil) }
85
- let(:workflow_definition) do
86
- FlowFiber.stub(:current) { Hash.new(Hash.new) }
87
- WorkflowDefinitionFactory.new(MyWorkflow, nil, nil, nil, nil, nil, nil).get_workflow_definition(fake_decision_context) end
88
- it "makes sure that workflowDefinitionFactory#get_workflow_definition returns different instances" do
89
- FlowFiber.stub(:current) { Hash.new(Hash.new) }
90
- workflow_factory = WorkflowDefinitionFactory.new(MyWorkflow, nil, nil, nil, nil, nil ,nil)
91
- first_definition = workflow_factory.get_workflow_definition(fake_decision_context)
92
- second_definition = workflow_factory.get_workflow_definition(fake_decision_context)
93
- (first_definition.object_id == second_definition.object_id).should == false
94
- end
95
- describe "Testing the input/output" do
96
- before(:each) do
97
- workflow_definition.converter = TrivialConverter.new
50
+ it "ensures that you can get the activity context " do
51
+ activity_definition = ActivityDefinition.new(MyActivity.new, :test_getting_context, nil , nil, TrivialConverter.new)
52
+ (activity_definition.execute(nil, ActivityExecutionContext.new(nil, nil, nil)).first.is_a? ActivityExecutionContext).should == true
98
53
  end
99
- it "ensures that a workflow definition can handle multiple arguments" do
100
- workflow_definition.workflow_method = :multiple_arguments
101
- AsyncScope.new do
102
- workflow_definition.execute([1, 2, 3]).get
103
- end.eventLoop
54
+ it "ensures that the activity context gets unset after the execute" do
55
+ activity_definition = ActivityDefinition.new(MyActivity.new, :test_getting_context, nil , nil, TrivialConverter.new)
56
+ activity_definition.execute(nil, ActivityExecutionContext.new(nil, nil, nil))
57
+ begin
58
+ activity_definition.execute(nil, nil)
59
+ rescue Exception => e
60
+ e.backtrace.should include "No activity execution context"
61
+ end
104
62
  end
105
- it "ensures that a workflow definition can handle no arguments" do
106
- workflow_definition.workflow_method = :no_arguments
107
- AsyncScope.new do
108
- workflow_definition.execute(nil).get.should == :no_arguments
109
- end.eventLoop
63
+ it "ensures that an activity definition can handle multiple arguments" do
64
+ activity_definition = ActivityDefinition.new(MyActivity.new, :test_three_arguments, nil , nil, TrivialConverter.new)
65
+
66
+ activity_definition.execute([1,2,3], nil).first.should == 6
110
67
  end
111
- it "ensures that a workflow definition can handle one argument" do
112
- workflow_definition.workflow_method = :one_argument
113
- AsyncScope.new do
114
- workflow_definition.execute(5).get.should == 5
115
- end.eventLoop
68
+ it "ensures that an activity definition can handle no arguments" do
69
+ activity_definition = ActivityDefinition.new(MyActivity.new, :test_no_arguments, nil , nil, TrivialConverter.new)
70
+ activity_definition.execute(nil, nil).first.should == :no_arguments
116
71
  end
117
72
  end
118
- end
119
73
 
120
- describe YAMLDataConverter do
121
- let(:converter) {YAMLDataConverter.new}
122
- %w{syck psych}.each do |engine|
123
- describe "ensures that x == load(dump(x)) is true using #{engine}" do
124
- before :all do
125
- YAML::ENGINE.yamler = engine
126
- end
127
-
128
- {
129
- Fixnum => 5,
130
- String => "Hello World",
131
- Hash => {:test => "good"},
132
- Array => ["Hello", "World", 5],
133
- Symbol => :test,
134
- NilClass => nil,
135
- }.each_pair do |klass, exemplar|
136
- it "tests #{klass}" do
137
- 1.upto(10).each do |i|
138
- converted_exemplar = exemplar
139
- i.times {converted_exemplar = converter.dump converted_exemplar}
140
- i.times {converted_exemplar = converter.load converted_exemplar}
141
- converted_exemplar.should == exemplar
142
- end
74
+ describe WorkflowDefinitionFactory do
75
+ before(:each) do
76
+ class MyWorkflow
77
+ extend Decider
78
+ version "1"
79
+ def no_arguments
80
+ :no_arguments
81
+ end
82
+ def one_argument(arg)
83
+ arg
84
+ end
85
+ def multiple_arguments(arg1, arg2, arg3)
86
+ arg3
143
87
  end
144
- end
145
88
 
146
- it 'loads exception backtraces correctly' do
147
- exemplar = Exception.new('exception')
148
- exemplar.set_backtrace(caller)
149
- converted_exemplar = converter.load(converter.dump(exemplar))
150
- converted_exemplar.should == exemplar
89
+ end
90
+ class WorkflowDefinition
91
+ attr_accessor :decision_helper, :workflow_method, :converter
92
+ end
93
+ end
94
+ let(:fake_decision_context) { stub(:decision_helper => nil) }
95
+ let(:workflow_definition) do
96
+ FlowFiber.stub(:current) { Hash.new(Hash.new) }
97
+ WorkflowDefinitionFactory.new(MyWorkflow, nil, nil, nil, nil, nil, nil).get_workflow_definition(fake_decision_context) end
98
+ it "makes sure that workflowDefinitionFactory#get_workflow_definition returns different instances" do
99
+ FlowFiber.stub(:current) { Hash.new(Hash.new) }
100
+ workflow_factory = WorkflowDefinitionFactory.new(MyWorkflow, nil, nil, nil, nil, nil ,nil)
101
+ first_definition = workflow_factory.get_workflow_definition(fake_decision_context)
102
+ second_definition = workflow_factory.get_workflow_definition(fake_decision_context)
103
+ (first_definition.object_id == second_definition.object_id).should == false
104
+ end
105
+ describe "Testing the input/output" do
106
+ before(:each) do
107
+ workflow_definition.converter = TrivialConverter.new
108
+ end
109
+ it "ensures that a workflow definition can handle multiple arguments" do
110
+ workflow_definition.workflow_method = :multiple_arguments
111
+ AsyncScope.new do
112
+ workflow_definition.execute([1, 2, 3]).get
113
+ end.eventLoop
114
+ end
115
+ it "ensures that a workflow definition can handle no arguments" do
116
+ workflow_definition.workflow_method = :no_arguments
117
+ AsyncScope.new do
118
+ workflow_definition.execute(nil).get.should == :no_arguments
119
+ end.eventLoop
120
+ end
121
+ it "ensures that a workflow definition can handle one argument" do
122
+ workflow_definition.workflow_method = :one_argument
123
+ AsyncScope.new do
124
+ workflow_definition.execute(5).get.should == 5
125
+ end.eventLoop
151
126
  end
152
127
  end
153
128
  end
154
- end
155
129
 
156
- describe Workflows do
130
+ describe Workflows do
157
131
 
158
- context "#workflow" do
132
+ context "#workflow" do
159
133
 
160
- it "makes sure we can specify multiple workflows" do
161
- class MultipleWorkflowsTest1_Workflow
162
- extend AWS::Flow::Workflows
163
- workflow :workflow_a do
164
- {
165
- version: "1.0",
166
- default_execution_start_to_close_timeout: 600,
167
- default_task_list: "tasklist_a"
168
- }
134
+ it "makes sure we can specify multiple workflows" do
135
+ class MultipleWorkflowsTest1_Workflow
136
+ extend AWS::Flow::Workflows
137
+ workflow :workflow_a do
138
+ {
139
+ version: "1.0",
140
+ default_execution_start_to_close_timeout: 600,
141
+ default_task_list: "tasklist_a"
142
+ }
143
+ end
144
+ workflow :workflow_b do
145
+ {
146
+ version: "1.0",
147
+ default_execution_start_to_close_timeout: 300,
148
+ default_task_list: "tasklist_b"
149
+ }
150
+ end
169
151
  end
170
- workflow :workflow_b do
171
- {
172
- version: "1.0",
173
- default_execution_start_to_close_timeout: 300,
174
- default_task_list: "tasklist_b"
175
- }
152
+ MultipleWorkflowsTest1_Workflow.workflows.count.should == 2
153
+ MultipleWorkflowsTest1_Workflow.workflows.map(&:name).should == ["MultipleWorkflowsTest1_Workflow.workflow_a", "MultipleWorkflowsTest1_Workflow.workflow_b"]
154
+ MultipleWorkflowsTest1_Workflow.workflows.map(&:options).map(&:default_task_list).should == ["tasklist_a", "tasklist_b"]
155
+ end
156
+
157
+ it "makes sure we can pass multiple workflow names with same options" do
158
+ class MultipleWorkflowsTest2_Workflow
159
+ extend AWS::Flow::Workflows
160
+ workflow :workflow_a, :workflow_b do
161
+ {
162
+ version: "1.0",
163
+ default_task_list: "tasklist_a"
164
+ }
165
+ end
176
166
  end
177
- end
178
- MultipleWorkflowsTest1_Workflow.workflows.count.should == 2
179
- MultipleWorkflowsTest1_Workflow.workflows.map(&:name).should == ["MultipleWorkflowsTest1_Workflow.workflow_a", "MultipleWorkflowsTest1_Workflow.workflow_b"]
180
- MultipleWorkflowsTest1_Workflow.workflows.map(&:options).map(&:default_task_list).should == ["tasklist_a", "tasklist_b"]
181
- end
167
+ MultipleWorkflowsTest2_Workflow.workflows.count.should == 2
168
+ MultipleWorkflowsTest2_Workflow.workflows.map(&:name).should == ["MultipleWorkflowsTest2_Workflow.workflow_a", "MultipleWorkflowsTest2_Workflow.workflow_b"]
169
+ MultipleWorkflowsTest2_Workflow.workflows.map(&:options).map(&:default_task_list).should == ["tasklist_a", "tasklist_a"]
182
170
 
183
- it "makes sure we can pass multiple workflow names with same options" do
184
- class MultipleWorkflowsTest2_Workflow
185
- extend AWS::Flow::Workflows
186
- workflow :workflow_a, :workflow_b do
187
- {
188
- version: "1.0",
189
- default_task_list: "tasklist_a"
190
- }
191
- end
192
171
  end
193
- MultipleWorkflowsTest2_Workflow.workflows.count.should == 2
194
- MultipleWorkflowsTest2_Workflow.workflows.map(&:name).should == ["MultipleWorkflowsTest2_Workflow.workflow_a", "MultipleWorkflowsTest2_Workflow.workflow_b"]
195
- MultipleWorkflowsTest2_Workflow.workflows.map(&:options).map(&:default_task_list).should == ["tasklist_a", "tasklist_a"]
196
-
197
172
  end
198
173
  end
199
- end
200
174
 
201
- describe WorkflowFactory do
202
- it "ensures that you can create a workflow_client without access to the Workflow definition" do
203
- workflow_type_object = double("workflow_type", :name => "NonExistantWorkflow.some_entry_method", :start_execution => "" )
204
- domain = FakeDomain.new(workflow_type_object)
205
- swf_client = FakeServiceClient.new
206
- my_workflow_factory = workflow_factory(swf_client, domain) do |options|
207
- options.workflow_name = "NonExistantWorkflow"
208
- options.execution_method = "some_entry_method"
175
+ describe WorkflowFactory do
176
+ it "ensures that you can create a workflow_client without access to the Workflow definition" do
177
+ workflow_type_object = double("workflow_type", :name => "NonExistantWorkflow.some_entry_method", :start_execution => "" )
178
+ domain = FakeDomain.new(workflow_type_object)
179
+ swf_client = FakeServiceClient.new
180
+ my_workflow_factory = workflow_factory(swf_client, domain) do |options|
181
+ options.workflow_name = "NonExistantWorkflow"
182
+ options.execution_method = "some_entry_method"
183
+ end
184
+ # We want to make sure that we get to trying to start the execution on the
185
+ # workflow_type. The workflow_type will be nil, since we return an empty
186
+ # array in the domain.
187
+ my_workflow_factory.get_client.start_execution
209
188
  end
210
- # We want to make sure that we get to trying to start the execution on the
211
- # workflow_type. The workflow_type will be nil, since we return an empty
212
- # array in the domain.
213
- my_workflow_factory.get_client.start_execution
214
189
  end
215
- end
216
190
 
217
- describe "FakeHistory" do
218
- before(:all) do
219
- class WorkflowClock
220
- alias_method :old_current_time, :current_time
221
- def current_time
222
- Time.now
191
+ describe "FakeHistory" do
192
+ before(:all) do
193
+ class WorkflowClock
194
+ alias_method :old_current_time, :current_time
195
+ def current_time
196
+ Time.now
197
+ end
223
198
  end
224
199
  end
225
- end
226
- after(:all) do
227
- class WorkflowClock
228
- alias_method :current_time, :old_current_time
200
+ after(:all) do
201
+ class WorkflowClock
202
+ alias_method :current_time, :old_current_time
203
+ end
204
+
229
205
  end
230
206
 
231
- end
232
207
 
208
+ it "reproduces a bug found by a customer" do
209
+ class BadWorkflow
210
+ class << self
211
+ attr_accessor :task_list
212
+ end
213
+ extend Decider
233
214
 
234
- it "reproduces a bug found by a customer" do
235
- class BadWorkflow
236
- class << self
237
- attr_accessor :task_list
215
+ version "1"
216
+ entry_point :entry_point
217
+ def entry_point
218
+ # pass
219
+ end
238
220
  end
239
- extend Decider
221
+ workflow_type_object = double("workflow_type", :name => "BadWorkflow.entry_point", :start_execution => "" )
222
+ domain = FakeDomain.new(workflow_type_object)
223
+
240
224
 
241
- version "1"
242
- entry_point :entry_point
243
- def entry_point
244
- # pass
225
+ swf_client = FakeServiceClient.new
226
+ task_list = "BadWorkflow_tasklist"
227
+ worker = SynchronousWorkflowWorker.new(swf_client, domain, task_list)
228
+ worker.add_workflow_implementation(BadWorkflow)
229
+ my_workflow_factory = workflow_factory(swf_client, domain) do |options|
230
+ options.workflow_name = "BadWorkflow"
231
+ options.execution_start_to_close_timeout = 3600
232
+ options.task_list = task_list
233
+ options.task_start_to_close_timeout = 10
234
+ options.child_policy = :request_cancel
245
235
  end
246
- end
247
- workflow_type_object = double("workflow_type", :name => "BadWorkflow.entry_point", :start_execution => "" )
248
- domain = FakeDomain.new(workflow_type_object)
249
-
250
-
251
- swf_client = FakeServiceClient.new
252
- task_list = "BadWorkflow_tasklist"
253
- worker = SynchronousWorkflowWorker.new(swf_client, domain, task_list)
254
- worker.add_workflow_implementation(BadWorkflow)
255
- my_workflow_factory = workflow_factory(swf_client, domain) do |options|
256
- options.workflow_name = "BadWorkflow"
257
- options.execution_start_to_close_timeout = 3600
258
- options.task_list = task_list
259
- options.task_start_to_close_timeout = 10
260
- options.child_policy = :request_cancel
261
- end
262
- my_workflow = my_workflow_factory.get_client
263
- workflow_execution = my_workflow.start_execution(5)
236
+ my_workflow = my_workflow_factory.get_client
237
+ workflow_execution = my_workflow.start_execution(5)
264
238
 
265
239
 
266
- class SynchronousWorkflowTaskPoller < WorkflowTaskPoller
267
- def get_decision_task
268
- fake_workflow_type = FakeWorkflowType.new(nil, "BadWorkflow.entry_point", "1")
269
- TestHistoryWrapper.new(fake_workflow_type, FakeWorkflowExecution.new(nil, nil),
270
- [TestHistoryEvent.new("WorkflowExecutionStarted", 1, {:parent_initiated_event_id=>0, :child_policy=>:request_cancel, :execution_start_to_close_timeout=>3600, :task_start_to_close_timeout=>5, :workflow_type=> fake_workflow_type, :task_list=>"BadWorkflow"}),
271
- TestHistoryEvent.new("DecisionTaskScheduled", 2, {:parent_initiated_event_id=>0, :child_policy=>:request_cancel, :execution_start_to_close_timeout=>3600, :task_start_to_close_timeout=>5, :workflow_type=> fake_workflow_type, :task_list=>"BadWorkflow"}),
272
- TestHistoryEvent.new("DecisionTaskStarted", 3, {:scheduled_event_id=>2, :identity=>"some_identity"}),
273
- TestHistoryEvent.new("DecisionTaskTimedOut", 4, {:scheduled_event_id=>2, :timeout_type=>"START_TO_CLOSE", :started_event_id=>3})
274
- ])
240
+ class SynchronousWorkflowTaskPoller < WorkflowTaskPoller
241
+ def get_decision_task
242
+ fake_workflow_type = FakeWorkflowType.new(nil, "BadWorkflow.entry_point", "1")
243
+ TestHistoryWrapper.new(fake_workflow_type, FakeWorkflowExecution.new(nil, nil),
244
+ [TestHistoryEvent.new("WorkflowExecutionStarted", 1, {:parent_initiated_event_id=>0, :child_policy=>:request_cancel, :execution_start_to_close_timeout=>3600, :task_start_to_close_timeout=>5, :workflow_type=> fake_workflow_type, :task_list=>"BadWorkflow"}),
245
+ TestHistoryEvent.new("DecisionTaskScheduled", 2, {:parent_initiated_event_id=>0, :child_policy=>:request_cancel, :execution_start_to_close_timeout=>3600, :task_start_to_close_timeout=>5, :workflow_type=> fake_workflow_type, :task_list=>"BadWorkflow"}),
246
+ TestHistoryEvent.new("DecisionTaskStarted", 3, {:scheduled_event_id=>2, :identity=>"some_identity"}),
247
+ TestHistoryEvent.new("DecisionTaskTimedOut", 4, {:scheduled_event_id=>2, :timeout_type=>"START_TO_CLOSE", :started_event_id=>3})
248
+ ])
275
249
 
250
+ end
276
251
  end
277
- end
278
- worker.start
279
- # @forking_executor.execute { activity_worker.start }
280
-
281
- # worker.start
282
- swf_client.trace.first[:decisions].first[:decision_type].should ==
283
- "CompleteWorkflowExecution"
284
- end
285
-
286
- it "reproduces the ActivityTaskTimedOut problem" do
287
- class SynchronousWorkflowTaskPoller < WorkflowTaskPoller
288
- def get_decision_task
289
- fake_workflow_type = FakeWorkflowType.new(nil, "BadWorkflow.start", "1")
290
- TestHistoryWrapper.new(fake_workflow_type, FakeWorkflowExecution.new(nil, nil),
291
- [
292
- TestHistoryEvent.new("WorkflowExecutionStarted", 1, {}),
293
- TestHistoryEvent.new("DecisionTaskScheduled", 2, {}),
294
- TestHistoryEvent.new("DecisionTaskStarted", 3, {}),
295
- TestHistoryEvent.new("DecisionTaskCompleted", 4, {}),
296
- TestHistoryEvent.new("ActivityTaskScheduled", 5, {:activity_id => "Activity1"}),
297
- TestHistoryEvent.new("ActivityTaskStarted", 6, {}),
298
- TestHistoryEvent.new("ActivityTaskTimedOut", 7, {:scheduled_event_id => 5, :timeout_type => "START_TO_CLOSE"}),
299
- ])
252
+ worker.start
253
+ # @forking_executor.execute { activity_worker.start }
254
+
255
+ # worker.start
256
+ swf_client.trace.first[:decisions].first[:decision_type].should ==
257
+ "CompleteWorkflowExecution"
258
+ end
259
+
260
+ it "reproduces the ActivityTaskTimedOut problem" do
261
+ class SynchronousWorkflowTaskPoller < WorkflowTaskPoller
262
+ def get_decision_task
263
+ fake_workflow_type = FakeWorkflowType.new(nil, "BadWorkflow.start", "1")
264
+ TestHistoryWrapper.new(fake_workflow_type, FakeWorkflowExecution.new(nil, nil),
265
+ [
266
+ TestHistoryEvent.new("WorkflowExecutionStarted", 1, {}),
267
+ TestHistoryEvent.new("DecisionTaskScheduled", 2, {}),
268
+ TestHistoryEvent.new("DecisionTaskStarted", 3, {}),
269
+ TestHistoryEvent.new("DecisionTaskCompleted", 4, {}),
270
+ TestHistoryEvent.new("ActivityTaskScheduled", 5, {:activity_id => "Activity1"}),
271
+ TestHistoryEvent.new("ActivityTaskStarted", 6, {}),
272
+ TestHistoryEvent.new("ActivityTaskTimedOut", 7, {:scheduled_event_id => 5, :timeout_type => "START_TO_CLOSE"}),
273
+ ])
274
+ end
300
275
  end
301
- end
302
276
 
303
- class BadWorkflow
304
- extend AWS::Flow::Workflows
305
- workflow :start do
306
- {
307
- version: "1",
308
- default_execution_start_to_close_timeout: 3600,
309
- default_task_list: "BadWorkflow_tasklist",
310
- default_task_start_to_close_timeout: 10,
311
- default_child_policy: :request_cancel
312
- }
313
- end
314
- activity_client(:activity) do
315
- {
316
- prefix_name: "BadActivity",
317
- version: "1",
318
- default_task_heartbeat_timeout: "3600",
319
- default_task_list: "BadWorkflow",
320
- default_task_schedule_to_close_timeout: "30",
321
- default_task_schedule_to_start_timeout: "30",
322
- default_task_start_to_close_timeout: "10",
323
- }
324
- end
325
- def start
326
- activity.run_activity1
327
- activity.run_activity2
277
+ class BadWorkflow
278
+ extend AWS::Flow::Workflows
279
+ workflow :start do
280
+ {
281
+ version: "1",
282
+ default_execution_start_to_close_timeout: 3600,
283
+ default_task_list: "BadWorkflow_tasklist",
284
+ default_task_start_to_close_timeout: 10,
285
+ default_child_policy: :request_cancel
286
+ }
287
+ end
288
+ activity_client(:activity) do
289
+ {
290
+ prefix_name: "BadActivity",
291
+ version: "1",
292
+ default_task_heartbeat_timeout: "3600",
293
+ default_task_list: "BadWorkflow",
294
+ default_task_schedule_to_close_timeout: "30",
295
+ default_task_schedule_to_start_timeout: "30",
296
+ default_task_start_to_close_timeout: "10",
297
+ }
298
+ end
299
+ def start
300
+ activity.run_activity1
301
+ activity.run_activity2
302
+ end
328
303
  end
329
- end
330
- workflow_type_object = FakeWorkflowType.new(nil, "BadWorkflow.start", "1.0")
331
- domain = FakeDomain.new(workflow_type_object)
304
+ workflow_type_object = FakeWorkflowType.new(nil, "BadWorkflow.start", "1.0")
305
+ domain = FakeDomain.new(workflow_type_object)
332
306
 
333
- swf_client = FakeServiceClient.new
334
- task_list = "BadWorkflow_tasklist"
335
- worker = SynchronousWorkflowWorker.new(swf_client, domain, task_list)
336
- worker.add_workflow_implementation(BadWorkflow)
337
- client = AWS::Flow::workflow_client(swf_client, domain) { { from_class: "BadWorkflow" } }
307
+ swf_client = FakeServiceClient.new
308
+ task_list = "BadWorkflow_tasklist"
309
+ worker = SynchronousWorkflowWorker.new(swf_client, domain, task_list)
310
+ worker.add_workflow_implementation(BadWorkflow)
311
+ client = AWS::Flow::workflow_client(swf_client, domain) { { from_class: "BadWorkflow" } }
338
312
 
339
- workflow_execution = client.start_execution(5)
340
- worker.start
313
+ workflow_execution = client.start_execution(5)
314
+ worker.start
341
315
 
342
- swf_client.trace.first[:decisions].first[:decision_type].should ==
343
- "FailWorkflowExecution"
344
- swf_client.trace.first[:decisions].first[:fail_workflow_execution_decision_attributes][:details].should =~
316
+ swf_client.trace.first[:decisions].first[:decision_type].should ==
317
+ "FailWorkflowExecution"
318
+ swf_client.trace.first[:decisions].first[:fail_workflow_execution_decision_attributes][:details].should =~
345
319
  /AWS::Flow::ActivityTaskTimedOutException/
346
- end
320
+ end
347
321
 
348
- it "makes sure that exponential retry can take arguments" do
349
- class SynchronousWorkflowTaskPoller < WorkflowTaskPoller
350
- def get_decision_task
351
- fake_workflow_type = FakeWorkflowType.new(nil, "BadWorkflow.entry_point", "1")
352
- TestHistoryWrapper.new(fake_workflow_type, FakeWorkflowExecution.new(nil, nil),
353
- [
354
- TestHistoryEvent.new("WorkflowExecutionStarted", 1, {}),
355
- ])
322
+ it "makes sure that exponential retry can take arguments" do
323
+ class SynchronousWorkflowTaskPoller < WorkflowTaskPoller
324
+ def get_decision_task
325
+ fake_workflow_type = FakeWorkflowType.new(nil, "BadWorkflow.entry_point", "1")
326
+ TestHistoryWrapper.new(fake_workflow_type, FakeWorkflowExecution.new(nil, nil),
327
+ [
328
+ TestHistoryEvent.new("WorkflowExecutionStarted", 1, {}),
329
+ ])
330
+ end
356
331
  end
357
- end
358
- class BadWorkflow
359
- class << self
360
- attr_accessor :task_list
332
+ class BadWorkflow
333
+ class << self
334
+ attr_accessor :task_list
335
+ end
336
+ extend Decider
337
+ version "1"
338
+ entry_point :entry_point
339
+
340
+ activity_client :activity do |options|
341
+ options.prefix_name = "BadActivity"
342
+ options.version = "1"
343
+ options.default_task_heartbeat_timeout = "3600"
344
+ options.default_task_list = "BadWorkflow"
345
+ options.default_task_schedule_to_close_timeout = "30"
346
+ options.default_task_schedule_to_start_timeout = "30"
347
+ options.default_task_start_to_close_timeout = "10"
348
+ end
349
+ def entry_point
350
+ activity.exponential_retry(:run_activity1, 5) do |o|
351
+ o.maximum_attempts = 3
352
+ end
353
+ end
361
354
  end
362
- extend Decider
363
- version "1"
364
- entry_point :entry_point
365
-
366
- activity_client :activity do |options|
367
- options.prefix_name = "BadActivity"
368
- options.version = "1"
369
- options.default_task_heartbeat_timeout = "3600"
370
- options.default_task_list = "BadWorkflow"
371
- options.default_task_schedule_to_close_timeout = "30"
372
- options.default_task_schedule_to_start_timeout = "30"
373
- options.default_task_start_to_close_timeout = "10"
355
+ workflow_type_object = double("workflow_type", :name => "BadWorkflow.entry_point", :start_execution => "" )
356
+ domain = FakeDomain.new(workflow_type_object)
357
+
358
+ swf_client = FakeServiceClient.new
359
+ task_list = "BadWorkflow_tasklist"
360
+ worker = SynchronousWorkflowWorker.new(swf_client, domain, task_list)
361
+ worker.add_workflow_implementation(BadWorkflow)
362
+ my_workflow_factory = workflow_factory(swf_client, domain) do |options|
363
+ options.workflow_name = "BadWorkflow"
364
+ options.execution_start_to_close_timeout = 3600
365
+ options.task_list = task_list
366
+ options.task_start_to_close_timeout = 10
367
+ options.child_policy = :request_cancel
368
+ end
369
+ my_workflow = my_workflow_factory.get_client
370
+ workflow_execution = my_workflow.start_execution
371
+ worker.start
372
+ swf_client.trace.first[:decisions].first[:decision_type].should ==
373
+ "ScheduleActivityTask"
374
+ end
375
+
376
+ it "makes sure that overriding works correctly" do
377
+ class SynchronousWorkflowTaskPoller < WorkflowTaskPoller
378
+ def get_decision_task
379
+ fake_workflow_type = FakeWorkflowType.new(nil, "BadWorkflow.entry_point", "1")
380
+ TestHistoryWrapper.new(fake_workflow_type, FakeWorkflowExecution.new(nil, nil),
381
+ [
382
+ TestHistoryEvent.new("WorkflowExecutionStarted", 1, {}),
383
+ ])
384
+ end
374
385
  end
375
- def entry_point
376
- activity.exponential_retry(:run_activity1, 5) do |o|
377
- o.maximum_attempts = 3
386
+ class BadWorkflow
387
+ class << self
388
+ attr_accessor :task_list
389
+ end
390
+ extend Decider
391
+ version "1"
392
+ entry_point :entry_point
393
+ activity_client :activity do |options|
394
+ options.prefix_name = "BadActivity"
395
+ options.version = "1"
396
+ options.default_task_heartbeat_timeout = "3600"
397
+ options.default_task_list = "BadWorkflow"
398
+ options.default_task_schedule_to_close_timeout = "30"
399
+ options.default_task_schedule_to_start_timeout = "30"
400
+ options.default_task_start_to_close_timeout = "10"
401
+ end
402
+ def entry_point
403
+ activity.exponential_retry(:run_activity1, 5) do |o|
404
+ o.maximum_attempts = 3
405
+ end
378
406
  end
379
407
  end
380
- end
381
- workflow_type_object = double("workflow_type", :name => "BadWorkflow.entry_point", :start_execution => "" )
382
- domain = FakeDomain.new(workflow_type_object)
383
-
384
- swf_client = FakeServiceClient.new
385
- task_list = "BadWorkflow_tasklist"
386
- worker = SynchronousWorkflowWorker.new(swf_client, domain, task_list)
387
- worker.add_workflow_implementation(BadWorkflow)
388
- my_workflow_factory = workflow_factory(swf_client, domain) do |options|
389
- options.workflow_name = "BadWorkflow"
390
- options.execution_start_to_close_timeout = 3600
391
- options.task_list = task_list
392
- options.task_start_to_close_timeout = 10
393
- options.child_policy = :request_cancel
394
- end
395
- my_workflow = my_workflow_factory.get_client
396
- workflow_execution = my_workflow.start_execution
397
- worker.start
398
- swf_client.trace.first[:decisions].first[:decision_type].should ==
399
- "ScheduleActivityTask"
400
- end
401
-
402
- it "makes sure that overriding works correctly" do
403
- class SynchronousWorkflowTaskPoller < WorkflowTaskPoller
404
- def get_decision_task
405
- fake_workflow_type = FakeWorkflowType.new(nil, "BadWorkflow.entry_point", "1")
406
- TestHistoryWrapper.new(fake_workflow_type, FakeWorkflowExecution.new(nil, nil),
407
- [
408
- TestHistoryEvent.new("WorkflowExecutionStarted", 1, {}),
409
- ])
408
+ workflow_type_object = double("workflow_type", :name => "BadWorkflow.entry_point", :start_execution => "" )
409
+ domain = FakeDomain.new(workflow_type_object)
410
+
411
+ swf_client = FakeServiceClient.new
412
+ task_list = "BadWorkflow_tasklist"
413
+ worker = SynchronousWorkflowWorker.new(swf_client, domain, task_list)
414
+ worker.add_workflow_implementation(BadWorkflow)
415
+ my_workflow_factory = workflow_factory(swf_client, domain) do |options|
416
+ options.workflow_name = "BadWorkflow"
417
+ options.execution_start_to_close_timeout = 3600
418
+ options.task_list = task_list
419
+ options.task_start_to_close_timeout = 10
420
+ options.child_policy = :request_cancel
421
+ end
422
+ my_workflow = my_workflow_factory.get_client
423
+ workflow_execution = my_workflow.start_execution
424
+ worker.start
425
+ swf_client.trace.first[:decisions].first[:decision_type].should ==
426
+ "ScheduleActivityTask"
427
+ end
428
+
429
+ it "makes sure that exponential_retry blocks correctly" do
430
+ class SynchronousWorkflowTaskPoller < WorkflowTaskPoller
431
+ def get_decision_task
432
+ fake_workflow_type = FakeWorkflowType.new(nil, "BadWorkflow.entry_point", "1")
433
+ TestHistoryWrapper.new(fake_workflow_type, FakeWorkflowExecution.new(nil, nil),
434
+ [
435
+ TestHistoryEvent.new("WorkflowExecutionStarted", 1, {}),
436
+ ])
437
+ end
410
438
  end
411
- end
412
- class BadWorkflow
413
- class << self
414
- attr_accessor :task_list
415
- end
416
- extend Decider
417
- version "1"
418
- entry_point :entry_point
419
- activity_client :activity do |options|
420
- options.prefix_name = "BadActivity"
421
- options.version = "1"
422
- options.default_task_heartbeat_timeout = "3600"
423
- options.default_task_list = "BadWorkflow"
424
- options.default_task_schedule_to_close_timeout = "30"
425
- options.default_task_schedule_to_start_timeout = "30"
426
- options.default_task_start_to_close_timeout = "10"
427
- end
428
- def entry_point
429
- activity.exponential_retry(:run_activity1, 5) do |o|
430
- o.maximum_attempts = 3
439
+ class BadWorkflow
440
+ class << self
441
+ attr_accessor :task_list, :trace
442
+ end
443
+ @trace = []
444
+ extend Decider
445
+ version "1"
446
+ entry_point :entry_point
447
+ activity_client :activity do |options|
448
+ options.prefix_name = "BadActivity"
449
+ options.version = "1"
450
+ options.default_task_heartbeat_timeout = "3600"
451
+ options.default_task_list = "BadWorkflow"
452
+ options.default_task_schedule_to_close_timeout = "30"
453
+ options.default_task_schedule_to_start_timeout = "30"
454
+ options.default_task_start_to_close_timeout = "10"
455
+ end
456
+ def entry_point
457
+ BadWorkflow.trace << :start
458
+ activity.exponential_retry(:run_activity1, 5) do |o|
459
+ o.maximum_attempts = 3
460
+ end
461
+ BadWorkflow.trace << :middle
462
+ activity.exponential_retry(:run_activity2, 5) do |o|
463
+ o.maximum_attempts = 3
464
+ end
465
+ activity.run_activity1
466
+ BadWorkflow.trace << :end
431
467
  end
432
468
  end
433
- end
434
- workflow_type_object = double("workflow_type", :name => "BadWorkflow.entry_point", :start_execution => "" )
435
- domain = FakeDomain.new(workflow_type_object)
436
-
437
- swf_client = FakeServiceClient.new
438
- task_list = "BadWorkflow_tasklist"
439
- worker = SynchronousWorkflowWorker.new(swf_client, domain, task_list)
440
- worker.add_workflow_implementation(BadWorkflow)
441
- my_workflow_factory = workflow_factory(swf_client, domain) do |options|
442
- options.workflow_name = "BadWorkflow"
443
- options.execution_start_to_close_timeout = 3600
444
- options.task_list = task_list
445
- options.task_start_to_close_timeout = 10
446
- options.child_policy = :request_cancel
447
- end
448
- my_workflow = my_workflow_factory.get_client
449
- workflow_execution = my_workflow.start_execution
450
- worker.start
451
- swf_client.trace.first[:decisions].first[:decision_type].should ==
452
- "ScheduleActivityTask"
453
- end
469
+ workflow_type_object = double("workflow_type", :name => "BadWorkflow.entry_point", :start_execution => "" )
470
+ domain = FakeDomain.new(workflow_type_object)
471
+
472
+ swf_client = FakeServiceClient.new
473
+ task_list = "BadWorkflow_tasklist"
474
+ worker = SynchronousWorkflowWorker.new(swf_client, domain, task_list)
475
+ worker.add_workflow_implementation(BadWorkflow)
476
+ my_workflow_factory = workflow_factory(swf_client, domain) do |options|
477
+ options.workflow_name = "BadWorkflow"
478
+ options.execution_start_to_close_timeout = 3600
479
+ options.task_list = task_list
480
+ options.task_start_to_close_timeout = 10
481
+ options.child_policy = :request_cancel
482
+ end
483
+ my_workflow = my_workflow_factory.get_client
484
+ workflow_execution = my_workflow.start_execution
485
+ worker.start
486
+ swf_client.trace.first[:decisions].first[:decision_type].should ==
487
+ "ScheduleActivityTask"
488
+ BadWorkflow.trace.should == [:start]
489
+ end
490
+
491
+ it "makes sure that exponential_retry blocks correctly when done through configure" do
492
+ class SynchronousWorkflowTaskPoller < WorkflowTaskPoller
493
+ def get_decision_task
494
+ fake_workflow_type = FakeWorkflowType.new(nil, "BadWorkflow.entry_point", "1")
495
+ TestHistoryWrapper.new(fake_workflow_type, FakeWorkflowExecution.new(nil, nil),
496
+ [
497
+ TestHistoryEvent.new("WorkflowExecutionStarted", 1, {}),
498
+ TestHistoryEvent.new("DecisionTaskScheduled", 2, {}),
499
+ TestHistoryEvent.new("DecisionTaskStarted", 3, {}),
500
+ TestHistoryEvent.new("DecisionTaskCompleted", 4, {}),
501
+ TestHistoryEvent.new("ActivityTaskScheduled", 5, {:activity_id => "Activity1"}),
502
+ TestHistoryEvent.new("ActivityTaskStarted", 6, {}),
503
+ TestHistoryEvent.new("ActivityTaskTimedOut", 7, {:scheduled_event_id => 5, :timeout_type => "START_TO_CLOSE"}),
504
+ ])
505
+ end
506
+ end
507
+ class BadWorkflow
508
+ class << self
509
+ attr_accessor :task_list, :trace
510
+ end
511
+ @trace = []
512
+ extend Decider
513
+ version "1"
514
+ entry_point :entry_point
515
+ activity_client :activity do |options|
516
+ options.prefix_name = "BadActivity"
517
+ options.version = "1"
518
+ options.default_task_heartbeat_timeout = "3600"
519
+ options.default_task_list = "BadWorkflow"
520
+ options.default_task_schedule_to_close_timeout = "90"
521
+ options.default_task_schedule_to_start_timeout = "90"
522
+ options.default_task_start_to_close_timeout = "90"
523
+ end
524
+ def entry_point
525
+ BadWorkflow.trace << :start
454
526
 
455
- it "makes sure that exponential_retry blocks correctly" do
456
- class SynchronousWorkflowTaskPoller < WorkflowTaskPoller
457
- def get_decision_task
458
- fake_workflow_type = FakeWorkflowType.new(nil, "BadWorkflow.entry_point", "1")
459
- TestHistoryWrapper.new(fake_workflow_type, FakeWorkflowExecution.new(nil, nil),
460
- [
461
- TestHistoryEvent.new("WorkflowExecutionStarted", 1, {}),
462
- ])
527
+ activity.reconfigure(:run_activity1) do |o|
528
+ o.exponential_retry do |retry_options|
529
+ retry_options.maximum_attempts = 3
530
+ end
531
+ end
532
+ activity.run_activity1
533
+ BadWorkflow.trace << :middle
534
+ activity.run_activity1
535
+ end
463
536
  end
464
- end
465
- class BadWorkflow
466
- class << self
467
- attr_accessor :task_list, :trace
468
- end
469
- @trace = []
470
- extend Decider
471
- version "1"
472
- entry_point :entry_point
473
- activity_client :activity do |options|
474
- options.prefix_name = "BadActivity"
475
- options.version = "1"
476
- options.default_task_heartbeat_timeout = "3600"
477
- options.default_task_list = "BadWorkflow"
478
- options.default_task_schedule_to_close_timeout = "30"
479
- options.default_task_schedule_to_start_timeout = "30"
480
- options.default_task_start_to_close_timeout = "10"
481
- end
482
- def entry_point
483
- BadWorkflow.trace << :start
484
- activity.exponential_retry(:run_activity1, 5) do |o|
485
- o.maximum_attempts = 3
486
- end
487
- BadWorkflow.trace << :middle
488
- activity.exponential_retry(:run_activity2, 5) do |o|
489
- o.maximum_attempts = 3
490
- end
491
- activity.run_activity1
492
- BadWorkflow.trace << :end
537
+ workflow_type_object = double("workflow_type", :name => "BadWorkflow.entry_point", :start_execution => "" )
538
+ domain = FakeDomain.new(workflow_type_object)
539
+
540
+ swf_client = FakeServiceClient.new
541
+ task_list = "BadWorkflow_tasklist"
542
+ worker = SynchronousWorkflowWorker.new(swf_client, domain, task_list)
543
+ worker.add_workflow_implementation(BadWorkflow)
544
+ my_workflow_factory = workflow_factory(swf_client, domain) do |options|
545
+ options.workflow_name = "BadWorkflow"
546
+ options.execution_start_to_close_timeout = 3600
547
+ options.task_list = task_list
548
+ options.task_start_to_close_timeout = 30
549
+ options.child_policy = :request_cancel
550
+ end
551
+ my_workflow = my_workflow_factory.get_client
552
+ workflow_execution = my_workflow.start_execution
553
+ worker.start
554
+ swf_client.trace.first[:decisions].first[:decision_type].should ==
555
+ "StartTimer"
556
+ BadWorkflow.trace.should == [:start]
557
+ end
558
+
559
+ it "makes sure that exponential_retry blocks correctly when done through the activity_client" do
560
+ class SynchronousWorkflowTaskPoller < WorkflowTaskPoller
561
+ def get_decision_task
562
+ fake_workflow_type = FakeWorkflowType.new(nil, "BadWorkflow.entry_point", "1")
563
+ TestHistoryWrapper.new(fake_workflow_type, FakeWorkflowExecution.new(nil, nil),
564
+ [
565
+
566
+ TestHistoryEvent.new("WorkflowExecutionStarted", 1, {:created_at => Time.now}),
567
+ TestHistoryEvent.new("DecisionTaskScheduled", 2, {:created_at => Time.now}),
568
+ TestHistoryEvent.new("DecisionTaskStarted", 3, {:created_at => Time.now}),
569
+ TestHistoryEvent.new("DecisionTaskCompleted", 4, {:created_at => Time.now}),
570
+ TestHistoryEvent.new("ActivityTaskScheduled", 5, {:activity_id => "Activity1", :created_at => Time.now}),
571
+ TestHistoryEvent.new("ActivityTaskStarted", 6, {:created_at => Time.now}),
572
+ TestHistoryEvent.new("ActivityTaskTimedOut", 7, {:scheduled_event_id => 5, :timeout_type => "START_TO_CLOSE", :created_at => Time.now}),
573
+ ])
574
+ end
493
575
  end
494
- end
495
- workflow_type_object = double("workflow_type", :name => "BadWorkflow.entry_point", :start_execution => "" )
496
- domain = FakeDomain.new(workflow_type_object)
497
-
498
- swf_client = FakeServiceClient.new
499
- task_list = "BadWorkflow_tasklist"
500
- worker = SynchronousWorkflowWorker.new(swf_client, domain, task_list)
501
- worker.add_workflow_implementation(BadWorkflow)
502
- my_workflow_factory = workflow_factory(swf_client, domain) do |options|
503
- options.workflow_name = "BadWorkflow"
504
- options.execution_start_to_close_timeout = 3600
505
- options.task_list = task_list
506
- options.task_start_to_close_timeout = 10
507
- options.child_policy = :request_cancel
508
- end
509
- my_workflow = my_workflow_factory.get_client
510
- workflow_execution = my_workflow.start_execution
511
- worker.start
512
- swf_client.trace.first[:decisions].first[:decision_type].should ==
513
- "ScheduleActivityTask"
514
- BadWorkflow.trace.should == [:start]
515
- end
576
+ class BadWorkflow
577
+ class << self
578
+ attr_accessor :task_list, :trace
579
+ end
580
+ @trace = []
581
+ extend Decider
582
+ version "1"
583
+ entry_point :entry_point
584
+ activity_client :activity do |options|
585
+ options.prefix_name = "BadActivity"
586
+ options.version = "1"
587
+ options.default_task_heartbeat_timeout = "3600"
588
+ options.default_task_list = "BadWorkflow"
589
+ options.default_task_schedule_to_close_timeout = "30"
590
+ options.default_task_schedule_to_start_timeout = "30"
591
+ options.default_task_start_to_close_timeout = "30"
592
+ options.exponential_retry do |retry_options|
593
+ retry_options.maximum_attempts = 3
594
+ end
595
+ end
596
+ def entry_point
597
+ BadWorkflow.trace << :start
598
+ activity.run_activity1
599
+ BadWorkflow.trace << :middle
600
+ activity.run_activity1
516
601
 
517
- it "makes sure that exponential_retry blocks correctly when done through configure" do
518
- class SynchronousWorkflowTaskPoller < WorkflowTaskPoller
519
- def get_decision_task
520
- fake_workflow_type = FakeWorkflowType.new(nil, "BadWorkflow.entry_point", "1")
521
- TestHistoryWrapper.new(fake_workflow_type, FakeWorkflowExecution.new(nil, nil),
522
- [
523
- TestHistoryEvent.new("WorkflowExecutionStarted", 1, {}),
524
- TestHistoryEvent.new("DecisionTaskScheduled", 2, {}),
525
- TestHistoryEvent.new("DecisionTaskStarted", 3, {}),
526
- TestHistoryEvent.new("DecisionTaskCompleted", 4, {}),
527
- TestHistoryEvent.new("ActivityTaskScheduled", 5, {:activity_id => "Activity1"}),
528
- TestHistoryEvent.new("ActivityTaskStarted", 6, {}),
529
- TestHistoryEvent.new("ActivityTaskTimedOut", 7, {:scheduled_event_id => 5, :timeout_type => "START_TO_CLOSE"}),
530
- ])
602
+ end
531
603
  end
532
- end
533
- class BadWorkflow
534
- class << self
535
- attr_accessor :task_list, :trace
536
- end
537
- @trace = []
538
- extend Decider
539
- version "1"
540
- entry_point :entry_point
541
- activity_client :activity do |options|
542
- options.prefix_name = "BadActivity"
543
- options.version = "1"
544
- options.default_task_heartbeat_timeout = "3600"
545
- options.default_task_list = "BadWorkflow"
546
- options.default_task_schedule_to_close_timeout = "90"
547
- options.default_task_schedule_to_start_timeout = "90"
548
- options.default_task_start_to_close_timeout = "90"
549
- end
550
- def entry_point
551
- BadWorkflow.trace << :start
552
-
553
- activity.reconfigure(:run_activity1) do |o|
554
- o.exponential_retry do |retry_options|
604
+ workflow_type_object = double("workflow_type", :name => "BadWorkflow.entry_point", :start_execution => "" )
605
+ domain = FakeDomain.new(workflow_type_object)
606
+
607
+ swf_client = FakeServiceClient.new
608
+ task_list = "BadWorkflow_tasklist"
609
+ worker = SynchronousWorkflowWorker.new(swf_client, domain, task_list)
610
+ worker.add_workflow_implementation(BadWorkflow)
611
+ my_workflow_factory = workflow_factory(swf_client, domain) do |options|
612
+ options.workflow_name = "BadWorkflow"
613
+ options.execution_start_to_close_timeout = 3600
614
+ options.task_list = task_list
615
+ options.task_start_to_close_timeout = 30
616
+ options.child_policy = :request_cancel
617
+ end
618
+ my_workflow = my_workflow_factory.get_client
619
+ workflow_execution = my_workflow.start_execution
620
+ worker.start
621
+
622
+ swf_client.trace.first[:decisions].first[:decision_type].should ==
623
+ "StartTimer"
624
+ BadWorkflow.trace.should == [:start]
625
+ end
626
+
627
+ it "makes sure that multiple schedules followed by a timeout work" do
628
+ class SynchronousWorkflowTaskPoller < WorkflowTaskPoller
629
+ def get_decision_task
630
+ fake_workflow_type = FakeWorkflowType.new(nil, "BadWorkflow.entry_point", "1")
631
+ TestHistoryWrapper.new(fake_workflow_type, FakeWorkflowExecution.new(nil, nil),
632
+ [
633
+ TestHistoryEvent.new("WorkflowExecutionStarted", 1, {}),
634
+ TestHistoryEvent.new("DecisionTaskScheduled", 2, {}),
635
+ TestHistoryEvent.new("DecisionTaskStarted", 3, {}),
636
+ TestHistoryEvent.new("DecisionTaskCompleted", 4, {}),
637
+ TestHistoryEvent.new("ActivityTaskScheduled", 5, {:activity_id => "Activity1"}),
638
+ TestHistoryEvent.new("ActivityTaskScheduled", 6, {:activity_id => "Activity2"}),
639
+ TestHistoryEvent.new("ActivityTaskScheduled", 7, {:activity_id => "Activity3"}),
640
+ TestHistoryEvent.new("ActivityTaskScheduled", 8, {:activity_id => "Activity4"}),
641
+ TestHistoryEvent.new("ActivityTaskTimedOut", 9, {:scheduled_event_id => 5, :timeout_type => "START_TO_CLOSE"}),
642
+ TestHistoryEvent.new("ActivityTaskTimedOut", 10, {:scheduled_event_id => 6, :timeout_type => "START_TO_CLOSE"}),
643
+ TestHistoryEvent.new("ActivityTaskTimedOut", 11, {:scheduled_event_id => 7, :timeout_type => "START_TO_CLOSE"}),
644
+ TestHistoryEvent.new("ActivityTaskTimedOut", 12, {:scheduled_event_id => 8, :timeout_type => "START_TO_CLOSE"}),
645
+ TestHistoryEvent.new("DecisionTaskScheduled", 13, {}),
646
+ TestHistoryEvent.new("DecisionTaskStarted", 14, {}),
647
+
648
+ ])
649
+ end
650
+ end
651
+ class BadWorkflow
652
+ class << self
653
+ attr_accessor :task_list, :trace
654
+ end
655
+ @trace = []
656
+ extend Decider
657
+ version "1"
658
+ entry_point :entry_point
659
+ activity_client :activity do |options|
660
+ options.prefix_name = "BadActivity"
661
+ options.version = "1"
662
+ options.default_task_heartbeat_timeout = "3600"
663
+ options.default_task_list = "BadWorkflow"
664
+ options.default_task_schedule_to_close_timeout = "30"
665
+ options.default_task_schedule_to_start_timeout = "30"
666
+ options.default_task_start_to_close_timeout = "30"
667
+ options.exponential_retry do |retry_options|
555
668
  retry_options.maximum_attempts = 3
556
669
  end
557
670
  end
558
- activity.run_activity1
559
- BadWorkflow.trace << :middle
560
- activity.run_activity1
671
+ def entry_point
672
+ BadWorkflow.trace << :start
673
+ [:run_activity1, :run_activity2, :run_activity3, :run_activity4].each do |act|
674
+ activity.send_async(act)
675
+ end
676
+ BadWorkflow.trace << :middle
677
+ activity.run_activity3
678
+ BadWorkflow.trace << :end
679
+ end
561
680
  end
562
- end
563
- workflow_type_object = double("workflow_type", :name => "BadWorkflow.entry_point", :start_execution => "" )
564
- domain = FakeDomain.new(workflow_type_object)
565
-
566
- swf_client = FakeServiceClient.new
567
- task_list = "BadWorkflow_tasklist"
568
- worker = SynchronousWorkflowWorker.new(swf_client, domain, task_list)
569
- worker.add_workflow_implementation(BadWorkflow)
570
- my_workflow_factory = workflow_factory(swf_client, domain) do |options|
571
- options.workflow_name = "BadWorkflow"
572
- options.execution_start_to_close_timeout = 3600
573
- options.task_list = task_list
574
- options.task_start_to_close_timeout = 30
575
- options.child_policy = :request_cancel
576
- end
577
- my_workflow = my_workflow_factory.get_client
578
- workflow_execution = my_workflow.start_execution
579
- worker.start
580
- swf_client.trace.first[:decisions].first[:decision_type].should ==
581
- "StartTimer"
582
- BadWorkflow.trace.should == [:start]
583
- end
584
-
585
- it "makes sure that exponential_retry blocks correctly when done through the activity_client" do
586
- class SynchronousWorkflowTaskPoller < WorkflowTaskPoller
587
- def get_decision_task
588
- fake_workflow_type = FakeWorkflowType.new(nil, "BadWorkflow.entry_point", "1")
589
- TestHistoryWrapper.new(fake_workflow_type, FakeWorkflowExecution.new(nil, nil),
590
- [
591
-
592
- TestHistoryEvent.new("WorkflowExecutionStarted", 1, {:created_at => Time.now}),
593
- TestHistoryEvent.new("DecisionTaskScheduled", 2, {:created_at => Time.now}),
594
- TestHistoryEvent.new("DecisionTaskStarted", 3, {:created_at => Time.now}),
595
- TestHistoryEvent.new("DecisionTaskCompleted", 4, {:created_at => Time.now}),
596
- TestHistoryEvent.new("ActivityTaskScheduled", 5, {:activity_id => "Activity1", :created_at => Time.now}),
597
- TestHistoryEvent.new("ActivityTaskStarted", 6, {:created_at => Time.now}),
598
- TestHistoryEvent.new("ActivityTaskTimedOut", 7, {:scheduled_event_id => 5, :timeout_type => "START_TO_CLOSE", :created_at => Time.now}),
599
- ])
681
+ workflow_type_object = double("workflow_type", :name => "BadWorkflow.entry_point", :start_execution => "" )
682
+ domain = FakeDomain.new(workflow_type_object)
683
+
684
+ swf_client = FakeServiceClient.new
685
+ task_list = "BadWorkflow_tasklist"
686
+ worker = SynchronousWorkflowWorker.new(swf_client, domain, task_list)
687
+ worker.add_workflow_implementation(BadWorkflow)
688
+ my_workflow_factory = workflow_factory(swf_client, domain) do |options|
689
+ options.workflow_name = "BadWorkflow"
690
+ options.execution_start_to_close_timeout = 3600
691
+ options.task_list = task_list
692
+ options.task_start_to_close_timeout = 30
693
+ options.child_policy = :request_cancel
694
+ end
695
+ my_workflow = my_workflow_factory.get_client
696
+ workflow_execution = my_workflow.start_execution
697
+ worker.start
698
+ swf_client.trace.first[:decisions].first[:decision_type].should ==
699
+ "StartTimer"
700
+ swf_client.trace.first[:decisions].length.should == 4
701
+ BadWorkflow.trace.should == [:start, :middle]
702
+ end
703
+
704
+ it "makes sure that timeout followed by success is handled correctly" do
705
+ class SynchronousWorkflowTaskPoller < WorkflowTaskPoller
706
+ def get_decision_task
707
+ fake_workflow_type = FakeWorkflowType.new(nil, "BadWorkflow.entry_point", "1")
708
+ TestHistoryWrapper.new(fake_workflow_type, FakeWorkflowExecution.new(nil, nil),
709
+ [
710
+ TestHistoryEvent.new("WorkflowExecutionStarted", 1, {}),
711
+ TestHistoryEvent.new("DecisionTaskScheduled", 2, {}),
712
+ TestHistoryEvent.new("DecisionTaskStarted", 3, {}),
713
+ TestHistoryEvent.new("DecisionTaskCompleted", 4, {}),
714
+ TestHistoryEvent.new("ActivityTaskScheduled", 5, {:activity_id => "Activity1"}),
715
+ TestHistoryEvent.new("ActivityTaskTimedOut", 6, {:scheduled_event_id => 5, :timeout_type => "START_TO_CLOSE"}),
716
+ TestHistoryEvent.new("DecisionTaskScheduled", 7, {}),
717
+ TestHistoryEvent.new("DecisionTaskStarted", 8, {}),
718
+ TestHistoryEvent.new("DecisionTaskCompleted", 10, {}),
719
+ TestHistoryEvent.new("TimerStarted", 11, {:decision_task_completed_event_id => 10, :timer_id => "Timer1", :start_to_fire_timeout => 1}),
720
+ TestHistoryEvent.new("TimerFired", 12, {:timer_id => "Timer1", :started_event_id => 11}),
721
+ TestHistoryEvent.new("DecisionTaskScheduled", 13, {}),
722
+ TestHistoryEvent.new("DecisionTaskStarted", 14, {}),
723
+ TestHistoryEvent.new("DecisionTaskCompleted", 15, {}),
724
+ TestHistoryEvent.new("ActivityTaskScheduled", 16, {:activity_id => "Activity2"}),
725
+ TestHistoryEvent.new("ActivityTaskCompleted", 17, {:scheduled_event_id => 16 }),
726
+ TestHistoryEvent.new("DecisionTaskScheduled", 18, {}),
727
+ TestHistoryEvent.new("DecisionTaskStarted", 19, {}),
728
+
729
+ ])
730
+ end
600
731
  end
601
- end
602
- class BadWorkflow
603
- class << self
604
- attr_accessor :task_list, :trace
605
- end
606
- @trace = []
607
- extend Decider
608
- version "1"
609
- entry_point :entry_point
610
- activity_client :activity do |options|
611
- options.prefix_name = "BadActivity"
612
- options.version = "1"
613
- options.default_task_heartbeat_timeout = "3600"
614
- options.default_task_list = "BadWorkflow"
615
- options.default_task_schedule_to_close_timeout = "30"
616
- options.default_task_schedule_to_start_timeout = "30"
617
- options.default_task_start_to_close_timeout = "30"
618
- options.exponential_retry do |retry_options|
619
- retry_options.maximum_attempts = 3
620
- end
621
- end
622
- def entry_point
623
- BadWorkflow.trace << :start
624
- activity.run_activity1
625
- BadWorkflow.trace << :middle
626
- activity.run_activity1
732
+ class BadWorkflow
733
+ class << self
734
+ attr_accessor :task_list, :trace
735
+ end
736
+ @trace = []
737
+ extend Decider
738
+ version "1"
739
+ entry_point :entry_point
740
+ activity_client :activity do |options|
741
+ options.prefix_name = "BadActivity"
742
+ options.version = "1"
743
+ options.default_task_heartbeat_timeout = "3600"
744
+ options.default_task_list = "BadWorkflow"
745
+ options.default_task_schedule_to_close_timeout = "30"
746
+ options.default_task_schedule_to_start_timeout = "30"
747
+ options.default_task_start_to_close_timeout = "30"
748
+ options.exponential_retry do |retry_options|
749
+ retry_options.maximum_attempts = 3
750
+ end
751
+ end
752
+ def entry_point
753
+ BadWorkflow.trace << :start
754
+ activity.run_activity1
755
+ BadWorkflow.trace << :middle
627
756
 
757
+ BadWorkflow.trace << :end
758
+ end
628
759
  end
629
- end
630
- workflow_type_object = double("workflow_type", :name => "BadWorkflow.entry_point", :start_execution => "" )
631
- domain = FakeDomain.new(workflow_type_object)
632
-
633
- swf_client = FakeServiceClient.new
634
- task_list = "BadWorkflow_tasklist"
635
- worker = SynchronousWorkflowWorker.new(swf_client, domain, task_list)
636
- worker.add_workflow_implementation(BadWorkflow)
637
- my_workflow_factory = workflow_factory(swf_client, domain) do |options|
638
- options.workflow_name = "BadWorkflow"
639
- options.execution_start_to_close_timeout = 3600
640
- options.task_list = task_list
641
- options.task_start_to_close_timeout = 30
642
- options.child_policy = :request_cancel
643
- end
644
- my_workflow = my_workflow_factory.get_client
645
- workflow_execution = my_workflow.start_execution
646
- worker.start
647
-
648
- swf_client.trace.first[:decisions].first[:decision_type].should ==
649
- "StartTimer"
650
- BadWorkflow.trace.should == [:start]
651
- end
652
-
653
- it "makes sure that multiple schedules followed by a timeout work" do
654
- class SynchronousWorkflowTaskPoller < WorkflowTaskPoller
655
- def get_decision_task
656
- fake_workflow_type = FakeWorkflowType.new(nil, "BadWorkflow.entry_point", "1")
657
- TestHistoryWrapper.new(fake_workflow_type, FakeWorkflowExecution.new(nil, nil),
658
- [
659
- TestHistoryEvent.new("WorkflowExecutionStarted", 1, {}),
660
- TestHistoryEvent.new("DecisionTaskScheduled", 2, {}),
661
- TestHistoryEvent.new("DecisionTaskStarted", 3, {}),
662
- TestHistoryEvent.new("DecisionTaskCompleted", 4, {}),
663
- TestHistoryEvent.new("ActivityTaskScheduled", 5, {:activity_id => "Activity1"}),
664
- TestHistoryEvent.new("ActivityTaskScheduled", 6, {:activity_id => "Activity2"}),
665
- TestHistoryEvent.new("ActivityTaskScheduled", 7, {:activity_id => "Activity3"}),
666
- TestHistoryEvent.new("ActivityTaskScheduled", 8, {:activity_id => "Activity4"}),
667
- TestHistoryEvent.new("ActivityTaskTimedOut", 9, {:scheduled_event_id => 5, :timeout_type => "START_TO_CLOSE"}),
668
- TestHistoryEvent.new("ActivityTaskTimedOut", 10, {:scheduled_event_id => 6, :timeout_type => "START_TO_CLOSE"}),
669
- TestHistoryEvent.new("ActivityTaskTimedOut", 11, {:scheduled_event_id => 7, :timeout_type => "START_TO_CLOSE"}),
670
- TestHistoryEvent.new("ActivityTaskTimedOut", 12, {:scheduled_event_id => 8, :timeout_type => "START_TO_CLOSE"}),
671
- TestHistoryEvent.new("DecisionTaskScheduled", 13, {}),
672
- TestHistoryEvent.new("DecisionTaskStarted", 14, {}),
673
-
674
- ])
760
+ workflow_type_object = double("workflow_type", :name => "BadWorkflow.entry_point", :start_execution => "" )
761
+ domain = FakeDomain.new(workflow_type_object)
762
+
763
+ swf_client = FakeServiceClient.new
764
+ task_list = "BadWorkflow_tasklist"
765
+ worker = SynchronousWorkflowWorker.new(swf_client, domain, task_list)
766
+ worker.add_workflow_implementation(BadWorkflow)
767
+ my_workflow_factory = workflow_factory(swf_client, domain) do |options|
768
+ options.workflow_name = "BadWorkflow"
769
+ options.execution_start_to_close_timeout = 3600
770
+ options.task_list = task_list
771
+ options.task_start_to_close_timeout = 30
772
+ options.child_policy = :request_cancel
773
+ end
774
+ my_workflow = my_workflow_factory.get_client
775
+ workflow_execution = my_workflow.start_execution
776
+ worker.start
777
+
778
+ swf_client.trace.first[:decisions].first[:decision_type].should ==
779
+ "CompleteWorkflowExecution"
780
+ BadWorkflow.trace.should == [:start, :middle, :end]
781
+ end
782
+
783
+ it "makes sure that signal works correctly" do
784
+ class SynchronousWorkflowTaskPoller < WorkflowTaskPoller
785
+ def get_decision_task
786
+ fake_workflow_type = FakeWorkflowType.new(nil, "BadWorkflow.entry_point", "1")
787
+ TestHistoryWrapper.new(fake_workflow_type, FakeWorkflowExecution.new(nil, nil),
788
+ [
789
+ TestHistoryEvent.new("WorkflowExecutionStarted", 1, {}),
790
+ TestHistoryEvent.new("DecisionTaskScheduled", 2, {}),
791
+ TestHistoryEvent.new("DecisionTaskStarted", 3, {}),
792
+ TestHistoryEvent.new("DecisionTaskCompleted", 4, {}),
793
+ TestHistoryEvent.new("WorkflowExecutionSignaled", 5, {:signal_name => "this_signal"}),
794
+ ])
795
+ end
675
796
  end
676
- end
677
- class BadWorkflow
678
- class << self
679
- attr_accessor :task_list, :trace
680
- end
681
- @trace = []
682
- extend Decider
683
- version "1"
684
- entry_point :entry_point
685
- activity_client :activity do |options|
686
- options.prefix_name = "BadActivity"
687
- options.version = "1"
688
- options.default_task_heartbeat_timeout = "3600"
689
- options.default_task_list = "BadWorkflow"
690
- options.default_task_schedule_to_close_timeout = "30"
691
- options.default_task_schedule_to_start_timeout = "30"
692
- options.default_task_start_to_close_timeout = "30"
693
- options.exponential_retry do |retry_options|
694
- retry_options.maximum_attempts = 3
695
- end
696
- end
697
- def entry_point
698
- BadWorkflow.trace << :start
699
- [:run_activity1, :run_activity2, :run_activity3, :run_activity4].each do |act|
700
- activity.send_async(act)
701
- end
702
- BadWorkflow.trace << :middle
703
- activity.run_activity3
704
- BadWorkflow.trace << :end
797
+ class BadWorkflow
798
+ class << self
799
+ attr_accessor :task_list, :trace
800
+ end
801
+ @trace = []
802
+ extend Decider
803
+ version "1"
804
+ entry_point :entry_point
805
+ activity_client :activity do |options|
806
+ options.prefix_name = "BadActivity"
807
+ options.version = "1"
808
+ options.default_task_heartbeat_timeout = "3600"
809
+ options.default_task_list = "BadWorkflow"
810
+ options.default_task_schedule_to_close_timeout = "30"
811
+ options.default_task_schedule_to_start_timeout = "30"
812
+ options.default_task_start_to_close_timeout = "30"
813
+ options.exponential_retry do |retry_options|
814
+ retry_options.maximum_attempts = 3
815
+ end
816
+ end
817
+ def this_signal
818
+ @wait.broadcast
819
+ end
820
+ signal :this_signal
821
+ def entry_point
822
+ BadWorkflow.trace << :start
823
+ @wait ||= FiberConditionVariable.new
824
+ @wait.wait
825
+ BadWorkflow.trace << :middle
826
+ BadWorkflow.trace << :end
827
+ end
705
828
  end
706
- end
707
- workflow_type_object = double("workflow_type", :name => "BadWorkflow.entry_point", :start_execution => "" )
708
- domain = FakeDomain.new(workflow_type_object)
709
-
710
- swf_client = FakeServiceClient.new
711
- task_list = "BadWorkflow_tasklist"
712
- worker = SynchronousWorkflowWorker.new(swf_client, domain, task_list)
713
- worker.add_workflow_implementation(BadWorkflow)
714
- my_workflow_factory = workflow_factory(swf_client, domain) do |options|
715
- options.workflow_name = "BadWorkflow"
716
- options.execution_start_to_close_timeout = 3600
717
- options.task_list = task_list
718
- options.task_start_to_close_timeout = 30
719
- options.child_policy = :request_cancel
720
- end
721
- my_workflow = my_workflow_factory.get_client
722
- workflow_execution = my_workflow.start_execution
723
- worker.start
724
- swf_client.trace.first[:decisions].first[:decision_type].should ==
725
- "StartTimer"
726
- swf_client.trace.first[:decisions].length.should == 4
727
- BadWorkflow.trace.should == [:start, :middle]
728
- end
729
-
730
- it "makes sure that timeout followed by success is handled correctly" do
731
- class SynchronousWorkflowTaskPoller < WorkflowTaskPoller
732
- def get_decision_task
733
- fake_workflow_type = FakeWorkflowType.new(nil, "BadWorkflow.entry_point", "1")
734
- TestHistoryWrapper.new(fake_workflow_type, FakeWorkflowExecution.new(nil, nil),
735
- [
736
- TestHistoryEvent.new("WorkflowExecutionStarted", 1, {}),
737
- TestHistoryEvent.new("DecisionTaskScheduled", 2, {}),
738
- TestHistoryEvent.new("DecisionTaskStarted", 3, {}),
739
- TestHistoryEvent.new("DecisionTaskCompleted", 4, {}),
740
- TestHistoryEvent.new("ActivityTaskScheduled", 5, {:activity_id => "Activity1"}),
741
- TestHistoryEvent.new("ActivityTaskTimedOut", 6, {:scheduled_event_id => 5, :timeout_type => "START_TO_CLOSE"}),
742
- TestHistoryEvent.new("DecisionTaskScheduled", 7, {}),
743
- TestHistoryEvent.new("DecisionTaskStarted", 8, {}),
744
- TestHistoryEvent.new("DecisionTaskCompleted", 10, {}),
745
- TestHistoryEvent.new("TimerStarted", 11, {:decision_task_completed_event_id => 10, :timer_id => "Timer1", :start_to_fire_timeout => 1}),
746
- TestHistoryEvent.new("TimerFired", 12, {:timer_id => "Timer1", :started_event_id => 11}),
747
- TestHistoryEvent.new("DecisionTaskScheduled", 13, {}),
748
- TestHistoryEvent.new("DecisionTaskStarted", 14, {}),
749
- TestHistoryEvent.new("DecisionTaskCompleted", 15, {}),
750
- TestHistoryEvent.new("ActivityTaskScheduled", 16, {:activity_id => "Activity2"}),
751
- TestHistoryEvent.new("ActivityTaskCompleted", 17, {:scheduled_event_id => 16 }),
752
- TestHistoryEvent.new("DecisionTaskScheduled", 18, {}),
753
- TestHistoryEvent.new("DecisionTaskStarted", 19, {}),
754
-
755
- ])
829
+ workflow_type_object = double("workflow_type", :name => "BadWorkflow.entry_point", :start_execution => "" )
830
+ domain = FakeDomain.new(workflow_type_object)
831
+
832
+ swf_client = FakeServiceClient.new
833
+ task_list = "BadWorkflow_tasklist"
834
+ worker = SynchronousWorkflowWorker.new(swf_client, domain, task_list)
835
+ worker.add_workflow_implementation(BadWorkflow)
836
+ my_workflow_factory = workflow_factory(swf_client, domain) do |options|
837
+ options.workflow_name = "BadWorkflow"
838
+ options.execution_start_to_close_timeout = 3600
839
+ options.task_list = task_list
840
+ end
841
+ my_workflow = my_workflow_factory.get_client
842
+ workflow_execution = my_workflow.start_execution
843
+ worker.start
844
+ swf_client.trace.first[:decisions].first[:decision_type].should ==
845
+ "CompleteWorkflowExecution"
846
+ BadWorkflow.trace.should == [:start, :middle, :end]
847
+ end
848
+
849
+ it "makes sure that raising an error properly fails a workflow" do
850
+ class SynchronousWorkflowTaskPoller < WorkflowTaskPoller
851
+ def get_decision_task
852
+ fake_workflow_type = FakeWorkflowType.new(nil, "BadWorkflow.entry_point", "1")
853
+ TestHistoryWrapper.new(fake_workflow_type, FakeWorkflowExecution.new(nil, nil),
854
+ [
855
+ TestHistoryEvent.new("WorkflowExecutionStarted", 1, {}),
856
+ TestHistoryEvent.new("DecisionTaskScheduled", 2, {}),
857
+ TestHistoryEvent.new("DecisionTaskStarted", 3, {}),
858
+ ])
859
+ end
756
860
  end
757
- end
758
- class BadWorkflow
759
- class << self
760
- attr_accessor :task_list, :trace
761
- end
762
- @trace = []
763
- extend Decider
764
- version "1"
765
- entry_point :entry_point
766
- activity_client :activity do |options|
767
- options.prefix_name = "BadActivity"
768
- options.version = "1"
769
- options.default_task_heartbeat_timeout = "3600"
770
- options.default_task_list = "BadWorkflow"
771
- options.default_task_schedule_to_close_timeout = "30"
772
- options.default_task_schedule_to_start_timeout = "30"
773
- options.default_task_start_to_close_timeout = "30"
774
- options.exponential_retry do |retry_options|
775
- retry_options.maximum_attempts = 3
776
- end
777
- end
778
- def entry_point
779
- BadWorkflow.trace << :start
780
- activity.run_activity1
781
- BadWorkflow.trace << :middle
782
-
783
- BadWorkflow.trace << :end
861
+ class BadWorkflow
862
+ class << self
863
+ attr_accessor :task_list, :trace
864
+ end
865
+ @trace = []
866
+ extend Decider
867
+ version "1"
868
+ entry_point :entry_point
869
+ def entry_point
870
+ raise "This is an expected error"
871
+ end
784
872
  end
785
- end
786
- workflow_type_object = double("workflow_type", :name => "BadWorkflow.entry_point", :start_execution => "" )
787
- domain = FakeDomain.new(workflow_type_object)
788
-
789
- swf_client = FakeServiceClient.new
790
- task_list = "BadWorkflow_tasklist"
791
- worker = SynchronousWorkflowWorker.new(swf_client, domain, task_list)
792
- worker.add_workflow_implementation(BadWorkflow)
793
- my_workflow_factory = workflow_factory(swf_client, domain) do |options|
794
- options.workflow_name = "BadWorkflow"
795
- options.execution_start_to_close_timeout = 3600
796
- options.task_list = task_list
797
- options.task_start_to_close_timeout = 30
798
- options.child_policy = :request_cancel
799
- end
800
- my_workflow = my_workflow_factory.get_client
801
- workflow_execution = my_workflow.start_execution
802
- worker.start
803
-
804
- swf_client.trace.first[:decisions].first[:decision_type].should ==
805
- "CompleteWorkflowExecution"
806
- BadWorkflow.trace.should == [:start, :middle, :end]
807
- end
808
-
809
- it "makes sure that signal works correctly" do
810
- class SynchronousWorkflowTaskPoller < WorkflowTaskPoller
811
- def get_decision_task
812
- fake_workflow_type = FakeWorkflowType.new(nil, "BadWorkflow.entry_point", "1")
813
- TestHistoryWrapper.new(fake_workflow_type, FakeWorkflowExecution.new(nil, nil),
814
- [
815
- TestHistoryEvent.new("WorkflowExecutionStarted", 1, {}),
816
- TestHistoryEvent.new("DecisionTaskScheduled", 2, {}),
817
- TestHistoryEvent.new("DecisionTaskStarted", 3, {}),
818
- TestHistoryEvent.new("DecisionTaskCompleted", 4, {}),
819
- TestHistoryEvent.new("WorkflowExecutionSignaled", 5, {:signal_name => "this_signal"}),
820
- ])
873
+ workflow_type_object = double("workflow_type", :name => "BadWorkflow.entry_point", :start_execution => "" )
874
+ domain = FakeDomain.new(workflow_type_object)
875
+
876
+ swf_client = FakeServiceClient.new
877
+
878
+ task_list = "BadWorkflow_tasklist"
879
+ worker = SynchronousWorkflowWorker.new(swf_client, domain, task_list, BadWorkflow)
880
+
881
+ my_workflow_factory = workflow_factory(swf_client, domain) do |options|
882
+ options.workflow_name = "BadWorkflow"
883
+ options.execution_start_to_close_timeout = 3600
884
+ options.task_list = task_list
885
+ end
886
+ my_workflow = my_workflow_factory.get_client
887
+ workflow_execution = my_workflow.start_execution
888
+ worker.start
889
+ swf_client.trace.first[:decisions].first[:fail_workflow_execution_decision_attributes][:details].should =~ /This is an expected error/
890
+ end
891
+ it "makes sure that you can do retry with the easier Fixnum semantic"do
892
+
893
+ class SynchronousWorkflowTaskPoller < WorkflowTaskPoller
894
+ def get_decision_task
895
+ fake_workflow_type = FakeWorkflowType.new(nil, "FixnumWorkflow.entry_point", "1")
896
+ TestHistoryWrapper.new(fake_workflow_type, FakeWorkflowExecution.new(nil, nil),
897
+ [
898
+ TestHistoryEvent.new("WorkflowExecutionStarted", 1, {}),
899
+ TestHistoryEvent.new("DecisionTaskScheduled", 2, {}),
900
+ TestHistoryEvent.new("DecisionTaskStarted", 3, {}),
901
+ TestHistoryEvent.new("DecisionTaskCompleted", 4, {}),
902
+ TestHistoryEvent.new("ActivityTaskScheduled", 5, {:activity_id => "Activity1"}),
903
+ TestHistoryEvent.new("ActivityTaskStarted", 6, {}),
904
+ TestHistoryEvent.new("ActivityTaskTimedOut", 7, {:scheduled_event_id => 5, :timeout_type => "START_TO_CLOSE"}),
905
+ ])
906
+ end
821
907
  end
822
- end
823
- class BadWorkflow
824
- class << self
825
- attr_accessor :task_list, :trace
826
- end
827
- @trace = []
828
- extend Decider
829
- version "1"
830
- entry_point :entry_point
831
- activity_client :activity do |options|
832
- options.prefix_name = "BadActivity"
833
- options.version = "1"
834
- options.default_task_heartbeat_timeout = "3600"
835
- options.default_task_list = "BadWorkflow"
836
- options.default_task_schedule_to_close_timeout = "30"
837
- options.default_task_schedule_to_start_timeout = "30"
838
- options.default_task_start_to_close_timeout = "30"
839
- options.exponential_retry do |retry_options|
840
- retry_options.maximum_attempts = 3
841
- end
842
- end
843
- def this_signal
844
- @wait.broadcast
845
- end
846
- signal :this_signal
847
- def entry_point
848
- BadWorkflow.trace << :start
849
- @wait ||= FiberConditionVariable.new
850
- @wait.wait
851
- BadWorkflow.trace << :middle
852
- BadWorkflow.trace << :end
908
+ workflow_type_object = double("workflow_type", :name => "FixnumWorkflow.entry_point", :start_execution => "" )
909
+ domain = FakeDomain.new(workflow_type_object)
910
+
911
+ class FixnumActivity
912
+ extend Activity
913
+ activity :run_activity1
914
+ def run_activity1; raise StandardError; end
853
915
  end
854
- end
855
- workflow_type_object = double("workflow_type", :name => "BadWorkflow.entry_point", :start_execution => "" )
856
- domain = FakeDomain.new(workflow_type_object)
857
-
858
- swf_client = FakeServiceClient.new
859
- task_list = "BadWorkflow_tasklist"
860
- worker = SynchronousWorkflowWorker.new(swf_client, domain, task_list)
861
- worker.add_workflow_implementation(BadWorkflow)
862
- my_workflow_factory = workflow_factory(swf_client, domain) do |options|
863
- options.workflow_name = "BadWorkflow"
864
- options.execution_start_to_close_timeout = 3600
865
- options.task_list = task_list
866
- end
867
- my_workflow = my_workflow_factory.get_client
868
- workflow_execution = my_workflow.start_execution
869
- worker.start
870
- swf_client.trace.first[:decisions].first[:decision_type].should ==
871
- "CompleteWorkflowExecution"
872
- BadWorkflow.trace.should == [:start, :middle, :end]
873
- end
916
+ class FixnumWorkflow
917
+ extend Workflows
918
+ workflow(:entry_point) { {:version => "1"} }
919
+ activity_client(:activity) { {:version => "1", :prefix_name => "FixnumActivity" } }
920
+ def entry_point
874
921
 
875
- it "makes sure that raising an error properly fails a workflow" do
876
- class SynchronousWorkflowTaskPoller < WorkflowTaskPoller
877
- def get_decision_task
878
- fake_workflow_type = FakeWorkflowType.new(nil, "BadWorkflow.entry_point", "1")
879
- TestHistoryWrapper.new(fake_workflow_type, FakeWorkflowExecution.new(nil, nil),
880
- [
881
- TestHistoryEvent.new("WorkflowExecutionStarted", 1, {}),
882
- TestHistoryEvent.new("DecisionTaskScheduled", 2, {}),
883
- TestHistoryEvent.new("DecisionTaskStarted", 3, {}),
884
- ])
922
+ activity.retry(:run_activity1, 5) {{:maximum_attempts => 5, :should_jitter => false}}
923
+ end
885
924
  end
886
- end
887
- class BadWorkflow
888
- class << self
889
- attr_accessor :task_list, :trace
925
+ swf_client = FakeServiceClient.new
926
+ task_list = "FixnumWorkflow_tasklist"
927
+ my_workflow_factory = workflow_factory(swf_client, domain) do |options|
928
+ options.workflow_name = "FixnumWorkflow"
929
+ options.execution_start_to_close_timeout = 3600
930
+ options.task_list = task_list
931
+ end
932
+ worker = SynchronousWorkflowWorker.new(swf_client, domain, task_list)
933
+ worker.add_workflow_implementation(FixnumWorkflow)
934
+ my_workflow = my_workflow_factory.get_client
935
+ workflow_execution = my_workflow.start_execution
936
+ worker.start
937
+ swf_client.trace.first[:decisions].first[:start_timer_decision_attributes][:start_to_fire_timeout].should == "5"
938
+ end
939
+
940
+ it "ensures that CompleteWorkflowExecutionFailed is correctly handled" do
941
+
942
+ class SynchronousWorkflowTaskPoller < WorkflowTaskPoller
943
+ def get_decision_task
944
+ fake_workflow_type = FakeWorkflowType.new(nil, "CompleteWorkflowExecutionFailedWorkflow.entry_point", "1")
945
+ TestHistoryWrapper.new(fake_workflow_type, FakeWorkflowExecution.new(nil, nil),
946
+ [
947
+ TestHistoryEvent.new("WorkflowExecutionStarted", 1, {}),
948
+ TestHistoryEvent.new("DecisionTaskScheduled", 2, {}),
949
+ TestHistoryEvent.new("DecisionTaskStarted", 3, {}),
950
+ TestHistoryEvent.new("DecisionTaskCompleted", 4, {}),
951
+ TestHistoryEvent.new("ActivityTaskScheduled", 5, {:activity_id => "Activity1"}),
952
+ TestHistoryEvent.new("ActivityTaskScheduled", 6, {:activity_id => "Activity2"}),
953
+ TestHistoryEvent.new("ActivityTaskStarted", 7, {}),
954
+ TestHistoryEvent.new("ActivityTaskFailed", 8, {:scheduled_event_id => 5}),
955
+ TestHistoryEvent.new("DecisionTaskScheduled", 9, {}),
956
+ TestHistoryEvent.new("ActivityTaskStarted", 10, {}),
957
+ TestHistoryEvent.new("ActivityTaskFailed", 11, {:scheduled_event_id => 6}),
958
+ TestHistoryEvent.new("DecisionTaskStarted", 12, {}),
959
+ TestHistoryEvent.new("DecisionTaskCompleted", 13, {}),
960
+ TestHistoryEvent.new("RequestCancelActivityTaskFailed", 14, FakeAttribute.new({:activity_id => "Activity2"}) ) ,
961
+ TestHistoryEvent.new("CompleteWorkflowExecutionFailed", 15, {}),
962
+ TestHistoryEvent.new("DecisionTaskScheduled", 16, {}),
963
+ ])
964
+ end
890
965
  end
891
- @trace = []
892
- extend Decider
893
- version "1"
894
- entry_point :entry_point
895
- def entry_point
896
- raise "This is an expected error"
966
+ workflow_type_object = double("workflow_type", :name => "CompleteWorkflowExecutionFailedWorkflow.entry_point", :start_execution => "" )
967
+ domain = FakeDomain.new(workflow_type_object)
968
+
969
+ class CompleteWorkflowExecutionFailedActivity
970
+ extend Activity
971
+ activity :run_activity1
972
+ def run_activity1; raise StandardError; end
973
+ end
974
+ class CompleteWorkflowExecutionFailedWorkflow
975
+ extend Workflows
976
+ workflow(:entry_point) { {:version => "1"} }
977
+ activity_client(:activity) { {:version => "1", :prefix_name => "CompleteWorkflowExecutionFailedActivity" } }
978
+ def entry_point
979
+ child_futures = []
980
+ error_handler do |t|
981
+ t.begin do
982
+ child_futures << activity.send_async(:run_activity1)
983
+ child_futures << activity.send_async(:run_activity1)
984
+ wait_for_all(child_futures)
985
+ end
986
+ t.rescue(Exception) do |error|
987
+ end
988
+ t.ensure do
989
+ end
990
+ end
991
+ end
897
992
  end
898
- end
899
- workflow_type_object = double("workflow_type", :name => "BadWorkflow.entry_point", :start_execution => "" )
900
- domain = FakeDomain.new(workflow_type_object)
993
+ swf_client = FakeServiceClient.new
994
+ task_list = "CompleteWorkflowExecutionFailedWorkflow_tasklist"
995
+ my_workflow_factory = workflow_factory(swf_client, domain) do |options|
996
+ options.workflow_name = "CompleteWorkflowExecutionFailedWorkflow"
997
+ options.execution_start_to_close_timeout = 3600
998
+ options.task_list = task_list
999
+ end
1000
+ worker = SynchronousWorkflowWorker.new(swf_client, domain, task_list)
1001
+ worker.add_workflow_implementation(CompleteWorkflowExecutionFailedWorkflow)
1002
+ my_workflow = my_workflow_factory.get_client
1003
+ workflow_execution = my_workflow.start_execution
1004
+ worker.start
1005
+ swf_client.trace.first[:decisions].first[:decision_type].should == "CompleteWorkflowExecution"
1006
+ end
1007
+
1008
+ it "ensures that time outs do not cause problems" do
1009
+ class SynchronousWorkflowTaskPoller < WorkflowTaskPoller
1010
+ def get_decision_task
1011
+ fake_workflow_type = FakeWorkflowType.new(nil, "TimeOutWorkflow.entry_point", "1")
1012
+ TestHistoryWrapper.new(fake_workflow_type, FakeWorkflowExecution.new(nil, nil),
1013
+ FakeEvents.new(["WorkflowExecutionStarted",
1014
+ "DecisionTaskScheduled",
1015
+ "DecisionTaskStarted",
1016
+ "DecisionTaskCompleted",
1017
+ ["StartChildWorkflowExecutionInitiated", {:workflow_id => "child_workflow_test"}],
1018
+ ["ChildWorkflowExecutionStarted", {:workflow_execution => FakeWorkflowExecution.new("1", "child_workflow_test"), :workflow_id => "child_workflow_test"}],
1019
+ "DecisionTaskScheduled",
1020
+ "DecisionTaskStarted",
1021
+ ["ChildWorkflowExecutionCompleted", {:workflow_execution => FakeWorkflowExecution.new("1", "child_workflow_test"), :workflow_id => "child_workflow_test"}],
1022
+ "DecisionTaskScheduled",
1023
+ "DecisionTaskTimedOut",
1024
+ "DecisionTaskStarted",
1025
+ "DecisionTaskCompleted",
1026
+ ["ActivityTaskScheduled", {:activity_id => "Activity1"}],
1027
+ "ActivityTaskStarted",
1028
+ ["ActivityTaskCompleted", {:scheduled_event_id => 14}],
1029
+ "DecisionTaskScheduled",
1030
+ "DecisionTaskStarted"
1031
+ ]))
1032
+ end
1033
+ end
1034
+ workflow_type_object = FakeWorkflowType.new(nil, "TimeOutWorkflow.entry_point", "1")
901
1035
 
902
- swf_client = FakeServiceClient.new
1036
+ domain = FakeDomain.new(workflow_type_object)
1037
+ swf_client = FakeServiceClient.new
1038
+ $my_workflow_client = workflow_client(swf_client, domain){{:prefix_name => "TimeOutWorkflow", :execution_method => "entry_point", :version => "1"}}
903
1039
 
904
- task_list = "BadWorkflow_tasklist"
905
- worker = SynchronousWorkflowWorker.new(swf_client, domain, task_list, BadWorkflow)
1040
+ class TimeOutActivity
1041
+ extend Activity
1042
+ activity :run_activity1
1043
+ def run_activity1; nil; end
1044
+ end
1045
+ class TimeOutWorkflow
1046
+ extend Workflows
1047
+ workflow(:entry_point) { {:version => "1"} }
1048
+ activity_client(:activity) { {:version => "1", :prefix_name => "TimeOutActivity" } }
906
1049
 
907
- my_workflow_factory = workflow_factory(swf_client, domain) do |options|
908
- options.workflow_name = "BadWorkflow"
909
- options.execution_start_to_close_timeout = 3600
910
- options.task_list = task_list
911
- end
912
- my_workflow = my_workflow_factory.get_client
913
- workflow_execution = my_workflow.start_execution
914
- worker.start
915
- swf_client.trace.first[:decisions].first[:fail_workflow_execution_decision_attributes][:details].should =~ /This is an expected error/
916
- end
917
- it "makes sure that you can do retry with the easier Fixnum semantic"do
918
-
919
- class SynchronousWorkflowTaskPoller < WorkflowTaskPoller
920
- def get_decision_task
921
- fake_workflow_type = FakeWorkflowType.new(nil, "FixnumWorkflow.entry_point", "1")
922
- TestHistoryWrapper.new(fake_workflow_type, FakeWorkflowExecution.new(nil, nil),
923
- [
924
- TestHistoryEvent.new("WorkflowExecutionStarted", 1, {}),
925
- TestHistoryEvent.new("DecisionTaskScheduled", 2, {}),
926
- TestHistoryEvent.new("DecisionTaskStarted", 3, {}),
927
- TestHistoryEvent.new("DecisionTaskCompleted", 4, {}),
928
- TestHistoryEvent.new("ActivityTaskScheduled", 5, {:activity_id => "Activity1"}),
929
- TestHistoryEvent.new("ActivityTaskStarted", 6, {}),
930
- TestHistoryEvent.new("ActivityTaskTimedOut", 7, {:scheduled_event_id => 5, :timeout_type => "START_TO_CLOSE"}),
931
- ])
1050
+ def entry_point
1051
+ $my_workflow_client.start_execution { { task_list: "nonsense_tasklist", workflow_id: "child_workflow_test" } }
1052
+ activity_client.run_activity1
1053
+ end
932
1054
  end
933
- end
934
- workflow_type_object = double("workflow_type", :name => "FixnumWorkflow.entry_point", :start_execution => "" )
935
- domain = FakeDomain.new(workflow_type_object)
936
1055
 
937
- class FixnumActivity
938
- extend Activity
939
- activity :run_activity1
940
- def run_activity1; raise StandardError; end
941
- end
942
- class FixnumWorkflow
943
- extend Workflows
944
- workflow(:entry_point) { {:version => "1"} }
945
- activity_client(:activity) { {:version => "1", :prefix_name => "FixnumActivity" } }
946
- def entry_point
947
1056
 
948
- activity.retry(:run_activity1, 5) {{:maximum_attempts => 5, :should_jitter => false}}
1057
+ task_list = "TimeOutWorkflow_tasklist"
1058
+ my_workflow_factory = workflow_factory(swf_client, domain) do |options|
1059
+ options.workflow_name = "TimeOutWorkflow"
1060
+ options.execution_start_to_close_timeout = 3600
1061
+ options.task_list = task_list
1062
+ end
1063
+
1064
+ worker = SynchronousWorkflowWorker.new(swf_client, domain, task_list)
1065
+ worker.add_workflow_implementation(TimeOutWorkflow)
1066
+ my_workflow = my_workflow_factory.get_client
1067
+ workflow_execution = my_workflow.start_execution
1068
+ worker.start
1069
+ swf_client.trace.first[:decisions].first[:decision_type].should == "CompleteWorkflowExecution"
1070
+ end
1071
+
1072
+ it "ensures that the other timeout issue is not a problem" do
1073
+ class SynchronousWorkflowTaskPoller < WorkflowTaskPoller
1074
+ def get_decision_task
1075
+ fake_workflow_type = FakeWorkflowType.new(nil, "OtherTimeOutWorkflow.entry_point", "1")
1076
+ TestHistoryWrapper.new(fake_workflow_type, FakeWorkflowExecution.new(nil, nil),
1077
+ FakeEvents.new(["WorkflowExecutionStarted",
1078
+ "DecisionTaskScheduled",
1079
+ "DecisionTaskStarted",
1080
+ "DecisionTaskCompleted",
1081
+ ["ActivityTaskScheduled", {:activity_id => "Activity1"}],
1082
+ ["ActivityTaskScheduled", {:activity_id => "Activity2"}],
1083
+ "ActivityTaskStarted",
1084
+ "ActivityTaskStarted",
1085
+ ["ActivityTaskCompleted", {:scheduled_event_id => 5}],
1086
+ "DecisionTaskScheduled",
1087
+ "DecisionTaskStarted",
1088
+ ["ActivityTaskCompleted", {:scheduled_event_id => 6}],
1089
+ "DecisionTaskScheduled",
1090
+ "DecisionTaskTimedOut",
1091
+ "DecisionTaskStarted",
1092
+ "DecisionTaskCompleted",
1093
+ ["ActivityTaskScheduled", {:activity_id => "Activity3"}],
1094
+ "ActivityTaskStarted",
1095
+ ["ActivityTaskCompleted", {:scheduled_event_id => 17}],
1096
+ "DecisionTaskScheduled",
1097
+ "DecisionTaskStarted"
1098
+ ]))
1099
+ end
949
1100
  end
950
- end
951
- swf_client = FakeServiceClient.new
952
- task_list = "FixnumWorkflow_tasklist"
953
- my_workflow_factory = workflow_factory(swf_client, domain) do |options|
954
- options.workflow_name = "FixnumWorkflow"
955
- options.execution_start_to_close_timeout = 3600
956
- options.task_list = task_list
957
- end
958
- worker = SynchronousWorkflowWorker.new(swf_client, domain, task_list)
959
- worker.add_workflow_implementation(FixnumWorkflow)
960
- my_workflow = my_workflow_factory.get_client
961
- workflow_execution = my_workflow.start_execution
962
- worker.start
963
- swf_client.trace.first[:decisions].first[:start_timer_decision_attributes][:start_to_fire_timeout].should == "5"
964
- end
1101
+ workflow_type_object = double("workflow_type", :name => "OtherTimeOutWorkflow.entry_point", :start_execution => "" )
1102
+ domain = FakeDomain.new(workflow_type_object)
1103
+ swf_client = FakeServiceClient.new
1104
+ $my_workflow_client = workflow_client(swf_client, domain) {{:prefix_name => "OtherTimeOutWorkflow", :execution_method => "entry_point", :version => "1"}}
1105
+ class OtherTimeOutActivity
1106
+ extend Activity
1107
+ activity :run_activity1
1108
+ def run_activity1; nil; end
1109
+ end
1110
+ class OtherTimeOutWorkflow
1111
+ extend Workflows
1112
+ workflow(:entry_point) { {:version => "1"} }
1113
+ activity_client(:activity) { {:version => "1", :prefix_name => "OtherTimeOutActivity" } }
1114
+
1115
+ def entry_point
1116
+ futures = []
1117
+ futures << activity_client.send_async(:run_activity1)
1118
+ futures << activity_client.send_async(:run_activity1)
1119
+ wait_for_all(futures)
1120
+ activity_client.run_activity1
1121
+ end
965
1122
 
966
- it "ensures that CompleteWorkflowExecutionFailed is correctly handled" do
967
-
968
- class SynchronousWorkflowTaskPoller < WorkflowTaskPoller
969
- def get_decision_task
970
- fake_workflow_type = FakeWorkflowType.new(nil, "CompleteWorkflowExecutionFailedWorkflow.entry_point", "1")
971
- TestHistoryWrapper.new(fake_workflow_type, FakeWorkflowExecution.new(nil, nil),
972
- [
973
- TestHistoryEvent.new("WorkflowExecutionStarted", 1, {}),
974
- TestHistoryEvent.new("DecisionTaskScheduled", 2, {}),
975
- TestHistoryEvent.new("DecisionTaskStarted", 3, {}),
976
- TestHistoryEvent.new("DecisionTaskCompleted", 4, {}),
977
- TestHistoryEvent.new("ActivityTaskScheduled", 5, {:activity_id => "Activity1"}),
978
- TestHistoryEvent.new("ActivityTaskScheduled", 6, {:activity_id => "Activity2"}),
979
- TestHistoryEvent.new("ActivityTaskStarted", 7, {}),
980
- TestHistoryEvent.new("ActivityTaskFailed", 8, {:scheduled_event_id => 5}),
981
- TestHistoryEvent.new("DecisionTaskScheduled", 9, {}),
982
- TestHistoryEvent.new("ActivityTaskStarted", 10, {}),
983
- TestHistoryEvent.new("ActivityTaskFailed", 11, {:scheduled_event_id => 6}),
984
- TestHistoryEvent.new("DecisionTaskStarted", 12, {}),
985
- TestHistoryEvent.new("DecisionTaskCompleted", 13, {}),
986
- TestHistoryEvent.new("RequestCancelActivityTaskFailed", 14, FakeAttribute.new({:activity_id => "Activity2"}) ) ,
987
- TestHistoryEvent.new("CompleteWorkflowExecutionFailed", 15, {}),
988
- TestHistoryEvent.new("DecisionTaskScheduled", 16, {}),
989
- ])
990
1123
  end
991
- end
992
- workflow_type_object = double("workflow_type", :name => "CompleteWorkflowExecutionFailedWorkflow.entry_point", :start_execution => "" )
993
- domain = FakeDomain.new(workflow_type_object)
994
1124
 
995
- class CompleteWorkflowExecutionFailedActivity
996
- extend Activity
997
- activity :run_activity1
998
- def run_activity1; raise StandardError; end
1125
+ task_list = "OtherTimeOutWorkflow_tasklist"
1126
+ my_workflow_factory = workflow_factory(swf_client, domain) do |options|
1127
+ options.workflow_name = "OtherTimeOutWorkflow"
1128
+ options.execution_start_to_close_timeout = 3600
1129
+ options.task_list = task_list
1130
+ end
1131
+
1132
+ worker = SynchronousWorkflowWorker.new(swf_client, domain, task_list)
1133
+ worker.add_workflow_implementation(OtherTimeOutWorkflow)
1134
+ my_workflow = my_workflow_factory.get_client
1135
+ workflow_execution = my_workflow.start_execution
1136
+ worker.start
1137
+ swf_client.trace.first[:decisions].first[:decision_type].should == "CompleteWorkflowExecution"
999
1138
  end
1000
- class CompleteWorkflowExecutionFailedWorkflow
1001
- extend Workflows
1002
- workflow(:entry_point) { {:version => "1"} }
1003
- activity_client(:activity) { {:version => "1", :prefix_name => "CompleteWorkflowExecutionFailedActivity" } }
1004
- def entry_point
1005
- child_futures = []
1006
- error_handler do |t|
1007
- t.begin do
1008
- child_futures << activity.send_async(:run_activity1)
1009
- child_futures << activity.send_async(:run_activity1)
1010
- wait_for_all(child_futures)
1011
- end
1012
- t.rescue(Exception) do |error|
1013
- end
1014
- t.ensure do
1139
+
1140
+ it "replicates the error seen in github issue #37" do
1141
+
1142
+ class TimeOutFailuresWorkflow
1143
+ extend Workflows
1144
+ workflow(:entry_point) do
1145
+ {
1146
+ execution_start_to_close_timeout: 600,
1147
+ task_list: "TimeOutFailuresWorkflow_tasklist",
1148
+ version: "1.0",
1149
+ }
1150
+ end
1151
+
1152
+ def entry_point
1153
+ error_handler do |t|
1154
+ t.begin do
1155
+ $client.send_async(:start_execution) { {task_list: "nonsense_task_list", workflow_id: "child_workflow_test"}}
1156
+ create_timer(5)
1157
+ end
1158
+ t.rescue AWS::Flow::ChildWorkflowException do |ex|
1159
+ # noop because we don't want the parent execution to die
1160
+ end
1015
1161
  end
1016
1162
  end
1017
1163
  end
1018
- end
1019
- swf_client = FakeServiceClient.new
1020
- task_list = "CompleteWorkflowExecutionFailedWorkflow_tasklist"
1021
- my_workflow_factory = workflow_factory(swf_client, domain) do |options|
1022
- options.workflow_name = "CompleteWorkflowExecutionFailedWorkflow"
1023
- options.execution_start_to_close_timeout = 3600
1024
- options.task_list = task_list
1025
- end
1026
- worker = SynchronousWorkflowWorker.new(swf_client, domain, task_list)
1027
- worker.add_workflow_implementation(CompleteWorkflowExecutionFailedWorkflow)
1028
- my_workflow = my_workflow_factory.get_client
1029
- workflow_execution = my_workflow.start_execution
1030
- worker.start
1031
- swf_client.trace.first[:decisions].first[:decision_type].should == "CompleteWorkflowExecution"
1032
- end
1033
1164
 
1034
- it "ensures that time outs do not cause problems" do
1035
- class SynchronousWorkflowTaskPoller < WorkflowTaskPoller
1036
- def get_decision_task
1037
- fake_workflow_type = FakeWorkflowType.new(nil, "TimeOutWorkflow.entry_point", "1")
1038
- TestHistoryWrapper.new(fake_workflow_type, FakeWorkflowExecution.new(nil, nil),
1039
- FakeEvents.new(["WorkflowExecutionStarted",
1040
- "DecisionTaskScheduled",
1041
- "DecisionTaskStarted",
1042
- "DecisionTaskCompleted",
1043
- ["StartChildWorkflowExecutionInitiated", {:workflow_id => "child_workflow_test"}],
1044
- ["ChildWorkflowExecutionStarted", {:workflow_execution => FakeWorkflowExecution.new("1", "child_workflow_test"), :workflow_id => "child_workflow_test"}],
1045
- "DecisionTaskScheduled",
1046
- "DecisionTaskStarted",
1047
- ["ChildWorkflowExecutionCompleted", {:workflow_execution => FakeWorkflowExecution.new("1", "child_workflow_test"), :workflow_id => "child_workflow_test"}],
1048
- "DecisionTaskScheduled",
1049
- "DecisionTaskTimedOut",
1050
- "DecisionTaskStarted",
1051
- "DecisionTaskCompleted",
1052
- ["ActivityTaskScheduled", {:activity_id => "Activity1"}],
1053
- "ActivityTaskStarted",
1054
- ["ActivityTaskCompleted", {:scheduled_event_id => 14}],
1055
- "DecisionTaskScheduled",
1056
- "DecisionTaskStarted"
1057
- ]))
1165
+ class SynchronousWorkflowTaskPoller < WorkflowTaskPoller
1166
+ def get_decision_task
1167
+ TestHistoryWrapper.new($workflow_type, FakeWorkflowExecution.new(nil, nil),
1168
+ FakeEvents.new(["WorkflowExecutionStarted",
1169
+ "DecisionTaskScheduled",
1170
+ "DecisionTaskStarted",
1171
+ "DecisionTaskCompleted",
1172
+ ["TimerStarted", {:decision_task_completed_event_id => 4, :timer_id => "Timer1", :start_to_fire_timeout => 10}],
1173
+ ["StartChildWorkflowExecutionInitiated", {:workflow_id => "child_workflow_test"}],
1174
+ ["ChildWorkflowExecutionStarted", {:workflow_execution => FakeWorkflowExecution.new("1", "child_workflow_test"), :workflow_id => "child_workflow_test"}],
1175
+
1176
+ "DecisionTaskScheduled",
1177
+ "DecisionTaskStarted",
1178
+ "DecisionTaskCompleted",
1179
+ ["ChildWorkflowExecutionTerminated", :workflow_execution => FakeWorkflowExecution.new("1", "child_workflow_test")],
1180
+ "DecisionTaskScheduled",
1181
+ "DecisionTaskStarted",
1182
+ ["TimerFired", {:timer_id => "Timer1"}],
1183
+ "DecisionTaskScheduled",
1184
+ "DecisionTaskCompleted",
1185
+ ["CancelTimerFailed", {:timer_id => "Timer1"}],
1186
+ "CompleteWorkflowExecutionFailed",
1187
+ "DecisionTaskScheduled",
1188
+ "DecisionTaskStarted"
1189
+ ]))
1190
+ end
1058
1191
  end
1059
- end
1060
- workflow_type_object = FakeWorkflowType.new(nil, "TimeOutWorkflow.entry_point", "1")
1061
-
1062
- domain = FakeDomain.new(workflow_type_object)
1063
- swf_client = FakeServiceClient.new
1064
- $my_workflow_client = workflow_client(swf_client, domain){{:prefix_name => "TimeOutWorkflow", :execution_method => "entry_point", :version => "1"}}
1065
1192
 
1066
- class TimeOutActivity
1067
- extend Activity
1068
- activity :run_activity1
1069
- def run_activity1; nil; end
1070
- end
1071
- class TimeOutWorkflow
1072
- extend Workflows
1073
- workflow(:entry_point) { {:version => "1"} }
1074
- activity_client(:activity) { {:version => "1", :prefix_name => "TimeOutActivity" } }
1193
+ $workflow_type = FakeWorkflowType.new(nil, "TimeOutFailuresWorkflow.entry_point", "1.0")
1194
+ swf_client = FakeServiceClient.new
1195
+ domain = FakeDomain.new($workflow_type)
1196
+ $client = AWS::Flow::workflow_client(swf_client, domain) { { from_class: "TimeOutFailuresWorkflow" } }
1075
1197
 
1076
- def entry_point
1077
- $my_workflow_client.start_execution { { task_list: "nonsense_tasklist", workflow_id: "child_workflow_test" } }
1078
- activity_client.run_activity1
1198
+ task_list = "TimeOutFailuresWorkflow_tasklist"
1199
+ my_workflow_factory = workflow_factory(swf_client, domain) do |options|
1079
1200
  end
1080
- end
1081
1201
 
1082
-
1083
- task_list = "TimeOutWorkflow_tasklist"
1084
- my_workflow_factory = workflow_factory(swf_client, domain) do |options|
1085
- options.workflow_name = "TimeOutWorkflow"
1086
- options.execution_start_to_close_timeout = 3600
1087
- options.task_list = task_list
1202
+ $client.start_execution
1203
+ worker = SynchronousWorkflowWorker.new(swf_client, domain, task_list, TimeOutFailuresWorkflow)
1204
+ worker.start
1205
+ #my_workflow = my_workflow_factory.get_client
1206
+ #workflow_execution = my_workflow.start_execution
1207
+ swf_client.trace.first[:decisions].first[:decision_type].should == "CompleteWorkflowExecution"
1088
1208
  end
1089
1209
 
1090
- worker = SynchronousWorkflowWorker.new(swf_client, domain, task_list)
1091
- worker.add_workflow_implementation(TimeOutWorkflow)
1092
- my_workflow = my_workflow_factory.get_client
1093
- workflow_execution = my_workflow.start_execution
1094
- worker.start
1095
- swf_client.trace.first[:decisions].first[:decision_type].should == "CompleteWorkflowExecution"
1096
1210
  end
1097
1211
 
1098
- it "ensures that the other timeout issue is not a problem" do
1099
- class SynchronousWorkflowTaskPoller < WorkflowTaskPoller
1100
- def get_decision_task
1101
- fake_workflow_type = FakeWorkflowType.new(nil, "OtherTimeOutWorkflow.entry_point", "1")
1102
- TestHistoryWrapper.new(fake_workflow_type, FakeWorkflowExecution.new(nil, nil),
1103
- FakeEvents.new(["WorkflowExecutionStarted",
1104
- "DecisionTaskScheduled",
1105
- "DecisionTaskStarted",
1106
- "DecisionTaskCompleted",
1107
- ["ActivityTaskScheduled", {:activity_id => "Activity1"}],
1108
- ["ActivityTaskScheduled", {:activity_id => "Activity2"}],
1109
- "ActivityTaskStarted",
1110
- "ActivityTaskStarted",
1111
- ["ActivityTaskCompleted", {:scheduled_event_id => 5}],
1112
- "DecisionTaskScheduled",
1113
- "DecisionTaskStarted",
1114
- ["ActivityTaskCompleted", {:scheduled_event_id => 6}],
1115
- "DecisionTaskScheduled",
1116
- "DecisionTaskTimedOut",
1117
- "DecisionTaskStarted",
1118
- "DecisionTaskCompleted",
1119
- ["ActivityTaskScheduled", {:activity_id => "Activity3"}],
1120
- "ActivityTaskStarted",
1121
- ["ActivityTaskCompleted", {:scheduled_event_id => 17}],
1122
- "DecisionTaskScheduled",
1123
- "DecisionTaskStarted"
1124
- ]))
1125
- end
1126
- end
1127
- workflow_type_object = double("workflow_type", :name => "OtherTimeOutWorkflow.entry_point", :start_execution => "" )
1128
- domain = FakeDomain.new(workflow_type_object)
1129
- swf_client = FakeServiceClient.new
1130
- $my_workflow_client = workflow_client(swf_client, domain) {{:prefix_name => "OtherTimeOutWorkflow", :execution_method => "entry_point", :version => "1"}}
1131
- class OtherTimeOutActivity
1132
- extend Activity
1133
- activity :run_activity1
1134
- def run_activity1; nil; end
1135
- end
1136
- class OtherTimeOutWorkflow
1137
- extend Workflows
1138
- workflow(:entry_point) { {:version => "1"} }
1139
- activity_client(:activity) { {:version => "1", :prefix_name => "OtherTimeOutActivity" } }
1140
-
1141
- def entry_point
1142
- futures = []
1143
- futures << activity_client.send_async(:run_activity1)
1144
- futures << activity_client.send_async(:run_activity1)
1145
- wait_for_all(futures)
1146
- activity_client.run_activity1
1212
+ describe "Misc tests" do
1213
+ it "makes sure that Workflows is equivalent to Decider" do
1214
+ class TestDecider
1215
+ extend Workflows
1147
1216
  end
1148
-
1217
+ TestDecider.methods.map(&:to_sym).should include :signal
1149
1218
  end
1150
1219
 
1151
- task_list = "OtherTimeOutWorkflow_tasklist"
1152
- my_workflow_factory = workflow_factory(swf_client, domain) do |options|
1153
- options.workflow_name = "OtherTimeOutWorkflow"
1154
- options.execution_start_to_close_timeout = 3600
1155
- options.task_list = task_list
1220
+ it "ensures you can eager_autoload" do
1221
+ require 'aws'
1222
+ require 'aws/decider'
1223
+ AWS.eager_autoload!
1156
1224
  end
1157
1225
 
1158
- worker = SynchronousWorkflowWorker.new(swf_client, domain, task_list)
1159
- worker.add_workflow_implementation(OtherTimeOutWorkflow)
1160
- my_workflow = my_workflow_factory.get_client
1161
- workflow_execution = my_workflow.start_execution
1162
- worker.start
1163
- swf_client.trace.first[:decisions].first[:decision_type].should == "CompleteWorkflowExecution"
1164
- end
1165
-
1166
- it "replicates the error seen in github issue #37" do
1167
-
1168
- class TimeOutFailuresWorkflow
1169
- extend Workflows
1170
- workflow(:entry_point) do
1171
- {
1172
- execution_start_to_close_timeout: 600,
1173
- task_list: "TimeOutFailuresWorkflow_tasklist",
1174
- version: "1.0",
1175
- }
1226
+ it "ensures that using send_async doesn't mutate the original hash" do
1227
+ class GenericClientTest < GenericClient
1228
+ def call_options(*args, &options)
1229
+ options.call
1230
+ end
1176
1231
  end
1177
-
1178
- def entry_point
1179
- error_handler do |t|
1180
- t.begin do
1181
- $client.send_async(:start_execution) { {task_list: "nonsense_task_list", workflow_id: "child_workflow_test"}}
1182
- create_timer(5)
1183
- end
1184
- t.rescue AWS::Flow::ChildWorkflowException do |ex|
1185
- # noop because we don't want the parent execution to die
1232
+ # Instead of setting up the fiber, just pretend we're internal
1233
+ module Utilities
1234
+ class << self
1235
+ alias_method :old_is_external, :is_external
1236
+ def is_external
1237
+ return false
1186
1238
  end
1187
1239
  end
1188
1240
  end
1189
- end
1190
-
1191
- class SynchronousWorkflowTaskPoller < WorkflowTaskPoller
1192
- def get_decision_task
1193
- TestHistoryWrapper.new($workflow_type, FakeWorkflowExecution.new(nil, nil),
1194
- FakeEvents.new(["WorkflowExecutionStarted",
1195
- "DecisionTaskScheduled",
1196
- "DecisionTaskStarted",
1197
- "DecisionTaskCompleted",
1198
- ["TimerStarted", {:decision_task_completed_event_id => 4, :timer_id => "Timer1", :start_to_fire_timeout => 10}],
1199
- ["StartChildWorkflowExecutionInitiated", {:workflow_id => "child_workflow_test"}],
1200
- ["ChildWorkflowExecutionStarted", {:workflow_execution => FakeWorkflowExecution.new("1", "child_workflow_test"), :workflow_id => "child_workflow_test"}],
1201
-
1202
- "DecisionTaskScheduled",
1203
- "DecisionTaskStarted",
1204
- "DecisionTaskCompleted",
1205
- ["ChildWorkflowExecutionTerminated", :workflow_execution => FakeWorkflowExecution.new("1", "child_workflow_test")],
1206
- "DecisionTaskScheduled",
1207
- "DecisionTaskStarted",
1208
- ["TimerFired", {:timer_id => "Timer1"}],
1209
- "DecisionTaskScheduled",
1210
- "DecisionTaskCompleted",
1211
- ["CancelTimerFailed", {:timer_id => "Timer1"}],
1212
- "CompleteWorkflowExecutionFailed",
1213
- "DecisionTaskScheduled",
1214
- "DecisionTaskStarted"
1215
- ]))
1241
+ generic_client = GenericClientTest.new
1242
+ previous_hash = {:key => :value}
1243
+ previous_hash_copy = previous_hash.dup
1244
+ generic_client.send_async(:call_options) { previous_hash }
1245
+ # Put is_external back before we have a chance of failing
1246
+ module Utilities
1247
+ class << self
1248
+ alias_method :is_external, :old_is_external
1249
+ end
1216
1250
  end
1251
+ previous_hash.should == previous_hash_copy
1217
1252
  end
1218
-
1219
- $workflow_type = FakeWorkflowType.new(nil, "TimeOutFailuresWorkflow.entry_point", "1.0")
1220
- swf_client = FakeServiceClient.new
1221
- domain = FakeDomain.new($workflow_type)
1222
- $client = AWS::Flow::workflow_client(swf_client, domain) { { from_class: "TimeOutFailuresWorkflow" } }
1223
-
1224
- task_list = "TimeOutFailuresWorkflow_tasklist"
1225
- my_workflow_factory = workflow_factory(swf_client, domain) do |options|
1226
- end
1227
-
1228
- $client.start_execution
1229
- worker = SynchronousWorkflowWorker.new(swf_client, domain, task_list, TimeOutFailuresWorkflow)
1230
- worker.start
1231
- #my_workflow = my_workflow_factory.get_client
1232
- #workflow_execution = my_workflow.start_execution
1233
- swf_client.trace.first[:decisions].first[:decision_type].should == "CompleteWorkflowExecution"
1234
- end
1235
-
1236
- end
1237
1253
 
1238
- describe "Misc tests" do
1239
- it "makes sure that Workflows is equivalent to Decider" do
1240
- class TestDecider
1241
- extend Workflows
1254
+ it "makes sure complete method is present on the completion handle and not open request" do
1255
+ ( OpenRequestInfo.new.respond_to? :complete ).should == false
1256
+ task = ExternalTask.new({}) { |t| }
1257
+ ( ExternalTaskCompletionHandle.new(task).respond_to? :complete ).should == true
1242
1258
  end
1243
- TestDecider.methods.map(&:to_sym).should include :signal
1244
1259
  end
1245
1260
 
1246
- it "ensures you can eager_autoload" do
1247
- require 'aws'
1248
- require 'aws/decider'
1249
- AWS.eager_autoload!
1250
- end
1261
+ describe "Workflow/Activity return values/exceptions" do
1262
+ it "ensures that a workflow exception message > 32k fails the workflow correctly and truncates the message" do
1251
1263
 
1252
- it "ensures that using send_async doesn't mutate the original hash" do
1253
- class GenericClientTest < GenericClient
1254
- def call_options(*args, &options)
1255
- options.call
1256
- end
1257
- end
1258
- # Instead of setting up the fiber, just pretend we're internal
1259
- module Utilities
1260
- class << self
1261
- alias_method :old_is_external, :is_external
1262
- def is_external
1263
- return false
1264
+ class WorkflowOutputTooLarge
1265
+ extend Workflows
1266
+ workflow(:entry_point) do
1267
+ {
1268
+ version: "1.0",
1269
+ default_execution_start_to_close_timeout: 600,
1270
+ }
1264
1271
  end
1265
- end
1266
- end
1267
- generic_client = GenericClientTest.new
1268
- previous_hash = {:key => :value}
1269
- previous_hash_copy = previous_hash.dup
1270
- generic_client.send_async(:call_options) { previous_hash }
1271
- # Put is_external back before we have a chance of failing
1272
- module Utilities
1273
- class << self
1274
- alias_method :is_external, :old_is_external
1275
- end
1276
- end
1277
- previous_hash.should == previous_hash_copy
1278
- end
1279
1272
 
1280
- it "makes sure complete method is present on the completion handle and not open request" do
1281
- ( OpenRequestInfo.new.respond_to? :complete ).should == false
1282
- task = ExternalTask.new({}) { |t| }
1283
- ( ExternalTaskCompletionHandle.new(task).respond_to? :complete ).should == true
1284
- end
1285
- end
1286
-
1287
- describe "Workflow/Activity return values/exceptions" do
1288
- it "ensures that a workflow exception message > 32k fails the workflow correctly and truncates the message" do
1289
-
1290
- class WorkflowOutputTooLarge
1291
- extend Workflows
1292
- workflow(:entry_point) do
1293
- {
1294
- version: "1.0",
1295
- default_execution_start_to_close_timeout: 600,
1296
- }
1273
+ def entry_point
1274
+ raise "a"*33000
1275
+ end
1297
1276
  end
1298
1277
 
1299
- def entry_point
1300
- raise "a"*33000
1278
+ class SynchronousWorkflowTaskPoller < WorkflowTaskPoller
1279
+ def get_decision_task
1280
+ TestHistoryWrapper.new($workflow_type, FakeWorkflowExecution.new(nil, nil),
1281
+ FakeEvents.new(["WorkflowExecutionStarted",
1282
+ "DecisionTaskScheduled",
1283
+ "DecisionTaskStarted",
1284
+ ]))
1285
+ end
1301
1286
  end
1302
- end
1303
1287
 
1304
- class SynchronousWorkflowTaskPoller < WorkflowTaskPoller
1305
- def get_decision_task
1306
- TestHistoryWrapper.new($workflow_type, FakeWorkflowExecution.new(nil, nil),
1307
- FakeEvents.new(["WorkflowExecutionStarted",
1308
- "DecisionTaskScheduled",
1309
- "DecisionTaskStarted",
1310
- ]))
1311
- end
1312
- end
1288
+ $workflow_type = FakeWorkflowType.new(nil, "WorkflowOutputTooLarge.entry_point", "1.0")
1289
+ swf_client = FakeServiceClient.new
1290
+ domain = FakeDomain.new($workflow_type)
1291
+ client = AWS::Flow::workflow_client(swf_client, domain) { { from_class: "WorkflowOutputTooLarge" } }
1313
1292
 
1314
- $workflow_type = FakeWorkflowType.new(nil, "WorkflowOutputTooLarge.entry_point", "1.0")
1315
- swf_client = FakeServiceClient.new
1316
- domain = FakeDomain.new($workflow_type)
1317
- client = AWS::Flow::workflow_client(swf_client, domain) { { from_class: "WorkflowOutputTooLarge" } }
1293
+ task_list = "WorkflowsOutputTooLarge"
1318
1294
 
1319
- task_list = "WorkflowsOutputTooLarge"
1295
+ client.start_execution
1296
+ worker = SynchronousWorkflowWorker.new(swf_client, domain, task_list, WorkflowOutputTooLarge)
1297
+ worker.start
1320
1298
 
1321
- client.start_execution
1322
- worker = SynchronousWorkflowWorker.new(swf_client, domain, task_list, WorkflowOutputTooLarge)
1323
- worker.start
1299
+ swf_client.trace.first[:decisions].first[:decision_type].should == "FailWorkflowExecution"
1324
1300
 
1325
- swf_client.trace.first[:decisions].first[:decision_type].should == "FailWorkflowExecution"
1301
+ reason = swf_client.trace.first[:decisions].first[:fail_workflow_execution_decision_attributes][:reason]
1302
+ details = swf_client.trace.first[:decisions].first[:fail_workflow_execution_decision_attributes][:details]
1303
+ reason.should include("TRUNCATED")
1304
+ exception = FlowConstants.data_converter.load(details)
1305
+ exception.class.should == RuntimeError
1306
+ exception.message.should == "a"*245+"[TRUNCATED]"
1307
+ end
1326
1308
 
1327
- reason = swf_client.trace.first[:decisions].first[:fail_workflow_execution_decision_attributes][:reason]
1328
- details = swf_client.trace.first[:decisions].first[:fail_workflow_execution_decision_attributes][:details]
1329
- reason.should include("TRUNCATED")
1330
- exception = FlowConstants.default_data_converter.load(details)
1331
- exception.class.should == RuntimeError
1332
- exception.message.should == "a"*245+"[TRUNCATED]"
1333
- end
1309
+ it "ensures that a workflow backtrace > 32k fails the workflow correctly and truncates the backtrace" do
1334
1310
 
1335
- it "ensures that a workflow backtrace > 32k fails the workflow correctly and truncates the backtrace" do
1311
+ class WorkflowOutputTooLarge
1312
+ extend Workflows
1313
+ workflow(:entry_point) do
1314
+ {
1315
+ version: "1.0",
1316
+ default_execution_start_to_close_timeout: 600,
1317
+ }
1318
+ end
1336
1319
 
1337
- class WorkflowOutputTooLarge
1338
- extend Workflows
1339
- workflow(:entry_point) do
1340
- {
1341
- version: "1.0",
1342
- default_execution_start_to_close_timeout: 600,
1343
- }
1320
+ def entry_point
1321
+ a = StandardError.new("SIMULATION")
1322
+ a.set_backtrace("a"*33000)
1323
+ raise a
1324
+ end
1344
1325
  end
1345
1326
 
1346
- def entry_point
1347
- a = StandardError.new("SIMULATION")
1348
- a.set_backtrace("a"*33000)
1349
- raise a
1327
+ class SynchronousWorkflowTaskPoller < WorkflowTaskPoller
1328
+ def get_decision_task
1329
+ TestHistoryWrapper.new($workflow_type, FakeWorkflowExecution.new(nil, nil),
1330
+ FakeEvents.new(["WorkflowExecutionStarted",
1331
+ "DecisionTaskScheduled",
1332
+ "DecisionTaskStarted",
1333
+ ]))
1334
+ end
1350
1335
  end
1351
- end
1352
1336
 
1353
- class SynchronousWorkflowTaskPoller < WorkflowTaskPoller
1354
- def get_decision_task
1355
- TestHistoryWrapper.new($workflow_type, FakeWorkflowExecution.new(nil, nil),
1356
- FakeEvents.new(["WorkflowExecutionStarted",
1357
- "DecisionTaskScheduled",
1358
- "DecisionTaskStarted",
1359
- ]))
1360
- end
1361
- end
1337
+ $workflow_type = FakeWorkflowType.new(nil, "WorkflowOutputTooLarge.entry_point", "1.0")
1338
+ swf_client = FakeServiceClient.new
1339
+ domain = FakeDomain.new($workflow_type)
1340
+ client = AWS::Flow::workflow_client(swf_client, domain) { { from_class: "WorkflowOutputTooLarge" } }
1362
1341
 
1363
- $workflow_type = FakeWorkflowType.new(nil, "WorkflowOutputTooLarge.entry_point", "1.0")
1364
- swf_client = FakeServiceClient.new
1365
- domain = FakeDomain.new($workflow_type)
1366
- client = AWS::Flow::workflow_client(swf_client, domain) { { from_class: "WorkflowOutputTooLarge" } }
1342
+ task_list = "WorkflowsOutputTooLarge"
1367
1343
 
1368
- task_list = "WorkflowsOutputTooLarge"
1344
+ client.start_execution
1345
+ worker = SynchronousWorkflowWorker.new(swf_client, domain, task_list, WorkflowOutputTooLarge)
1346
+ worker.start
1369
1347
 
1370
- client.start_execution
1371
- worker = SynchronousWorkflowWorker.new(swf_client, domain, task_list, WorkflowOutputTooLarge)
1372
- worker.start
1348
+ reason = swf_client.trace.first[:decisions].first[:fail_workflow_execution_decision_attributes][:reason]
1349
+ details = swf_client.trace.first[:decisions].first[:fail_workflow_execution_decision_attributes][:details]
1350
+ exception = FlowConstants.data_converter.load(details)
1351
+ exception.class.should == StandardError
1352
+ exception.message.should == "SIMULATION"
1353
+ exception.backtrace.first.should include("[TRUNCATED]")
1354
+ swf_client.trace.first[:decisions].first[:decision_type].should == "FailWorkflowExecution"
1355
+ end
1373
1356
 
1374
- reason = swf_client.trace.first[:decisions].first[:fail_workflow_execution_decision_attributes][:reason]
1375
- details = swf_client.trace.first[:decisions].first[:fail_workflow_execution_decision_attributes][:details]
1376
- exception = FlowConstants.default_data_converter.load(details)
1377
- exception.class.should == StandardError
1378
- exception.message.should == "SIMULATION"
1379
- exception.backtrace.first.should include("[TRUNCATED]")
1380
- swf_client.trace.first[:decisions].first[:decision_type].should == "FailWorkflowExecution"
1381
- end
1357
+ it "ensures that a workflow output > 32k fails the workflow correctly" do
1382
1358
 
1383
- it "ensures that a workflow output > 32k fails the workflow correctly" do
1359
+ class WorkflowOutputTooLarge
1360
+ extend Workflows
1361
+ workflow(:entry_point) do
1362
+ {
1363
+ version: "1.0",
1364
+ default_execution_start_to_close_timeout: 600,
1365
+ }
1366
+ end
1384
1367
 
1385
- class WorkflowOutputTooLarge
1386
- extend Workflows
1387
- workflow(:entry_point) do
1388
- {
1389
- version: "1.0",
1390
- default_execution_start_to_close_timeout: 600,
1391
- }
1368
+ def entry_point
1369
+ return "a"*33000
1370
+ end
1392
1371
  end
1393
1372
 
1394
- def entry_point
1395
- return "a"*33000
1373
+ class SynchronousWorkflowTaskPoller < WorkflowTaskPoller
1374
+ def get_decision_task
1375
+ TestHistoryWrapper.new($workflow_type, FakeWorkflowExecution.new(nil, nil),
1376
+ FakeEvents.new(["WorkflowExecutionStarted",
1377
+ "DecisionTaskScheduled",
1378
+ "DecisionTaskStarted",
1379
+ ]))
1380
+ end
1396
1381
  end
1397
- end
1398
1382
 
1399
- class SynchronousWorkflowTaskPoller < WorkflowTaskPoller
1400
- def get_decision_task
1401
- TestHistoryWrapper.new($workflow_type, FakeWorkflowExecution.new(nil, nil),
1402
- FakeEvents.new(["WorkflowExecutionStarted",
1403
- "DecisionTaskScheduled",
1404
- "DecisionTaskStarted",
1405
- ]))
1406
- end
1407
- end
1383
+ $workflow_type = FakeWorkflowType.new(nil, "WorkflowOutputTooLarge.entry_point", "1.0")
1384
+ swf_client = FakeServiceClient.new
1385
+ domain = FakeDomain.new($workflow_type)
1386
+ client = AWS::Flow::workflow_client(swf_client, domain) { { from_class: "WorkflowOutputTooLarge" } }
1408
1387
 
1409
- $workflow_type = FakeWorkflowType.new(nil, "WorkflowOutputTooLarge.entry_point", "1.0")
1410
- swf_client = FakeServiceClient.new
1411
- domain = FakeDomain.new($workflow_type)
1412
- client = AWS::Flow::workflow_client(swf_client, domain) { { from_class: "WorkflowOutputTooLarge" } }
1388
+ task_list = "WorkflowsOutputTooLarge"
1413
1389
 
1414
- task_list = "WorkflowsOutputTooLarge"
1390
+ client.start_execution
1391
+ worker = SynchronousWorkflowWorker.new(swf_client, domain, task_list, WorkflowOutputTooLarge)
1392
+ worker.start
1393
+ swf_client.trace.first[:decisions].first[:decision_type].should == "FailWorkflowExecution"
1394
+ end
1415
1395
 
1416
- client.start_execution
1417
- worker = SynchronousWorkflowWorker.new(swf_client, domain, task_list, WorkflowOutputTooLarge)
1418
- worker.start
1419
- swf_client.trace.first[:decisions].first[:decision_type].should == "FailWorkflowExecution"
1420
- end
1421
1396
 
1397
+ it "ensures that child workflows returning exceptions > 32k get wrapped correctly" do
1422
1398
 
1423
- it "ensures that child workflows returning exceptions > 32k get wrapped correctly" do
1399
+ class ChildWorkflowOutputTooLargeTestWorkflow
1400
+ extend Workflows
1401
+ workflow(:entry_point, :child) do
1402
+ {
1403
+ version: "1.0",
1404
+ default_execution_start_to_close_timeout: 600,
1405
+ }
1406
+ end
1424
1407
 
1425
- class ChildWorkflowOutputTooLargeTestWorkflow
1426
- extend Workflows
1427
- workflow(:entry_point, :child) do
1428
- {
1429
- version: "1.0",
1430
- default_execution_start_to_close_timeout: 600,
1431
- }
1408
+ def entry_point
1409
+ $my_workflow_client.child { { workflow_id: "child_workflow_test" }}
1410
+ end
1411
+ def child; end
1412
+ end
1413
+ class SynchronousWorkflowTaskPoller < WorkflowTaskPoller
1414
+ def get_decision_task
1415
+ fake_workflow_type = FakeWorkflowType.new(nil, "ChildWorkflowOutputTooLargeTestWorkflow.entry_point", "1.0")
1416
+ TestHistoryWrapper.new(fake_workflow_type, FakeWorkflowExecution.new(nil, nil),
1417
+ FakeEvents.new(["WorkflowExecutionStarted",
1418
+ "DecisionTaskScheduled",
1419
+ "DecisionTaskStarted",
1420
+ "DecisionTaskCompleted",
1421
+ ["StartChildWorkflowExecutionInitiated", {:workflow_id => "child_workflow_test"}],
1422
+ ["ChildWorkflowExecutionStarted", {:workflow_execution => FakeWorkflowExecution.new("1", "child_workflow_test"), :workflow_id => "child_workflow_test"}],
1423
+ "DecisionTaskScheduled",
1424
+ "DecisionTaskStarted",
1425
+ ["ChildWorkflowExecutionFailed", {:workflow_execution => FakeWorkflowExecution.new("1", "child_workflow_test"), :workflow_id => "child_workflow_test", :workflow_type => fake_workflow_type, :reason => "a"*245+"[TRUNCATED]", :details => "SIMULATED"}],
1426
+ "DecisionTaskScheduled",
1427
+ "DecisionTaskStarted",
1428
+ ]))
1429
+ end
1432
1430
  end
1431
+ workflow_type = FakeWorkflowType.new(nil, "ChildWorkflowOutputTooLargeTestWorkflow.entry_point", "1")
1433
1432
 
1434
- def entry_point
1435
- $my_workflow_client.child { { workflow_id: "child_workflow_test" }}
1436
- end
1437
- def child; end
1438
- end
1439
- class SynchronousWorkflowTaskPoller < WorkflowTaskPoller
1440
- def get_decision_task
1441
- fake_workflow_type = FakeWorkflowType.new(nil, "ChildWorkflowOutputTooLargeTestWorkflow.entry_point", "1.0")
1442
- TestHistoryWrapper.new(fake_workflow_type, FakeWorkflowExecution.new(nil, nil),
1443
- FakeEvents.new(["WorkflowExecutionStarted",
1444
- "DecisionTaskScheduled",
1445
- "DecisionTaskStarted",
1446
- "DecisionTaskCompleted",
1447
- ["StartChildWorkflowExecutionInitiated", {:workflow_id => "child_workflow_test"}],
1448
- ["ChildWorkflowExecutionStarted", {:workflow_execution => FakeWorkflowExecution.new("1", "child_workflow_test"), :workflow_id => "child_workflow_test"}],
1449
- "DecisionTaskScheduled",
1450
- "DecisionTaskStarted",
1451
- ["ChildWorkflowExecutionFailed", {:workflow_execution => FakeWorkflowExecution.new("1", "child_workflow_test"), :workflow_id => "child_workflow_test", :workflow_type => fake_workflow_type, :reason => "a"*245+"[TRUNCATED]", :details => "SIMULATED"}],
1452
- "DecisionTaskScheduled",
1453
- "DecisionTaskStarted",
1454
- ]))
1455
- end
1456
- end
1457
- workflow_type = FakeWorkflowType.new(nil, "ChildWorkflowOutputTooLargeTestWorkflow.entry_point", "1")
1458
-
1459
- domain = FakeDomain.new(workflow_type)
1460
- swf_client = FakeServiceClient.new
1461
- $my_workflow_client = workflow_client(swf_client, domain) { { from_class: "ChildWorkflowOutputTooLargeTestWorkflow" } }
1462
-
1463
- task_list = "ChildWorkflowOutputTooLargeTestWorkflow"
1464
-
1465
- $my_workflow_client.start_execution
1466
- worker = SynchronousWorkflowWorker.new(swf_client, domain, task_list, ChildWorkflowOutputTooLargeTestWorkflow)
1467
- worker.start
1468
- swf_client.trace.first[:decisions].first[:decision_type].should == "FailWorkflowExecution"
1469
- reason = swf_client.trace.first[:decisions].first[:fail_workflow_execution_decision_attributes][:reason]
1470
- details = swf_client.trace.first[:decisions].first[:fail_workflow_execution_decision_attributes][:details]
1471
- reason.should include("TRUNCATED")
1472
- exception = FlowConstants.default_data_converter.load(details)
1473
- exception.class.should == AWS::Flow::ChildWorkflowFailedException
1474
- exception.reason.should == "a"*245+"[TRUNCATED]"
1475
- exception.details.should == "SIMULATED"
1476
- end
1433
+ domain = FakeDomain.new(workflow_type)
1434
+ swf_client = FakeServiceClient.new
1435
+ $my_workflow_client = workflow_client(swf_client, domain) { { from_class: "ChildWorkflowOutputTooLargeTestWorkflow" } }
1477
1436
 
1478
- it "ensures that activities returning exceptions > 32k get wrapped correctly" do
1437
+ task_list = "ChildWorkflowOutputTooLargeTestWorkflow"
1479
1438
 
1480
- class ActivityExceptionTooLargeActivity
1481
- extend Activities
1482
- activity(:activity_a) do
1483
- {
1484
- version: "1.0"
1485
- }
1486
- end
1487
- def activity_a; end
1439
+ $my_workflow_client.start_execution
1440
+ worker = SynchronousWorkflowWorker.new(swf_client, domain, task_list, ChildWorkflowOutputTooLargeTestWorkflow)
1441
+ worker.start
1442
+ swf_client.trace.first[:decisions].first[:decision_type].should == "FailWorkflowExecution"
1443
+ reason = swf_client.trace.first[:decisions].first[:fail_workflow_execution_decision_attributes][:reason]
1444
+ details = swf_client.trace.first[:decisions].first[:fail_workflow_execution_decision_attributes][:details]
1445
+ reason.should include("TRUNCATED")
1446
+ exception = FlowConstants.data_converter.load(details)
1447
+ exception.class.should == AWS::Flow::ChildWorkflowFailedException
1448
+ exception.reason.should == "a"*245+"[TRUNCATED]"
1449
+ exception.details.should == "SIMULATED"
1488
1450
  end
1489
- class ActivityExceptionTooLargeTestWorkflow
1490
- extend Workflows
1491
- workflow(:entry_point) do
1492
- {
1493
- version: "1.0",
1494
- default_execution_start_to_close_timeout: 600,
1495
- }
1451
+
1452
+ it "ensures that activities returning exceptions > 32k get wrapped correctly" do
1453
+
1454
+ class ActivityExceptionTooLargeActivity
1455
+ extend Activities
1456
+ activity(:activity_a) do
1457
+ {
1458
+ version: "1.0"
1459
+ }
1460
+ end
1461
+ def activity_a; end
1496
1462
  end
1463
+ class ActivityExceptionTooLargeTestWorkflow
1464
+ extend Workflows
1465
+ workflow(:entry_point) do
1466
+ {
1467
+ version: "1.0",
1468
+ default_execution_start_to_close_timeout: 600,
1469
+ }
1470
+ end
1497
1471
 
1498
- activity_client(:client) { { from_class: "ActivityExceptionTooLargeActivity" } }
1499
- def entry_point
1500
- client.activity_a
1472
+ activity_client(:client) { { from_class: "ActivityExceptionTooLargeActivity" } }
1473
+ def entry_point
1474
+ client.activity_a
1475
+ end
1501
1476
  end
1502
- end
1503
- class SynchronousWorkflowTaskPoller < WorkflowTaskPoller
1504
- def get_decision_task
1505
- fake_workflow_type = FakeWorkflowType.new(nil, "ActivityExceptionTooLargeTestWorkflow.entry_point", "1.0")
1506
- TestHistoryWrapper.new(fake_workflow_type, FakeWorkflowExecution.new(nil, nil),
1507
- FakeEvents.new(["WorkflowExecutionStarted",
1508
- "DecisionTaskScheduled",
1509
- "DecisionTaskStarted",
1510
- "DecisionTaskCompleted",
1511
- ["ActivityTaskScheduled", {:activity_id => "Activity1"}],
1512
- "ActivityTaskStarted",
1513
- ["ActivityTaskFailed", scheduled_event_id: 5, activity_id: "Activity1", reason: "a"*245+"[TRUNCATED]", details: "SIMULATED"],
1514
- "DecisionTaskScheduled",
1515
- "DecisionTaskStarted",
1516
- ]))
1477
+ class SynchronousWorkflowTaskPoller < WorkflowTaskPoller
1478
+ def get_decision_task
1479
+ fake_workflow_type = FakeWorkflowType.new(nil, "ActivityExceptionTooLargeTestWorkflow.entry_point", "1.0")
1480
+ TestHistoryWrapper.new(fake_workflow_type, FakeWorkflowExecution.new(nil, nil),
1481
+ FakeEvents.new(["WorkflowExecutionStarted",
1482
+ "DecisionTaskScheduled",
1483
+ "DecisionTaskStarted",
1484
+ "DecisionTaskCompleted",
1485
+ ["ActivityTaskScheduled", {:activity_id => "Activity1"}],
1486
+ "ActivityTaskStarted",
1487
+ ["ActivityTaskFailed", scheduled_event_id: 5, activity_id: "Activity1", reason: "a"*245+"[TRUNCATED]", details: "SIMULATED"],
1488
+ "DecisionTaskScheduled",
1489
+ "DecisionTaskStarted",
1490
+ ]))
1491
+ end
1517
1492
  end
1493
+ workflow_type = FakeWorkflowType.new(nil, "ActivityExceptionTooLargeTestWorkflow.entry_point", "1")
1494
+
1495
+ domain = FakeDomain.new(workflow_type)
1496
+ swf_client = FakeServiceClient.new
1497
+ $my_workflow_client = workflow_client(swf_client, domain) { { from_class: "ActivityExceptionTooLargeTestWorkflow" } }
1498
+
1499
+ task_list = "ActivityExceptionTooLargeTestWorkflow"
1500
+
1501
+ $my_workflow_client.start_execution
1502
+ worker = SynchronousWorkflowWorker.new(swf_client, domain, task_list, ActivityExceptionTooLargeTestWorkflow)
1503
+ worker.start
1504
+ swf_client.trace.first[:decisions].first[:decision_type].should == "FailWorkflowExecution"
1505
+ reason = swf_client.trace.first[:decisions].first[:fail_workflow_execution_decision_attributes][:reason]
1506
+ details = swf_client.trace.first[:decisions].first[:fail_workflow_execution_decision_attributes][:details]
1507
+ reason.should include("TRUNCATED")
1508
+ exception = FlowConstants.data_converter.load(details)
1509
+ exception.class.should == AWS::Flow::ActivityTaskFailedException
1510
+ exception.reason.should == "a"*245+"[TRUNCATED]"
1511
+ exception.details.should == "SIMULATED"
1518
1512
  end
1519
- workflow_type = FakeWorkflowType.new(nil, "ActivityExceptionTooLargeTestWorkflow.entry_point", "1")
1520
-
1521
- domain = FakeDomain.new(workflow_type)
1522
- swf_client = FakeServiceClient.new
1523
- $my_workflow_client = workflow_client(swf_client, domain) { { from_class: "ActivityExceptionTooLargeTestWorkflow" } }
1524
-
1525
- task_list = "ActivityExceptionTooLargeTestWorkflow"
1526
-
1527
- $my_workflow_client.start_execution
1528
- worker = SynchronousWorkflowWorker.new(swf_client, domain, task_list, ActivityExceptionTooLargeTestWorkflow)
1529
- worker.start
1530
- swf_client.trace.first[:decisions].first[:decision_type].should == "FailWorkflowExecution"
1531
- reason = swf_client.trace.first[:decisions].first[:fail_workflow_execution_decision_attributes][:reason]
1532
- details = swf_client.trace.first[:decisions].first[:fail_workflow_execution_decision_attributes][:details]
1533
- reason.should include("TRUNCATED")
1534
- exception = FlowConstants.default_data_converter.load(details)
1535
- exception.class.should == AWS::Flow::ActivityTaskFailedException
1536
- exception.reason.should == "a"*245+"[TRUNCATED]"
1537
- exception.details.should == "SIMULATED"
1538
- end
1539
1513
 
1540
1514
 
1541
- # A bug was introduced in the previous commit which resulted in unnecessary
1542
- # calls to #describe_workflow_execution during logging of a DecisionTask. This
1543
- # test ensures that we don't call describe_workflow_execution anymore.
1544
- it "ensures describe_workflow_execution is not called during polling" do
1515
+ # A bug was introduced in the previous commit which resulted in unnecessary
1516
+ # calls to #describe_workflow_execution during logging of a DecisionTask. This
1517
+ # test ensures that we don't call describe_workflow_execution anymore.
1518
+ it "ensures describe_workflow_execution is not called during polling" do
1545
1519
 
1546
- swf = double("swf")
1547
- domain = double("domain")
1548
- allow(domain).to receive(:name).and_return("foo")
1549
- allow(swf).to receive(:domain).and_return(domain)
1520
+ swf = double("swf")
1521
+ domain = double("domain")
1522
+ allow(domain).to receive(:name).and_return("foo")
1523
+ allow(swf).to receive(:domain).and_return(domain)
1550
1524
 
1551
- # Set the expectations for the test
1552
- expect_any_instance_of(AWS::SimpleWorkflow::Client::V20120125).to_not receive(:describe_workflow_execution)
1525
+ # Set the expectations for the test
1526
+ expect_any_instance_of(AWS::SimpleWorkflow::Client::V20120125).to_not receive(:describe_workflow_execution)
1553
1527
 
1554
- class SomeWorkflow
1555
- extend Workflows
1556
- workflow(:start) do
1557
- {
1558
- version: "1.0",
1559
- default_execution_start_to_close_timeout: 600,
1560
- }
1528
+ class SomeWorkflow
1529
+ extend Workflows
1530
+ workflow(:start) do
1531
+ {
1532
+ version: "1.0",
1533
+ default_execution_start_to_close_timeout: 600,
1534
+ }
1535
+ end
1536
+ def start; end
1537
+ end
1538
+
1539
+ class SynchronousWorkflowTaskPoller < WorkflowTaskPoller
1540
+ def get_decision_task
1541
+ fake_workflow_type = FakeWorkflowType.new(nil, "SomeWorkflow.start", "1.0")
1542
+ domain = double("domain")
1543
+ TestHistoryWrapper.new(fake_workflow_type, AWS::SimpleWorkflow::WorkflowExecution.new(domain, "workflow_id", "run_id"),
1544
+ FakeEvents.new(["WorkflowExecutionStarted",
1545
+ "DecisionTaskScheduled",
1546
+ "DecisionTaskStarted",
1547
+ ]))
1548
+ end
1561
1549
  end
1562
- def start; end
1563
- end
1550
+ workflow_type = FakeWorkflowType.new(nil, "SomeWorkflow.entry_point", "1")
1551
+ client = workflow_client(swf, domain) { { from_class: "SomeWorkflow" } }
1564
1552
 
1565
- class SynchronousWorkflowTaskPoller < WorkflowTaskPoller
1566
- def get_decision_task
1567
- fake_workflow_type = FakeWorkflowType.new(nil, "SomeWorkflow.start", "1.0")
1568
- domain = double("domain")
1569
- TestHistoryWrapper.new(fake_workflow_type, AWS::SimpleWorkflow::WorkflowExecution.new(domain, "workflow_id", "run_id"),
1570
- FakeEvents.new(["WorkflowExecutionStarted",
1571
- "DecisionTaskScheduled",
1572
- "DecisionTaskStarted",
1573
- ]))
1574
- end
1553
+ worker = SynchronousWorkflowWorker.new(swf, domain, "SomeWorkflow", SomeWorkflow)
1554
+ worker.start
1575
1555
  end
1576
- workflow_type = FakeWorkflowType.new(nil, "SomeWorkflow.entry_point", "1")
1577
- client = workflow_client(swf, domain) { { from_class: "SomeWorkflow" } }
1578
1556
 
1579
- worker = SynchronousWorkflowWorker.new(swf, domain, "SomeWorkflow", SomeWorkflow)
1580
- worker.start
1581
1557
  end
1582
-
1583
1558
  end
1584
-