aws-flow 3.0.0 → 3.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -13
- data/lib/aws/decider/data_converter.rb +1 -1
- data/lib/aws/decider/state_machines.rb +2 -0
- data/lib/aws/decider/task_poller.rb +1 -1
- data/lib/aws/decider/version.rb +1 -1
- data/lib/aws/decider/worker.rb +2 -2
- data/lib/aws/utils.rb +1 -1
- data/spec/aws/decider/unit/child_cancellation_spec.rb +94 -0
- data/spec/aws/decider/unit/child_startfailed_spec.rb +93 -0
- data/spec/aws/decider/unit/data_converter_spec.rb +3 -1
- data/spec/aws/decider/unit/state_machines_spec.rb +61 -0
- data/spec/aws/decider/unit/task_poller_spec.rb +50 -0
- data/spec/aws/decider/unit/worker_spec.rb +81 -0
- data/spec/aws/flow/unit/external_condition_variable_spec.rb +19 -4
- data/spec/aws/flow/unit/future_spec.rb +7 -3
- data/spec/aws/templates/unit/result_spec.rb +1 -0
- data/spec/aws/utils/unit/utils_spec.rb +11 -0
- data/spec/spec_helper.rb +9 -0
- metadata +18 -13
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
ZWJhNjZjMDgzNTE0NDgwYzI1NjQ4ZDVmNjA2MjM5YzYzODI2MzA5ZQ==
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 19330ec67715312fabd0fda12e2825f28b7f5cb3
|
4
|
+
data.tar.gz: 8bdb38e2cd661d142f362a279812ab5432112e4a
|
7
5
|
SHA512:
|
8
|
-
metadata.gz:
|
9
|
-
|
10
|
-
ZmM2MjE0NGNhODhkOWNhYjRkMDM4OGNkMzU5YzU4ZjUzYmE3NmU3NDYxMDRi
|
11
|
-
YTFiYjJmOTZmODUxNzk2NDJjYjczOGNhMGY1NTU2NjkxZDhhYjQ=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
MTAxY2Y4ZWMwYmIyYThiOGE5MGNmODc5NTE3MTM3NDkxYTYxYTNkYTU4MmM1
|
14
|
-
NmI2Njk4NzlhMmI0MTlhZTUzODIzOTZkNTRkMjRlODFhY2FmMDlhZjQ2ZDFm
|
15
|
-
Zjg1NTE3ZWU0NGE4MmNjYmQyNjhhYTZlMDU0MmI3YjBhZWM4YzQ=
|
6
|
+
metadata.gz: b2664a24f3841908254d360e7a48f4a77a755fde01cbfa45307d6ed31bcdaf87d60fd75963961aa584ffad5d8af3c7e8dea309a0ea27ba9f772c3e4bb0c3d9ff
|
7
|
+
data.tar.gz: b6c576bc8b5df2f592cf1bf8bada8371e3ea6186dfc19974825bc80d1f75b1156283700fcb45d6d1b857629048966e204a5a74c1690dd3340103b060f8c53055
|
@@ -41,7 +41,7 @@ module AWS
|
|
41
41
|
output = YAML.load source
|
42
42
|
if output.is_a? Exception
|
43
43
|
documents = YAML.load_stream(source)
|
44
|
-
if YAML::ENGINE.yamler == 'syck'
|
44
|
+
if YAML.const_defined?(:ENGINE) && YAML::ENGINE.yamler == 'syck'
|
45
45
|
documents = documents.documents
|
46
46
|
end
|
47
47
|
backtrace = documents.find {|x| ! x.is_a? Exception}
|
@@ -142,6 +142,7 @@ module AWS
|
|
142
142
|
[:decision_sent, :handle_initiation_failed_event, :completed],
|
143
143
|
[:initiated, :cancel, :cancelled_after_initiated],
|
144
144
|
[:initiated, :handle_completion_event, :completed],
|
145
|
+
[:initiated, :handle_initiation_failed_event, :completed],
|
145
146
|
[:started, :handle_decision_task_started_event, :started],
|
146
147
|
]
|
147
148
|
self_transitions(:handle_decision_task_started_event)
|
@@ -367,6 +368,7 @@ module AWS
|
|
367
368
|
[:cancellation_decision_sent, :handle_cancellation_failure_event, :started],
|
368
369
|
[:started, :cancel, :cancelled_after_started],
|
369
370
|
[:started, :handle_completion_event, :completed],
|
371
|
+
[:started, :handle_cancellation_event, :completed],
|
370
372
|
[:cancelled_after_started, :handle_completion_event, :completed],
|
371
373
|
]
|
372
374
|
end
|
@@ -290,7 +290,7 @@ module AWS
|
|
290
290
|
# possibly because of large custom exceptions we should fail the
|
291
291
|
# activity task with some minimal details
|
292
292
|
respond_activity_task_failed_with_retry(
|
293
|
-
|
293
|
+
task_token,
|
294
294
|
Utilities.validation_error_string("Activity"),
|
295
295
|
"AWS::SimpleWorkflow::Errors::ValidationException"
|
296
296
|
)
|
data/lib/aws/decider/version.rb
CHANGED
data/lib/aws/decider/worker.rb
CHANGED
@@ -72,10 +72,10 @@ module AWS
|
|
72
72
|
|
73
73
|
module GenericTypeModule
|
74
74
|
def hash
|
75
|
-
[@name
|
75
|
+
[@name, @version].hash
|
76
76
|
end
|
77
77
|
def eql?(other)
|
78
|
-
@name.
|
78
|
+
@name.eql?(other.name) && @version.eql?(other.version)
|
79
79
|
end
|
80
80
|
end
|
81
81
|
|
data/lib/aws/utils.rb
CHANGED
@@ -0,0 +1,94 @@
|
|
1
|
+
require_relative 'setup'
|
2
|
+
|
3
|
+
def get_child_cancellation_history_array
|
4
|
+
[
|
5
|
+
"WorkflowExecutionStarted",
|
6
|
+
"DecisionTaskScheduled",
|
7
|
+
"DecisionTaskStarted",
|
8
|
+
]
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "TestChildCancellationNotInitiatedFromParent" do
|
12
|
+
|
13
|
+
context "ChildCancellation" do
|
14
|
+
# The following tests for swf-issue-2031
|
15
|
+
before(:all) do
|
16
|
+
class ParentWorkflow
|
17
|
+
extend AWS::Flow::Workflows
|
18
|
+
workflow :parent, :child do
|
19
|
+
{
|
20
|
+
version: "1.0",
|
21
|
+
task_list: "default",
|
22
|
+
}
|
23
|
+
end
|
24
|
+
|
25
|
+
def parent
|
26
|
+
$client.child { {workflow_id: "child_workflow_test"}}
|
27
|
+
end
|
28
|
+
|
29
|
+
def child; end
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
it "tests part 1 - child gets scheduled in the first decision" do
|
35
|
+
|
36
|
+
class SynchronousWorkflowTaskPoller < WorkflowTaskPoller
|
37
|
+
def get_decision_task
|
38
|
+
TestHistoryWrapper.new($type, FakeWorkflowExecution.new(nil, nil), FakeEvents.new(get_child_cancellation_history_array))
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
$type = FakeWorkflowType.new(nil, "ParentWorkflow.parent", "1.0")
|
43
|
+
|
44
|
+
domain = FakeDomain.new($type)
|
45
|
+
swf_client = FakeServiceClient.new
|
46
|
+
|
47
|
+
task_list = "default"
|
48
|
+
|
49
|
+
$client = AWS::Flow::workflow_client(swf_client, domain) { { from_class: "ParentWorkflow" } }
|
50
|
+
|
51
|
+
$client.start_execution
|
52
|
+
|
53
|
+
worker = SynchronousWorkflowWorker.new(swf_client, domain, task_list, ParentWorkflow)
|
54
|
+
|
55
|
+
worker.start
|
56
|
+
|
57
|
+
swf_client.trace.first[:decisions].first[:decision_type].should == "StartChildWorkflowExecution"
|
58
|
+
end
|
59
|
+
|
60
|
+
it "tests part 2 - the workflow fails because child workflow is cancelled" do
|
61
|
+
|
62
|
+
class SynchronousWorkflowTaskPoller < WorkflowTaskPoller
|
63
|
+
def get_decision_task
|
64
|
+
TestHistoryWrapper.new($type, FakeWorkflowExecution.new(nil, nil),
|
65
|
+
FakeEvents.new(get_child_cancellation_history_array().push(*[
|
66
|
+
"DecisionTaskCompleted",
|
67
|
+
["StartChildWorkflowExecutionInitiated", {:workflow_id => "child_workflow_test"}],
|
68
|
+
["ChildWorkflowExecutionStarted", {:workflow_execution => FakeWorkflowExecution.new("1", "child_workflow_test"), :workflow_id => "child_workflow_test"}],
|
69
|
+
["ChildWorkflowExecutionCanceled",{:workflow_execution => FakeWorkflowExecution.new("1", "child_workflow_test")}],
|
70
|
+
"DecisionTaskScheduled",
|
71
|
+
"DecisionTaskStarted",
|
72
|
+
])))
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
$type = FakeWorkflowType.new(nil, "ParentWorkflow.parent", "1.0")
|
77
|
+
|
78
|
+
domain = FakeDomain.new($type)
|
79
|
+
swf_client = FakeServiceClient.new
|
80
|
+
|
81
|
+
task_list = "default"
|
82
|
+
|
83
|
+
$client = AWS::Flow::workflow_client(swf_client, domain) { { from_class: "ParentWorkflow" } }
|
84
|
+
|
85
|
+
$client.start_execution
|
86
|
+
|
87
|
+
worker = SynchronousWorkflowWorker.new(swf_client, domain, task_list, ParentWorkflow)
|
88
|
+
|
89
|
+
worker.start
|
90
|
+
|
91
|
+
swf_client.trace.first[:decisions].first[:decision_type].should == "FailWorkflowExecution"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
require_relative 'setup'
|
2
|
+
|
3
|
+
def get_start_child_failed_history_array
|
4
|
+
[
|
5
|
+
"WorkflowExecutionStarted",
|
6
|
+
"DecisionTaskScheduled",
|
7
|
+
"DecisionTaskStarted",
|
8
|
+
]
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "TestStartChildFailedAfterStartChildInitiated" do
|
12
|
+
|
13
|
+
context "StartChildFailedAfterStartChildInitiated" do
|
14
|
+
# The following tests for swf-issue-2029
|
15
|
+
before(:all) do
|
16
|
+
class ParentWorkflow
|
17
|
+
extend AWS::Flow::Workflows
|
18
|
+
workflow :parent, :child do
|
19
|
+
{
|
20
|
+
version: "1.0",
|
21
|
+
task_list: "default",
|
22
|
+
}
|
23
|
+
end
|
24
|
+
|
25
|
+
def parent
|
26
|
+
$client.send_async(:child) { {workflow_id: "child_workflow_test"}}
|
27
|
+
end
|
28
|
+
|
29
|
+
def child; end
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
it "tests part 1 - child gets scheduled in the first decision" do
|
35
|
+
|
36
|
+
class SynchronousWorkflowTaskPoller < WorkflowTaskPoller
|
37
|
+
def get_decision_task
|
38
|
+
TestHistoryWrapper.new($type, FakeWorkflowExecution.new(nil, nil), FakeEvents.new(get_start_child_failed_history_array))
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
$type = FakeWorkflowType.new(nil, "ParentWorkflow.parent", "1.0")
|
43
|
+
|
44
|
+
domain = FakeDomain.new($type)
|
45
|
+
swf_client = FakeServiceClient.new
|
46
|
+
|
47
|
+
task_list = "default"
|
48
|
+
|
49
|
+
$client = AWS::Flow::workflow_client(swf_client, domain) { { from_class: "ParentWorkflow" } }
|
50
|
+
|
51
|
+
$client.start_execution
|
52
|
+
|
53
|
+
worker = SynchronousWorkflowWorker.new(swf_client, domain, task_list, ParentWorkflow)
|
54
|
+
|
55
|
+
worker.start
|
56
|
+
|
57
|
+
swf_client.trace.first[:decisions].first[:decision_type].should == "StartChildWorkflowExecution"
|
58
|
+
end
|
59
|
+
|
60
|
+
it "tests part 2 - the workflow fails because start child workflow is failed" do
|
61
|
+
|
62
|
+
class SynchronousWorkflowTaskPoller < WorkflowTaskPoller
|
63
|
+
def get_decision_task
|
64
|
+
TestHistoryWrapper.new($type, FakeWorkflowExecution.new(nil, nil),
|
65
|
+
FakeEvents.new(get_start_child_failed_history_array().push(*[
|
66
|
+
"DecisionTaskCompleted",
|
67
|
+
["StartChildWorkflowExecutionInitiated", {:workflow_id => "child_workflow_test"}],
|
68
|
+
["StartChildWorkflowExecutionFailed", {:workflow_type => { name: "ParentWorkflow.child", version: "1.0" }, :workflow_execution => FakeWorkflowExecution.new("1", "child_workflow_test"), :workflow_id => "child_workflow_test", cause: "WORKFLOW_ALREADY_RUNNING" }],
|
69
|
+
"DecisionTaskScheduled",
|
70
|
+
"DecisionTaskStarted",
|
71
|
+
])))
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
$type = FakeWorkflowType.new(nil, "ParentWorkflow.parent", "1.0")
|
76
|
+
|
77
|
+
domain = FakeDomain.new($type)
|
78
|
+
swf_client = FakeServiceClient.new
|
79
|
+
|
80
|
+
task_list = "default"
|
81
|
+
|
82
|
+
$client = AWS::Flow::workflow_client(swf_client, domain) { { from_class: "ParentWorkflow" } }
|
83
|
+
|
84
|
+
$client.start_execution
|
85
|
+
|
86
|
+
worker = SynchronousWorkflowWorker.new(swf_client, domain, task_list, ParentWorkflow)
|
87
|
+
|
88
|
+
worker.start
|
89
|
+
|
90
|
+
swf_client.trace.first[:decisions].first[:decision_type].should == "FailWorkflowExecution"
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -7,7 +7,9 @@ describe YAMLDataConverter do
|
|
7
7
|
%w{syck psych}.each do |engine|
|
8
8
|
describe "ensures that x == load(dump(x)) is true using #{engine}" do
|
9
9
|
before :all do
|
10
|
-
YAML
|
10
|
+
if YAML.const_defined?(:ENGINE)
|
11
|
+
YAML::ENGINE.yamler = engine
|
12
|
+
end
|
11
13
|
end
|
12
14
|
|
13
15
|
{
|
@@ -0,0 +1,61 @@
|
|
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 "spec_helper"
|
17
|
+
|
18
|
+
describe ChildWorkflowDecisionStateMachine do
|
19
|
+
before do
|
20
|
+
@this_machine = ChildWorkflowDecisionStateMachine.new('id1',nil)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "ensures to handle child cancellation that wasn't initiated from the parent" do
|
24
|
+
@this_machine.current_state = :started
|
25
|
+
@this_machine.consume(:handle_cancellation_event)
|
26
|
+
@this_machine.current_state.should == :completed
|
27
|
+
end
|
28
|
+
|
29
|
+
it "ensures to handle StartChildFailed after StartChildInitiated" do
|
30
|
+
@this_machine.current_state = :initiated
|
31
|
+
@this_machine.consume(:handle_initiation_failed_event)
|
32
|
+
@this_machine.current_state.should == :completed
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
describe ActivityDecisionStateMachine do
|
38
|
+
before do
|
39
|
+
@this_machine = ActivityDecisionStateMachine.new('id2',nil)
|
40
|
+
end
|
41
|
+
|
42
|
+
it "ensures to handle ScheduleActivity failed after ScheduleActivity" do
|
43
|
+
@this_machine.current_state = :initiated
|
44
|
+
@this_machine.consume(:handle_initiation_failed_event)
|
45
|
+
@this_machine.current_state.should == :completed
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
describe TimerDecisionStateMachine do
|
51
|
+
before do
|
52
|
+
@this_machine = TimerDecisionStateMachine.new('id3',nil)
|
53
|
+
end
|
54
|
+
|
55
|
+
it "ensures to handle StartTimer failed after StartTimer" do
|
56
|
+
@this_machine.current_state = :initiated
|
57
|
+
@this_machine.consume(:handle_initiation_failed_event)
|
58
|
+
@this_machine.current_state.should == :completed
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require_relative 'setup'
|
2
|
+
|
3
|
+
describe ActivityTaskPoller do
|
4
|
+
|
5
|
+
context "#respond_activity_task_failed" do
|
6
|
+
|
7
|
+
# This test checks a fix for Github issue #90
|
8
|
+
it "correctly calls #respond_activity_task_failed_with_retry on failures" do
|
9
|
+
|
10
|
+
# Set up test mock
|
11
|
+
swf = double
|
12
|
+
allow(swf).to receive(:config).and_return(swf)
|
13
|
+
allow(swf).to receive(:to_h).and_return({})
|
14
|
+
|
15
|
+
# Instantiate the poller
|
16
|
+
poller = ActivityTaskPoller.new(swf, nil, nil, nil, nil, nil)
|
17
|
+
|
18
|
+
# Set up mock logger to avoid test failures
|
19
|
+
logger = double
|
20
|
+
allow(logger).to receive(:debug)
|
21
|
+
allow(logger).to receive(:error)
|
22
|
+
poller.instance_variable_set(:@logger, logger)
|
23
|
+
|
24
|
+
# Ensure @service.respond_activity_task_failed method is called. Raise
|
25
|
+
# ValidationException to trigger the correct handler
|
26
|
+
allow(swf).to receive(:respond_activity_task_failed).with(
|
27
|
+
task_token: "task_token",
|
28
|
+
reason: "reason",
|
29
|
+
details: "details"
|
30
|
+
).and_raise(
|
31
|
+
AWS::SimpleWorkflow::Errors::ValidationException,
|
32
|
+
"failed to satisfy constraint: Member must have length less than or equal to"
|
33
|
+
)
|
34
|
+
|
35
|
+
# Final check - ensure respond_activity_task_failed_with_retry is called
|
36
|
+
# with the correct task_token string
|
37
|
+
expect(poller).to receive(:respond_activity_task_failed_with_retry).with(
|
38
|
+
"task_token",
|
39
|
+
Utilities.validation_error_string("Activity"),
|
40
|
+
AWS::SimpleWorkflow::Errors::ValidationException.to_s
|
41
|
+
)
|
42
|
+
|
43
|
+
# Start the test
|
44
|
+
poller.respond_activity_task_failed("task_token", "reason", "details")
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
@@ -371,3 +371,84 @@ describe ActivityWorker do
|
|
371
371
|
|
372
372
|
end
|
373
373
|
|
374
|
+
describe GenericType do
|
375
|
+
|
376
|
+
let(:type) { GenericType.new("name", "version", {}) }
|
377
|
+
let(:another_type) { GenericType.new("name", "version", {}) }
|
378
|
+
|
379
|
+
context "#hash" do
|
380
|
+
|
381
|
+
it "produces correct hash value" do
|
382
|
+
type.hash.should == another_type.hash
|
383
|
+
end
|
384
|
+
|
385
|
+
end
|
386
|
+
|
387
|
+
context "#eql?" do
|
388
|
+
|
389
|
+
it "correctly checks equality" do
|
390
|
+
type.should eql(another_type)
|
391
|
+
end
|
392
|
+
|
393
|
+
end
|
394
|
+
|
395
|
+
it "ensures the type can be retrieved from a hash" do
|
396
|
+
hash = { type => "foo_type" }
|
397
|
+
hash[another_type].should == "foo_type"
|
398
|
+
end
|
399
|
+
|
400
|
+
[:ActivityType, :WorkflowType].each do |type|
|
401
|
+
describe "#{type}" do
|
402
|
+
let(:swf_klass) { AWS::SimpleWorkflow.const_get(type) }
|
403
|
+
let(:flow_klass) { AWS::Flow::const_get(type) }
|
404
|
+
|
405
|
+
describe "with same name and version" do
|
406
|
+
let(:swf_type) { swf_klass.new("domain", "name", "version") }
|
407
|
+
let(:flow_type) { flow_klass.new("name", "version") }
|
408
|
+
|
409
|
+
context "#hash" do
|
410
|
+
it "produces same hash value" do
|
411
|
+
swf_type.hash.should == flow_type.hash
|
412
|
+
end
|
413
|
+
end
|
414
|
+
|
415
|
+
context "#eql?" do
|
416
|
+
it "ensures the two types are logically equivalent" do
|
417
|
+
swf_type.should eql(flow_type)
|
418
|
+
end
|
419
|
+
end
|
420
|
+
|
421
|
+
it "can be looked up in a hash" do
|
422
|
+
hash = { flow_type => "flow_type" }
|
423
|
+
hash[swf_type].should == "flow_type"
|
424
|
+
end
|
425
|
+
|
426
|
+
end
|
427
|
+
|
428
|
+
describe "with different name and version" do
|
429
|
+
let(:swf_type) { swf_klass.new("domain", "name", "version") }
|
430
|
+
let(:flow_type) { flow_klass.new("diff_name", "diff_version") }
|
431
|
+
|
432
|
+
context "#hash" do
|
433
|
+
it "produces different hash value" do
|
434
|
+
swf_type.hash.should_not == flow_type.hash
|
435
|
+
end
|
436
|
+
end
|
437
|
+
|
438
|
+
context "#eql?" do
|
439
|
+
it "ensures the two types are not logically equivalent" do
|
440
|
+
swf_type.should_not eql(flow_type)
|
441
|
+
end
|
442
|
+
end
|
443
|
+
|
444
|
+
it "cannot be looked up in a hash" do
|
445
|
+
hash = { flow_type => "flow_type" }
|
446
|
+
hash[swf_type].should be_nil
|
447
|
+
end
|
448
|
+
|
449
|
+
end
|
450
|
+
end
|
451
|
+
end
|
452
|
+
|
453
|
+
end
|
454
|
+
|
@@ -20,39 +20,54 @@ describe ExternalConditionVariable do
|
|
20
20
|
|
21
21
|
it "blocks a thread and wakes it up on signal" do
|
22
22
|
t = Thread.new { condition.wait }
|
23
|
-
|
23
|
+
Test::Unit::wait("run", 1, t)
|
24
24
|
t.status.should == "sleep"
|
25
25
|
condition.signal
|
26
|
+
Test::Unit::wait("run", 1, t)
|
26
27
|
t.status.should == false
|
27
28
|
end
|
28
29
|
|
29
30
|
it "blocks multiple threads and wakes one up on signal" do
|
30
31
|
t1 = Thread.new { condition.wait }
|
31
32
|
t2 = Thread.new { condition.wait }
|
32
|
-
|
33
|
+
|
34
|
+
Test::Unit::wait("run", 1, t1, t2)
|
33
35
|
t1.status.should == "sleep"
|
34
36
|
t2.status.should == "sleep"
|
35
37
|
condition.signal
|
38
|
+
|
39
|
+
Test::Unit::wait("run", 1, t1, t2)
|
36
40
|
(t1.status == false && t2.status == false).should == false
|
37
41
|
condition.signal
|
42
|
+
|
43
|
+
Test::Unit::wait("run", 1, t1, t2)
|
38
44
|
(t1.status == false && t2.status == false).should == true
|
39
45
|
end
|
40
46
|
|
41
47
|
it "blocks a thread and wakes it up on broadcast" do
|
42
48
|
t = Thread.new { condition.wait }
|
43
|
-
|
49
|
+
|
50
|
+
Test::Unit::wait("run", 1, t)
|
51
|
+
sleep 1 if t.status == "run"
|
44
52
|
t.status.should == "sleep"
|
45
53
|
condition.broadcast
|
54
|
+
|
55
|
+
Test::Unit::wait("run", 1, t)
|
56
|
+
sleep 1 if t.status == "run"
|
46
57
|
t.status.should == false
|
47
58
|
end
|
48
59
|
|
49
60
|
it "blocks multiple threads and wakes them up on broadcast" do
|
50
61
|
t1 = Thread.new { condition.wait }
|
51
62
|
t2 = Thread.new { condition.wait }
|
52
|
-
|
63
|
+
|
64
|
+
Test::Unit::wait("run", 1, t1, t2)
|
53
65
|
t1.status.should == "sleep"
|
54
66
|
t2.status.should == "sleep"
|
55
67
|
condition.broadcast
|
68
|
+
|
69
|
+
Test::Unit::wait("run", 1, t1, t2)
|
70
|
+
sleep 1 if t1.status == "run" || t2.status == "run"
|
56
71
|
(t1.status == false && t2.status == false).should == true
|
57
72
|
end
|
58
73
|
|
@@ -233,9 +233,10 @@ describe ExternalFuture do
|
|
233
233
|
future = ExternalFuture.new
|
234
234
|
|
235
235
|
t1 = Thread.new { future.get }
|
236
|
-
|
236
|
+
Test::Unit::wait("run", 1, t1)
|
237
237
|
t1.status.should == "sleep"
|
238
238
|
future.set
|
239
|
+
Test::Unit::wait("run", 1, t1)
|
239
240
|
t1.status.should == false
|
240
241
|
end
|
241
242
|
|
@@ -253,7 +254,7 @@ describe ExternalFuture do
|
|
253
254
|
t2 = Thread.new { future.get }
|
254
255
|
t3 = Thread.new { future.get }
|
255
256
|
|
256
|
-
|
257
|
+
Test::Unit::wait("run", 1, t1, t2, t3)
|
257
258
|
|
258
259
|
t1.status.should == "sleep"
|
259
260
|
t2.status.should == "sleep"
|
@@ -261,6 +262,8 @@ describe ExternalFuture do
|
|
261
262
|
|
262
263
|
future.set
|
263
264
|
|
265
|
+
Test::Unit::wait("run", 1, t1, t2, t3)
|
266
|
+
|
264
267
|
t1.status.should == false
|
265
268
|
t2.status.should == false
|
266
269
|
t3.status.should == false
|
@@ -283,9 +286,10 @@ describe ExternalFuture do
|
|
283
286
|
it "nil timeout will block until the future is set" do
|
284
287
|
future = ExternalFuture.new
|
285
288
|
t = Thread.new { future.get(nil) }
|
286
|
-
|
289
|
+
Test::Unit::wait("run", 1, t)
|
287
290
|
t.status.should == "sleep"
|
288
291
|
future.set
|
292
|
+
Test::Unit::wait("run", 1, t)
|
289
293
|
t.status.should == false
|
290
294
|
end
|
291
295
|
|
@@ -39,6 +39,7 @@ describe AWS::Flow::Templates::ResultWorker do
|
|
39
39
|
sleep 1
|
40
40
|
Thread.list.count.should == 2
|
41
41
|
AWS::Flow::Templates::ResultWorker.stop
|
42
|
+
sleep 1 if Thread.list.count == 2
|
42
43
|
Thread.list.count.should == 1
|
43
44
|
AWS::Flow::Templates::ResultWorker.instance_variable_get("@executor").should be_nil
|
44
45
|
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe AWS::Flow::Utils do
|
4
|
+
|
5
|
+
# This tests a fix for Github issue #89
|
6
|
+
it "aws-flow-utils writes files in binary mode" do
|
7
|
+
expect(File).to receive(:open).with("name", "wb")
|
8
|
+
AWS::Flow::Utils::InitConfig.write_to_file("name", "string")
|
9
|
+
end
|
10
|
+
|
11
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -16,6 +16,7 @@
|
|
16
16
|
require 'bundler/setup'
|
17
17
|
require 'aws/flow'
|
18
18
|
require 'aws/decider'
|
19
|
+
require 'aws/utils'
|
19
20
|
require 'replayer'
|
20
21
|
require 'runner'
|
21
22
|
|
@@ -125,11 +126,19 @@ module Test
|
|
125
126
|
|
126
127
|
module Unit
|
127
128
|
|
129
|
+
def self.wait(status, timeout, *t)
|
130
|
+
until t.select { |x| x.status == status }.empty? && timeout
|
131
|
+
sleep 1
|
132
|
+
timeout -= 1
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
128
136
|
class FakeConfig
|
129
137
|
def to_h
|
130
138
|
|
131
139
|
end
|
132
140
|
end
|
141
|
+
|
133
142
|
class FakeServiceClient
|
134
143
|
attr_accessor :trace
|
135
144
|
|
metadata
CHANGED
@@ -1,53 +1,53 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: aws-flow
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Steger, Paritosh Mohan, Jacques Thomas
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-04-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: aws-sdk-v1
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - ~>
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '1'
|
20
|
-
- -
|
20
|
+
- - ">="
|
21
21
|
- !ruby/object:Gem::Version
|
22
22
|
version: 1.60.2
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
26
26
|
requirements:
|
27
|
-
- - ~>
|
27
|
+
- - "~>"
|
28
28
|
- !ruby/object:Gem::Version
|
29
29
|
version: '1'
|
30
|
-
- -
|
30
|
+
- - ">="
|
31
31
|
- !ruby/object:Gem::Version
|
32
32
|
version: 1.60.2
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
34
|
name: lru_redux
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
36
36
|
requirements:
|
37
|
-
- - ~>
|
37
|
+
- - "~>"
|
38
38
|
- !ruby/object:Gem::Version
|
39
39
|
version: '0'
|
40
|
-
- -
|
40
|
+
- - ">="
|
41
41
|
- !ruby/object:Gem::Version
|
42
42
|
version: 0.8.1
|
43
43
|
type: :runtime
|
44
44
|
prerelease: false
|
45
45
|
version_requirements: !ruby/object:Gem::Requirement
|
46
46
|
requirements:
|
47
|
-
- - ~>
|
47
|
+
- - "~>"
|
48
48
|
- !ruby/object:Gem::Version
|
49
49
|
version: '0'
|
50
|
-
- -
|
50
|
+
- - ">="
|
51
51
|
- !ruby/object:Gem::Version
|
52
52
|
version: 0.8.1
|
53
53
|
description: Library to provide the AWS Flow Framework for Ruby
|
@@ -120,6 +120,8 @@ files:
|
|
120
120
|
- spec/aws/decider/integration/starter_spec.rb
|
121
121
|
- spec/aws/decider/unit/activity_spec.rb
|
122
122
|
- spec/aws/decider/unit/async_retrying_executor_spec.rb
|
123
|
+
- spec/aws/decider/unit/child_cancellation_spec.rb
|
124
|
+
- spec/aws/decider/unit/child_startfailed_spec.rb
|
123
125
|
- spec/aws/decider/unit/data_converter_spec.rb
|
124
126
|
- spec/aws/decider/unit/decider_spec.rb
|
125
127
|
- spec/aws/decider/unit/executor_spec.rb
|
@@ -130,6 +132,8 @@ files:
|
|
130
132
|
- spec/aws/decider/unit/rubyflow.rb
|
131
133
|
- spec/aws/decider/unit/setup.rb
|
132
134
|
- spec/aws/decider/unit/starter_spec.rb
|
135
|
+
- spec/aws/decider/unit/state_machines_spec.rb
|
136
|
+
- spec/aws/decider/unit/task_poller_spec.rb
|
133
137
|
- spec/aws/decider/unit/worker_spec.rb
|
134
138
|
- spec/aws/decider/unit/workflow_client_spec.rb
|
135
139
|
- spec/aws/flow/unit/async_backtrace_spec.rb
|
@@ -153,6 +157,7 @@ files:
|
|
153
157
|
- spec/aws/templates/unit/result_spec.rb
|
154
158
|
- spec/aws/templates/unit/starter_spec.rb
|
155
159
|
- spec/aws/templates/unit/utilities_spec.rb
|
160
|
+
- spec/aws/utils/unit/utils_spec.rb
|
156
161
|
- spec/spec_helper.rb
|
157
162
|
homepage: https://aws.amazon.com/swf/details/flow/
|
158
163
|
licenses:
|
@@ -165,17 +170,17 @@ require_paths:
|
|
165
170
|
- lib/aws/
|
166
171
|
required_ruby_version: !ruby/object:Gem::Requirement
|
167
172
|
requirements:
|
168
|
-
- -
|
173
|
+
- - ">="
|
169
174
|
- !ruby/object:Gem::Version
|
170
175
|
version: 1.9.1
|
171
176
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
172
177
|
requirements:
|
173
|
-
- -
|
178
|
+
- - ">="
|
174
179
|
- !ruby/object:Gem::Version
|
175
180
|
version: '0'
|
176
181
|
requirements: []
|
177
182
|
rubyforge_project:
|
178
|
-
rubygems_version: 2.
|
183
|
+
rubygems_version: 2.4.6
|
179
184
|
signing_key:
|
180
185
|
specification_version: 4
|
181
186
|
summary: AWS Flow Framework for Ruby
|