aws-flow 2.3.1 → 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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
-