aws-flow 1.1.1 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +8 -8
- data/lib/aws/decider/decider.rb +1 -1
- data/lib/aws/decider/executor.rb +36 -30
- data/lib/aws/decider/options.rb +178 -120
- data/lib/aws/decider/task_handler.rb +5 -7
- data/lib/aws/decider/task_poller.rb +49 -34
- data/lib/aws/decider/utilities.rb +13 -3
- data/lib/aws/decider/version.rb +1 -1
- data/lib/aws/decider/worker.rb +137 -40
- data/lib/aws/decider/workflow_client.rb +1 -1
- data/spec/aws/integration/integration_spec.rb +55 -33
- data/spec/aws/unit/decider_spec.rb +22 -19
- data/spec/aws/unit/executor_spec.rb +49 -0
- data/spec/aws/unit/options_spec.rb +293 -0
- data/spec/aws/unit/preinclude_tests.rb +2 -1
- data/spec/spec_helper.rb +1 -0
- metadata +4 -2
@@ -306,7 +306,7 @@ module AWS
|
|
306
306
|
state_machine = @decision_helper[workflow_id.to_s]
|
307
307
|
if state_machine.current_state == :created
|
308
308
|
open_request = @decision_helper.scheduled_external_workflows.delete(workflow_id)
|
309
|
-
open_request.complete
|
309
|
+
open_request.completion_handle.complete
|
310
310
|
end
|
311
311
|
state_machine.consume(:cancel)
|
312
312
|
end
|
@@ -192,7 +192,12 @@ describe "RubyFlowDecider" do
|
|
192
192
|
sleep 3
|
193
193
|
workflow_type, _ = @domain.workflow_types.page(:per_page => 1000).select {|x| x.name == workflow_type_name}
|
194
194
|
|
195
|
-
workflow_execution = workflow_type.start_execution(
|
195
|
+
workflow_execution = workflow_type.start_execution(
|
196
|
+
:execution_start_to_close_timeout => 3600,
|
197
|
+
:task_list => task_list,
|
198
|
+
:task_start_to_close_timeout => 3600,
|
199
|
+
:child_policy => :request_cancel
|
200
|
+
)
|
196
201
|
worker.run_once
|
197
202
|
activity_worker.run_once
|
198
203
|
worker.run_once
|
@@ -246,7 +251,18 @@ describe "RubyFlowDecider" do
|
|
246
251
|
activity_worker.register
|
247
252
|
sleep 3
|
248
253
|
workflow_id = "basic_activity_workflow"
|
249
|
-
run_id = @swf.client.start_workflow_execution(
|
254
|
+
run_id = @swf.client.start_workflow_execution(
|
255
|
+
:execution_start_to_close_timeout => "3600",
|
256
|
+
:task_list => {:name => task_list},
|
257
|
+
:task_start_to_close_timeout => "3600",
|
258
|
+
:child_policy => "REQUEST_CANCEL",
|
259
|
+
:workflow_type => {
|
260
|
+
:name => workflow_type_name,
|
261
|
+
:version => "1"
|
262
|
+
},
|
263
|
+
:workflow_id => workflow_id,
|
264
|
+
:domain => @domain.name.to_s
|
265
|
+
)
|
250
266
|
workflow_execution = AWS::SimpleWorkflow::WorkflowExecution.new(@domain, workflow_id, run_id["runId"])
|
251
267
|
@forking_executor = ForkingExecutor.new(:max_workers => 3)
|
252
268
|
@forking_executor.execute { worker.start }
|
@@ -379,7 +395,12 @@ describe "RubyFlowDecider" do
|
|
379
395
|
workflow_type_name = "LargeWorkflow.entry_point"
|
380
396
|
workflow_type, _ = @domain.workflow_types.page(:per_page => 1000).select {|x| x.name == workflow_type_name}
|
381
397
|
|
382
|
-
workflow_execution = workflow_type.start_execution(
|
398
|
+
workflow_execution = workflow_type.start_execution(
|
399
|
+
:execution_start_to_close_timeout => 3600,
|
400
|
+
:task_list => task_list,
|
401
|
+
:task_start_to_close_timeout => 15,
|
402
|
+
:child_policy => :request_cancel
|
403
|
+
)
|
383
404
|
@forking_executor = ForkingExecutor.new(:max_workers => 5)
|
384
405
|
@forking_executor.execute { activity_worker.start }
|
385
406
|
|
@@ -508,7 +529,14 @@ describe "RubyFlowDecider" do
|
|
508
529
|
@activity_class = Object.const_set("#{class_name}Activity", new_activity_class)
|
509
530
|
new_workflow_class = Class.new(ParentWorkflow) do
|
510
531
|
extend Workflows
|
511
|
-
workflow(:entry_point) {
|
532
|
+
workflow(:entry_point) {
|
533
|
+
{
|
534
|
+
:version => 1,
|
535
|
+
:execution_start_to_close_timeout => 120,
|
536
|
+
:task_list => task_list,
|
537
|
+
:prefix_name => "#{class_name}Workflow"
|
538
|
+
}
|
539
|
+
}
|
512
540
|
def entry_point
|
513
541
|
activity.run_activity1
|
514
542
|
end
|
@@ -611,8 +639,8 @@ describe "RubyFlowDecider" do
|
|
611
639
|
{
|
612
640
|
:default_task_heartbeat_timeout => "3600",
|
613
641
|
:default_task_list => task_list,
|
614
|
-
:
|
615
|
-
:
|
642
|
+
:default_task_schedule_to_start_timeout => 120,
|
643
|
+
:default_task_start_to_close_timeout => 120,
|
616
644
|
:version => "1",
|
617
645
|
:manual_completion => true
|
618
646
|
}
|
@@ -1017,7 +1045,13 @@ describe "RubyFlowDecider" do
|
|
1017
1045
|
@worker.run_once
|
1018
1046
|
history = workflow_execution.events.map(&:event_type)
|
1019
1047
|
history.last.should == "WorkflowExecutionFailed"
|
1020
|
-
# Should look something like: ["WorkflowExecutionStarted",
|
1048
|
+
# Should look something like: ["WorkflowExecutionStarted",
|
1049
|
+
# "DecisionTaskScheduled", "DecisionTaskStarted", "DecisionTaskCompleted",
|
1050
|
+
# "ActivityTaskScheduled", "ActivityTaskScheduled", "ActivityTaskStarted",
|
1051
|
+
# "ActivityTaskFailed", "DecisionTaskScheduled", "DecisionTaskStarted",
|
1052
|
+
# "DecisionTaskCompleted", "ActivityTaskCancelRequested",
|
1053
|
+
# "ActivityTaskCanceled", "DecisionTaskScheduled", "DecisionTaskStarted",
|
1054
|
+
# "DecisionTaskCompleted", "WorkflowExecutionFailed"]
|
1021
1055
|
history.should include "ActivityTaskCancelRequested"
|
1022
1056
|
end
|
1023
1057
|
|
@@ -1025,7 +1059,11 @@ describe "RubyFlowDecider" do
|
|
1025
1059
|
general_test(:task_list => "exponential_retry_key", :class_name => "ExponentialRetryKey")
|
1026
1060
|
@workflow_class.class_eval do
|
1027
1061
|
def entry_point
|
1028
|
-
activity.reconfigure(:run_activity1) {
|
1062
|
+
activity.reconfigure(:run_activity1) {
|
1063
|
+
{
|
1064
|
+
:exponential_retry => {:maximum_attempts => 1},
|
1065
|
+
:default_task_schedule_to_start_timeout => 5}
|
1066
|
+
}
|
1029
1067
|
activity.run_activity1
|
1030
1068
|
end
|
1031
1069
|
end
|
@@ -1318,15 +1356,6 @@ describe "RubyFlowDecider" do
|
|
1318
1356
|
end
|
1319
1357
|
it "makes sure that you can have an asynchronous timer with a block" do
|
1320
1358
|
general_test(:task_list => "async_timer_with_block", :class_name => "AsyncBlock")
|
1321
|
-
@activity_class.class_eval do
|
1322
|
-
def run_activity2
|
1323
|
-
end
|
1324
|
-
activity :run_activity2 do |options|
|
1325
|
-
options.default_task_heartbeat_timeout = "3600"
|
1326
|
-
options.default_task_list = self.task_list
|
1327
|
-
options.version = "1"
|
1328
|
-
end
|
1329
|
-
end
|
1330
1359
|
@workflow_class.class_eval do
|
1331
1360
|
def entry_point
|
1332
1361
|
create_timer_async(5) { activity.run_activity1 }
|
@@ -2115,7 +2144,6 @@ describe "RubyFlowDecider" do
|
|
2115
2144
|
# Sleep to give the threads some time to compute, as we'll run right out of
|
2116
2145
|
# the test before they can run otherwise
|
2117
2146
|
sleep 50
|
2118
|
-
p workflow_execution.events.to_a
|
2119
2147
|
workflow_execution.events.map(&:event_type).count("WorkflowExecutionCompleted").should == 1
|
2120
2148
|
end
|
2121
2149
|
|
@@ -2228,7 +2256,6 @@ describe "RubyFlowDecider" do
|
|
2228
2256
|
# end
|
2229
2257
|
# end
|
2230
2258
|
# end
|
2231
|
-
# debugger
|
2232
2259
|
|
2233
2260
|
worker.run_once
|
2234
2261
|
activity_worker.run_once
|
@@ -2384,7 +2411,9 @@ describe "RubyFlowDecider" do
|
|
2384
2411
|
options.version = "1"
|
2385
2412
|
options.task_list = "client_test_async2"
|
2386
2413
|
end
|
2387
|
-
client.send_async(:start_execution, arg) {
|
2414
|
+
client.send_async(:start_execution, arg) {
|
2415
|
+
{ :task_start_to_close_timeout => 35 }
|
2416
|
+
}
|
2388
2417
|
client.send_async(:start_execution, arg)
|
2389
2418
|
end
|
2390
2419
|
end
|
@@ -3080,23 +3109,16 @@ describe "RubyFlowDecider" do
|
|
3080
3109
|
|
3081
3110
|
it "ensures you can use manual completion" do
|
3082
3111
|
general_test(:task_list => "manual_completion", :class_name => "ManualCompletion")
|
3083
|
-
|
3084
|
-
activity :run_activity1 do
|
3085
|
-
{
|
3086
|
-
:default_task_heartbeat_timeout => "3600",
|
3087
|
-
:default_task_list => task_list,
|
3088
|
-
:task_schedule_to_start_timeout => 120,
|
3089
|
-
:task_start_to_close_timeout => 120,
|
3090
|
-
:version => "1",
|
3091
|
-
:manual_completion => true
|
3092
|
-
}
|
3093
|
-
end
|
3094
|
-
end
|
3112
|
+
|
3095
3113
|
activity_worker = ActivityWorker.new(@swf.client, @domain, "manual_completion", @activity_class)
|
3096
3114
|
activity_worker.register
|
3097
3115
|
@workflow_class.class_eval do
|
3116
|
+
activity_client(:activity1) { {
|
3117
|
+
from_class: self.activity_class,
|
3118
|
+
manual_completion: true
|
3119
|
+
} }
|
3098
3120
|
def entry_point
|
3099
|
-
activity.
|
3121
|
+
activity.run_activity2
|
3100
3122
|
end
|
3101
3123
|
end
|
3102
3124
|
workflow_execution = @my_workflow_client.start_execution
|
@@ -105,7 +105,7 @@ class FakeWorkflowExecution
|
|
105
105
|
@run_id = run_id
|
106
106
|
@workflow_id = workflow_id
|
107
107
|
end
|
108
|
-
attr_accessor :run_id, :workflow_id
|
108
|
+
attr_accessor :run_id, :workflow_id, :task_list
|
109
109
|
end
|
110
110
|
|
111
111
|
class FakeWorkflowExecutionCollecton
|
@@ -507,7 +507,7 @@ describe "FakeHistory" do
|
|
507
507
|
|
508
508
|
|
509
509
|
class SynchronousWorkflowTaskPoller < WorkflowTaskPoller
|
510
|
-
def
|
510
|
+
def get_decision_task
|
511
511
|
fake_workflow_type = FakeWorkflowType.new(nil, "BadWorkflow.entry_point", "1")
|
512
512
|
TestHistoryWrapper.new(fake_workflow_type,
|
513
513
|
[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"}),
|
@@ -521,7 +521,6 @@ describe "FakeHistory" do
|
|
521
521
|
worker.start
|
522
522
|
# @forking_executor.execute { activity_worker.start }
|
523
523
|
|
524
|
-
# debugger
|
525
524
|
# worker.start
|
526
525
|
swf_client.trace.first[:decisions].first[:decision_type].should ==
|
527
526
|
"CompleteWorkflowExecution"
|
@@ -529,7 +528,7 @@ describe "FakeHistory" do
|
|
529
528
|
|
530
529
|
it "reproduces the ActivityTaskTimedOut problem" do
|
531
530
|
class SynchronousWorkflowTaskPoller < WorkflowTaskPoller
|
532
|
-
def
|
531
|
+
def get_decision_task
|
533
532
|
fake_workflow_type = FakeWorkflowType.new(nil, "BadWorkflow.entry_point", "1")
|
534
533
|
TestHistoryWrapper.new(fake_workflow_type,
|
535
534
|
[
|
@@ -567,7 +566,6 @@ describe "FakeHistory" do
|
|
567
566
|
workflow_type_object = double("workflow_type", :name => "BadWorkflow.entry_point", :start_execution => "" )
|
568
567
|
domain = FakeDomain.new(workflow_type_object)
|
569
568
|
|
570
|
-
|
571
569
|
swf_client = FakeServiceClient.new
|
572
570
|
task_list = "BadWorkflow_tasklist"
|
573
571
|
worker = SynchronousWorkflowWorker.new(swf_client, domain, task_list)
|
@@ -592,7 +590,7 @@ describe "FakeHistory" do
|
|
592
590
|
|
593
591
|
it "makes sure that exponential retry can take arguments" do
|
594
592
|
class SynchronousWorkflowTaskPoller < WorkflowTaskPoller
|
595
|
-
def
|
593
|
+
def get_decision_task
|
596
594
|
fake_workflow_type = FakeWorkflowType.new(nil, "BadWorkflow.entry_point", "1")
|
597
595
|
TestHistoryWrapper.new(fake_workflow_type,
|
598
596
|
[
|
@@ -646,7 +644,7 @@ describe "FakeHistory" do
|
|
646
644
|
|
647
645
|
it "makes sure that overriding works correctly" do
|
648
646
|
class SynchronousWorkflowTaskPoller < WorkflowTaskPoller
|
649
|
-
def
|
647
|
+
def get_decision_task
|
650
648
|
fake_workflow_type = FakeWorkflowType.new(nil, "BadWorkflow.entry_point", "1")
|
651
649
|
TestHistoryWrapper.new(fake_workflow_type,
|
652
650
|
[
|
@@ -699,7 +697,7 @@ describe "FakeHistory" do
|
|
699
697
|
|
700
698
|
it "makes sure that exponential_retry blocks correctly" do
|
701
699
|
class SynchronousWorkflowTaskPoller < WorkflowTaskPoller
|
702
|
-
def
|
700
|
+
def get_decision_task
|
703
701
|
fake_workflow_type = FakeWorkflowType.new(nil, "BadWorkflow.entry_point", "1")
|
704
702
|
TestHistoryWrapper.new(fake_workflow_type,
|
705
703
|
[
|
@@ -761,7 +759,7 @@ describe "FakeHistory" do
|
|
761
759
|
|
762
760
|
it "makes sure that exponential_retry blocks correctly when done through configure" do
|
763
761
|
class SynchronousWorkflowTaskPoller < WorkflowTaskPoller
|
764
|
-
def
|
762
|
+
def get_decision_task
|
765
763
|
fake_workflow_type = FakeWorkflowType.new(nil, "BadWorkflow.entry_point", "1")
|
766
764
|
TestHistoryWrapper.new(fake_workflow_type,
|
767
765
|
[
|
@@ -829,7 +827,7 @@ describe "FakeHistory" do
|
|
829
827
|
|
830
828
|
it "makes sure that exponential_retry blocks correctly when done through the activity_client" do
|
831
829
|
class SynchronousWorkflowTaskPoller < WorkflowTaskPoller
|
832
|
-
def
|
830
|
+
def get_decision_task
|
833
831
|
fake_workflow_type = FakeWorkflowType.new(nil, "BadWorkflow.entry_point", "1")
|
834
832
|
TestHistoryWrapper.new(fake_workflow_type,
|
835
833
|
[
|
@@ -897,7 +895,7 @@ describe "FakeHistory" do
|
|
897
895
|
|
898
896
|
it "makes sure that multiple schedules followed by a timeout work" do
|
899
897
|
class SynchronousWorkflowTaskPoller < WorkflowTaskPoller
|
900
|
-
def
|
898
|
+
def get_decision_task
|
901
899
|
fake_workflow_type = FakeWorkflowType.new(nil, "BadWorkflow.entry_point", "1")
|
902
900
|
TestHistoryWrapper.new(fake_workflow_type,
|
903
901
|
[
|
@@ -974,7 +972,7 @@ describe "FakeHistory" do
|
|
974
972
|
|
975
973
|
it "makes sure that timeout followed by success is handled correctly" do
|
976
974
|
class SynchronousWorkflowTaskPoller < WorkflowTaskPoller
|
977
|
-
def
|
975
|
+
def get_decision_task
|
978
976
|
fake_workflow_type = FakeWorkflowType.new(nil, "BadWorkflow.entry_point", "1")
|
979
977
|
TestHistoryWrapper.new(fake_workflow_type,
|
980
978
|
[
|
@@ -1053,7 +1051,7 @@ describe "FakeHistory" do
|
|
1053
1051
|
|
1054
1052
|
it "makes sure that signal works correctly" do
|
1055
1053
|
class SynchronousWorkflowTaskPoller < WorkflowTaskPoller
|
1056
|
-
def
|
1054
|
+
def get_decision_task
|
1057
1055
|
fake_workflow_type = FakeWorkflowType.new(nil, "BadWorkflow.entry_point", "1")
|
1058
1056
|
TestHistoryWrapper.new(fake_workflow_type,
|
1059
1057
|
[
|
@@ -1119,7 +1117,7 @@ describe "FakeHistory" do
|
|
1119
1117
|
|
1120
1118
|
it "makes sure that raising an error properly fails a workflow" do
|
1121
1119
|
class SynchronousWorkflowTaskPoller < WorkflowTaskPoller
|
1122
|
-
def
|
1120
|
+
def get_decision_task
|
1123
1121
|
fake_workflow_type = FakeWorkflowType.new(nil, "BadWorkflow.entry_point", "1")
|
1124
1122
|
TestHistoryWrapper.new(fake_workflow_type,
|
1125
1123
|
[
|
@@ -1162,7 +1160,7 @@ describe "FakeHistory" do
|
|
1162
1160
|
it "makes sure that you can do retry with the easier Fixnum semantic"do
|
1163
1161
|
|
1164
1162
|
class SynchronousWorkflowTaskPoller < WorkflowTaskPoller
|
1165
|
-
def
|
1163
|
+
def get_decision_task
|
1166
1164
|
fake_workflow_type = FakeWorkflowType.new(nil, "FixnumWorkflow.entry_point", "1")
|
1167
1165
|
TestHistoryWrapper.new(fake_workflow_type,
|
1168
1166
|
[
|
@@ -1211,7 +1209,7 @@ describe "FakeHistory" do
|
|
1211
1209
|
it "ensures that CompleteWorkflowExecutionFailed is correctly handled" do
|
1212
1210
|
|
1213
1211
|
class SynchronousWorkflowTaskPoller < WorkflowTaskPoller
|
1214
|
-
def
|
1212
|
+
def get_decision_task
|
1215
1213
|
fake_workflow_type = FakeWorkflowType.new(nil, "CompleteWorkflowExecutionFailedWorkflow.entry_point", "1")
|
1216
1214
|
TestHistoryWrapper.new(fake_workflow_type,
|
1217
1215
|
[
|
@@ -1278,7 +1276,7 @@ describe "FakeHistory" do
|
|
1278
1276
|
|
1279
1277
|
it "ensures that time outs do not cause problems" do
|
1280
1278
|
class SynchronousWorkflowTaskPoller < WorkflowTaskPoller
|
1281
|
-
def
|
1279
|
+
def get_decision_task
|
1282
1280
|
fake_workflow_type = FakeWorkflowType.new(nil, "TimeOutWorkflow.entry_point", "1")
|
1283
1281
|
TestHistoryWrapper.new(fake_workflow_type,
|
1284
1282
|
FakeEvents.new(["WorkflowExecutionStarted",
|
@@ -1343,7 +1341,7 @@ describe "FakeHistory" do
|
|
1343
1341
|
|
1344
1342
|
it "ensures that the other timeout issue is not a problem" do
|
1345
1343
|
class SynchronousWorkflowTaskPoller < WorkflowTaskPoller
|
1346
|
-
def
|
1344
|
+
def get_decision_task
|
1347
1345
|
fake_workflow_type = FakeWorkflowType.new(nil, "OtherTimeOutWorkflow.entry_point", "1")
|
1348
1346
|
TestHistoryWrapper.new(fake_workflow_type,
|
1349
1347
|
FakeEvents.new(["WorkflowExecutionStarted",
|
@@ -1490,6 +1488,11 @@ describe "Misc tests" do
|
|
1490
1488
|
workflow = client.start_external_workflow
|
1491
1489
|
workflow.workflow_id.should match(regex)
|
1492
1490
|
end
|
1491
|
+
it "makes sure complete method is present on the completion handle and not open request" do
|
1492
|
+
( OpenRequestInfo.new.respond_to? :complete ).should == false
|
1493
|
+
task = ExternalTask.new({}) { |t| puts t }
|
1494
|
+
( ExternalTaskCompletionHandle.new(task).respond_to? :complete ).should == true
|
1495
|
+
end
|
1493
1496
|
end
|
1494
1497
|
|
1495
1498
|
|
@@ -1564,7 +1567,7 @@ class TestActivityWorker < ActivityWorker
|
|
1564
1567
|
end
|
1565
1568
|
|
1566
1569
|
class FakeTaskPoller < WorkflowTaskPoller
|
1567
|
-
def
|
1570
|
+
def get_decision_task
|
1568
1571
|
nil
|
1569
1572
|
end
|
1570
1573
|
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
##
|
2
|
+
# Copyright 2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License").
|
5
|
+
# You may not use this file except in compliance with the License.
|
6
|
+
# A copy of the License is located at
|
7
|
+
#
|
8
|
+
# http://aws.amazon.com/apache2.0
|
9
|
+
#
|
10
|
+
# or in the "license" file accompanying this file. This file is distributed
|
11
|
+
# on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
12
|
+
# express or implied. See the License for the specific language governing
|
13
|
+
# permissions and limitations under the License.
|
14
|
+
##
|
15
|
+
|
16
|
+
require 'aws/decider'
|
17
|
+
|
18
|
+
describe AWS::Flow::ForkingExecutor do
|
19
|
+
context "#remove_completed_pids" do
|
20
|
+
context "with block=false" do
|
21
|
+
it "should reap all completed child processes" do
|
22
|
+
executor = AWS::Flow::ForkingExecutor.new(max_workers: 3)
|
23
|
+
|
24
|
+
executor.execute { sleep 1 }
|
25
|
+
executor.execute { sleep 1 }
|
26
|
+
executor.execute { sleep 5 }
|
27
|
+
executor.pids.size.should == 3
|
28
|
+
sleep 2
|
29
|
+
executor.send(:remove_completed_pids, false)
|
30
|
+
# The two processes that are completed will be reaped.
|
31
|
+
executor.pids.size.should == 1
|
32
|
+
end
|
33
|
+
end
|
34
|
+
context "with block=true" do
|
35
|
+
it "should wait for and reap the first child process available" do
|
36
|
+
executor = AWS::Flow::ForkingExecutor.new(max_workers: 3)
|
37
|
+
|
38
|
+
executor.execute { sleep 1 }
|
39
|
+
executor.execute { sleep 1 }
|
40
|
+
executor.execute { sleep 5 }
|
41
|
+
executor.pids.size.should == 3
|
42
|
+
sleep 2
|
43
|
+
executor.send(:remove_completed_pids, true)
|
44
|
+
# One of the two processes that are completed will be reaped
|
45
|
+
executor.pids.size.should == 2
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,293 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe AWS::Flow::OptionsMethods do
|
4
|
+
|
5
|
+
class FooDefaults < AWS::Flow::Defaults
|
6
|
+
def default_foo; 1; end
|
7
|
+
def default_baz; 2; end
|
8
|
+
def default_xyz; 3; end
|
9
|
+
end
|
10
|
+
class FooOptions < AWS::Flow::Options
|
11
|
+
include AWS::Flow::OptionsMethods
|
12
|
+
property(:default_foo)
|
13
|
+
property(:foo)
|
14
|
+
property(:bar)
|
15
|
+
property(:baz)
|
16
|
+
property(:xyz)
|
17
|
+
property(:default_baz)
|
18
|
+
default_classes << FooDefaults.new
|
19
|
+
|
20
|
+
def default_keys
|
21
|
+
[:default_foo, :default_baz, :default_xyz]
|
22
|
+
end
|
23
|
+
def make_runtime_key(key)
|
24
|
+
key.to_s.gsub(/default_/, "").to_sym
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context "#get_full_options" do
|
29
|
+
it "should return merged default and regular options" do
|
30
|
+
options = FooOptions.new(
|
31
|
+
default_foo: 10,
|
32
|
+
bar: 10,
|
33
|
+
xyz: 10
|
34
|
+
)
|
35
|
+
options.get_full_options[:foo].should == "10"
|
36
|
+
options.get_full_options[:bar].should == "10"
|
37
|
+
options.get_full_options[:baz].should == "2"
|
38
|
+
options.get_full_options[:xyz].should == "10"
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
context "#get_runtime_options" do
|
44
|
+
it "should return the runtime values for the default options" do
|
45
|
+
options = FooOptions.new(
|
46
|
+
default_foo: 10,
|
47
|
+
bar: 10
|
48
|
+
)
|
49
|
+
options.get_runtime_options.has_key?(:foo).should == true
|
50
|
+
options.get_runtime_options.has_key?(:baz).should == true
|
51
|
+
options.get_runtime_options[:foo].should == "10"
|
52
|
+
options.get_runtime_options[:baz].should == "2"
|
53
|
+
options.get_runtime_options.has_key?(:bar).should == false
|
54
|
+
end
|
55
|
+
end
|
56
|
+
context "#get_default_options" do
|
57
|
+
it "should return the default values for the default options" do
|
58
|
+
options = FooOptions.new(
|
59
|
+
default_foo: 10,
|
60
|
+
baz: 10
|
61
|
+
)
|
62
|
+
options.get_default_options.has_key?(:default_foo).should == true
|
63
|
+
options.get_default_options.has_key?(:default_baz).should == true
|
64
|
+
options.get_default_options[:default_foo].should == "10"
|
65
|
+
options.get_default_options[:default_baz].should == "2"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
describe AWS::Flow::ActivityOptions do
|
71
|
+
context "#defaults" do
|
72
|
+
it "should be initialized correctly" do
|
73
|
+
options = AWS::Flow::ActivityOptions.new
|
74
|
+
options.default_task_schedule_to_start_timeout.should == "NONE"
|
75
|
+
options.default_task_schedule_to_close_timeout.should == "NONE"
|
76
|
+
options.default_task_start_to_close_timeout.should == "NONE"
|
77
|
+
options.default_task_heartbeat_timeout.should == "NONE"
|
78
|
+
options.data_converter.should ==
|
79
|
+
AWS::Flow::FlowConstants.default_data_converter
|
80
|
+
end
|
81
|
+
|
82
|
+
it "should change to the value passed in" do
|
83
|
+
options = AWS::Flow::ActivityOptions.new({
|
84
|
+
default_task_schedule_to_start_timeout: 20,
|
85
|
+
default_task_schedule_to_close_timeout: 50,
|
86
|
+
default_task_start_to_close_timeout: 30,
|
87
|
+
default_task_heartbeat_timeout: 5,
|
88
|
+
})
|
89
|
+
options.default_task_schedule_to_start_timeout.should == "20"
|
90
|
+
options.default_task_schedule_to_close_timeout.should == "50"
|
91
|
+
options.default_task_start_to_close_timeout.should == "30"
|
92
|
+
options.default_task_heartbeat_timeout.should == "5"
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should remain the same when a non default value is set" do
|
96
|
+
options = AWS::Flow::ActivityOptions.new
|
97
|
+
options.schedule_to_start_timeout = 20
|
98
|
+
options.schedule_to_close_timeout = 50
|
99
|
+
options.start_to_close_timeout = 30
|
100
|
+
options.heartbeat_timeout = 5
|
101
|
+
|
102
|
+
options.default_task_schedule_to_start_timeout.should == "NONE"
|
103
|
+
options.default_task_schedule_to_close_timeout.should == "NONE"
|
104
|
+
options.default_task_start_to_close_timeout.should == "NONE"
|
105
|
+
options.default_task_heartbeat_timeout.should == "NONE"
|
106
|
+
end
|
107
|
+
|
108
|
+
it "should not override non default values when non default values are set" do
|
109
|
+
options = AWS::Flow::ActivityOptions.new
|
110
|
+
options.schedule_to_start_timeout = 20
|
111
|
+
options.schedule_to_close_timeout = 50
|
112
|
+
options.start_to_close_timeout = 30
|
113
|
+
options.heartbeat_timeout = 5
|
114
|
+
|
115
|
+
options.schedule_to_start_timeout.should == "20"
|
116
|
+
options.schedule_to_close_timeout.should == "50"
|
117
|
+
options.start_to_close_timeout.should == "30"
|
118
|
+
options.heartbeat_timeout.should == "5"
|
119
|
+
end
|
120
|
+
|
121
|
+
|
122
|
+
end
|
123
|
+
|
124
|
+
context "#default_keys" do
|
125
|
+
it "should return the correct set of default keys" do
|
126
|
+
AWS::Flow::ActivityOptions.new.default_keys.should == [
|
127
|
+
:default_task_heartbeat_timeout,
|
128
|
+
:default_task_schedule_to_close_timeout,
|
129
|
+
:default_task_schedule_to_start_timeout,
|
130
|
+
:default_task_start_to_close_timeout,
|
131
|
+
:default_task_list
|
132
|
+
]
|
133
|
+
end
|
134
|
+
|
135
|
+
end
|
136
|
+
context "#make_runtime_key" do
|
137
|
+
it "should correctly convert default keys to runtime keys" do
|
138
|
+
AWS::Flow::ActivityOptions.new.make_runtime_key(
|
139
|
+
:default_task_foo
|
140
|
+
).should == :foo
|
141
|
+
end
|
142
|
+
|
143
|
+
it "should do nothing if an option without leading default_ is passed in" do
|
144
|
+
AWS::Flow::ActivityOptions.new.make_runtime_key(:foo).should == :foo
|
145
|
+
end
|
146
|
+
|
147
|
+
it "should handle the special case of default_task_list properly" do
|
148
|
+
AWS::Flow::ActivityOptions.new.make_runtime_key(
|
149
|
+
:default_task_list
|
150
|
+
).should == :task_list
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
describe AWS::Flow::WorkflowOptions do
|
156
|
+
context "#defaults" do
|
157
|
+
it "should be initialized correctly" do
|
158
|
+
options = AWS::Flow::WorkflowOptions.new
|
159
|
+
options.default_task_start_to_close_timeout.should == "30"
|
160
|
+
options.default_child_policy.should == "TERMINATE"
|
161
|
+
options.tag_list.should == []
|
162
|
+
options.data_converter.should ==
|
163
|
+
AWS::Flow::FlowConstants.default_data_converter
|
164
|
+
end
|
165
|
+
|
166
|
+
it "should change to the value passed in" do
|
167
|
+
options = AWS::Flow::WorkflowOptions.new({
|
168
|
+
default_task_start_to_close_timeout: 20,
|
169
|
+
default_execution_start_to_close_timeout: 120,
|
170
|
+
default_child_policy: "ABANDON",
|
171
|
+
})
|
172
|
+
options.default_task_start_to_close_timeout.should == "20"
|
173
|
+
options.default_execution_start_to_close_timeout.should == "120"
|
174
|
+
options.default_child_policy.should == "ABANDON"
|
175
|
+
end
|
176
|
+
|
177
|
+
it "should remain the same when a non default value is set" do
|
178
|
+
options = AWS::Flow::WorkflowOptions.new
|
179
|
+
options.task_start_to_close_timeout = 20
|
180
|
+
options.execution_start_to_close_timeout = 120
|
181
|
+
options.child_policy = "ABANDON"
|
182
|
+
|
183
|
+
options.default_task_start_to_close_timeout.should == "30"
|
184
|
+
options.default_execution_start_to_close_timeout.nil?.should == true
|
185
|
+
options.default_child_policy.should == "TERMINATE"
|
186
|
+
end
|
187
|
+
|
188
|
+
it "should not override non default values when non default values are set" do
|
189
|
+
options = AWS::Flow::WorkflowOptions.new
|
190
|
+
options.task_start_to_close_timeout = 20
|
191
|
+
options.execution_start_to_close_timeout = 120
|
192
|
+
options.child_policy = "ABANDON"
|
193
|
+
|
194
|
+
options.task_start_to_close_timeout.should == "20"
|
195
|
+
options.execution_start_to_close_timeout.should == "120"
|
196
|
+
options.child_policy.should == "ABANDON"
|
197
|
+
end
|
198
|
+
|
199
|
+
end
|
200
|
+
|
201
|
+
context "#default_keys" do
|
202
|
+
it "should return the correct set of default keys" do
|
203
|
+
AWS::Flow::WorkflowOptions.new.default_keys.should == [
|
204
|
+
:default_task_start_to_close_timeout,
|
205
|
+
:default_execution_start_to_close_timeout,
|
206
|
+
:default_task_list,
|
207
|
+
:default_child_policy
|
208
|
+
]
|
209
|
+
end
|
210
|
+
|
211
|
+
end
|
212
|
+
context "#make_runtime_key" do
|
213
|
+
it "should correctly convert default keys to runtime keys" do
|
214
|
+
AWS::Flow::WorkflowOptions.new.make_runtime_key(
|
215
|
+
:default_foo
|
216
|
+
).should == :foo
|
217
|
+
end
|
218
|
+
|
219
|
+
it "should do nothing if an option without leading default_ is passed in" do
|
220
|
+
AWS::Flow::WorkflowOptions.new.make_runtime_key(:foo).should == :foo
|
221
|
+
end
|
222
|
+
|
223
|
+
it "should handle the special case of default_task_list properly" do
|
224
|
+
AWS::Flow::WorkflowOptions.new.make_runtime_key(
|
225
|
+
:default_task_list
|
226
|
+
).should == :task_list
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
end
|
231
|
+
|
232
|
+
describe AWS::Flow::WorkflowDefaults do
|
233
|
+
context "#default_task_start_to_close_timeout" do
|
234
|
+
it "should return a value of 30" do
|
235
|
+
AWS::Flow::WorkflowDefaults.new.default_task_start_to_close_timeout
|
236
|
+
.should == 30
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
context "#default_child_policy" do
|
241
|
+
it "should return TERMINATE" do
|
242
|
+
AWS::Flow::WorkflowDefaults.new.default_child_policy.should == "TERMINATE"
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
context "#tag_list" do
|
247
|
+
it "should return an empty array" do
|
248
|
+
AWS::Flow::WorkflowDefaults.new.tag_list.should == []
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
context "#data_converter" do
|
253
|
+
it "should return the default data converter" do
|
254
|
+
AWS::Flow::WorkflowDefaults.new.data_converter
|
255
|
+
.should == AWS::Flow::FlowConstants.default_data_converter
|
256
|
+
end
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
describe AWS::Flow::ActivityDefaults do
|
261
|
+
context "#default_task_schedule_to_start_timeout" do
|
262
|
+
it "should return Float::INFINITY" do
|
263
|
+
AWS::Flow::ActivityDefaults.new.default_task_schedule_to_start_timeout
|
264
|
+
.should == Float::INFINITY
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
context "#default_task_schedule_to_close_timeout" do
|
269
|
+
it "should return Float::INFINITY" do
|
270
|
+
AWS::Flow::ActivityDefaults.new.default_task_schedule_to_close_timeout
|
271
|
+
.should == Float::INFINITY
|
272
|
+
end
|
273
|
+
end
|
274
|
+
context "#default_task_start_to_close_timeout" do
|
275
|
+
it "should return Float::INFINITY" do
|
276
|
+
AWS::Flow::ActivityDefaults.new.default_task_start_to_close_timeout
|
277
|
+
.should == Float::INFINITY
|
278
|
+
end
|
279
|
+
end
|
280
|
+
context "#default_task_heartbeat_timeout" do
|
281
|
+
it "should return Float::INFINITY" do
|
282
|
+
AWS::Flow::ActivityDefaults.new.default_task_heartbeat_timeout
|
283
|
+
.should == Float::INFINITY
|
284
|
+
end
|
285
|
+
end
|
286
|
+
context "#data_converter" do
|
287
|
+
it "should return the default data converter" do
|
288
|
+
AWS::Flow::ActivityDefaults.new.data_converter
|
289
|
+
.should == AWS::Flow::FlowConstants.default_data_converter
|
290
|
+
end
|
291
|
+
end
|
292
|
+
end
|
293
|
+
|