right_agent 0.14.0 → 0.16.2
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.
- data/README.rdoc +2 -0
- data/lib/right_agent/actors/agent_manager.rb +1 -1
- data/lib/right_agent/agent.rb +28 -14
- data/lib/right_agent/agent_config.rb +1 -1
- data/lib/right_agent/agent_identity.rb +4 -5
- data/lib/right_agent/agent_tag_manager.rb +21 -24
- data/lib/right_agent/core_payload_types/executable_bundle.rb +1 -1
- data/lib/right_agent/core_payload_types/recipe_instantiation.rb +7 -0
- data/lib/right_agent/core_payload_types/right_script_instantiation.rb +20 -5
- data/lib/right_agent/exceptions.rb +44 -1
- data/lib/right_agent/history.rb +4 -1
- data/lib/right_agent/packets.rb +2 -1
- data/lib/right_agent/platform/darwin.rb +6 -0
- data/lib/right_agent/platform/linux.rb +5 -1
- data/lib/right_agent/platform/windows.rb +8 -4
- data/lib/right_agent/scripts/stats_manager.rb +3 -3
- data/lib/right_agent/security/cached_certificate_store_proxy.rb +27 -13
- data/lib/right_agent/security/encrypted_document.rb +1 -2
- data/lib/right_agent/security/static_certificate_store.rb +30 -14
- data/lib/right_agent/sender.rb +101 -47
- data/lib/right_agent/serialize/secure_serializer.rb +29 -27
- data/lib/right_agent/serialize/secure_serializer_initializer.rb +3 -3
- data/lib/right_agent/serialize/serializable.rb +1 -1
- data/lib/right_agent/serialize/serializer.rb +15 -6
- data/right_agent.gemspec +4 -5
- data/spec/agent_spec.rb +2 -2
- data/spec/agent_tag_manager_spec.rb +330 -0
- data/spec/core_payload_types/recipe_instantiation_spec.rb +81 -0
- data/spec/core_payload_types/right_script_instantiation_spec.rb +79 -0
- data/spec/security/cached_certificate_store_proxy_spec.rb +14 -8
- data/spec/security/static_certificate_store_spec.rb +13 -7
- data/spec/sender_spec.rb +114 -17
- data/spec/serialize/secure_serializer_spec.rb +78 -49
- data/spec/serialize/serializer_spec.rb +21 -2
- metadata +90 -36
@@ -0,0 +1,81 @@
|
|
1
|
+
#-- -*- mode: ruby; encoding: utf-8 -*-
|
2
|
+
# Copyright: Copyright (c) 2009-2013 RightScale, Inc.
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
# a copy of this software and associated documentation files (the
|
6
|
+
# 'Software'), to deal in the Software without restriction, including
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
# the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be
|
13
|
+
# included in all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
18
|
+
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
19
|
+
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
20
|
+
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
21
|
+
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
#++
|
23
|
+
|
24
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
|
25
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'lib', 'right_agent', 'core_payload_types'))
|
26
|
+
|
27
|
+
module RightScale
|
28
|
+
describe RecipeInstantiation do
|
29
|
+
let(:nickname) { 'foo' }
|
30
|
+
let(:attributes) do
|
31
|
+
{
|
32
|
+
'rightscale' => {
|
33
|
+
'instance_uuid' => '123-abc',
|
34
|
+
'servers' => {
|
35
|
+
'sketchy' => {
|
36
|
+
'hostname' => 'sketchy123.sketchy.com',
|
37
|
+
'identifier' => '123-abc'
|
38
|
+
},
|
39
|
+
'lumberjack' => {
|
40
|
+
'hostname' => 'syslog123.lumberjack.com',
|
41
|
+
'identifier' => '123-abc'
|
42
|
+
}
|
43
|
+
}
|
44
|
+
}
|
45
|
+
}
|
46
|
+
end
|
47
|
+
let(:id) { 123 }
|
48
|
+
let(:ready) { true }
|
49
|
+
let(:external_inputs) { {} }
|
50
|
+
let(:input_flags) { {} }
|
51
|
+
|
52
|
+
context 'given all fields' do
|
53
|
+
subject do
|
54
|
+
described_class.new(
|
55
|
+
nickname, attributes, id, ready, external_inputs, input_flags)
|
56
|
+
end
|
57
|
+
|
58
|
+
its(:title) { should == nickname }
|
59
|
+
its(:nickname) { should == nickname }
|
60
|
+
its(:attributes) { should == attributes }
|
61
|
+
its(:id) { should == id }
|
62
|
+
its(:ready) { should == ready }
|
63
|
+
its(:external_inputs) { should == external_inputs }
|
64
|
+
its(:input_flags) { should == input_flags }
|
65
|
+
end
|
66
|
+
|
67
|
+
context 'given minimal fields' do
|
68
|
+
subject do
|
69
|
+
described_class.new(nickname, attributes, id, ready)
|
70
|
+
end
|
71
|
+
|
72
|
+
its(:title) { should == nickname }
|
73
|
+
its(:nickname) { should == nickname }
|
74
|
+
its(:attributes) { should == attributes }
|
75
|
+
its(:id) { should == id }
|
76
|
+
its(:ready) { should == ready }
|
77
|
+
its(:external_inputs) { should == nil }
|
78
|
+
its(:input_flags) { should == nil }
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
#-- -*- mode: ruby; encoding: utf-8 -*-
|
2
|
+
# Copyright: Copyright (c) 2009-2013 RightScale, Inc.
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
# a copy of this software and associated documentation files (the
|
6
|
+
# 'Software'), to deal in the Software without restriction, including
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
# the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be
|
13
|
+
# included in all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
18
|
+
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
19
|
+
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
20
|
+
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
21
|
+
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
#++
|
23
|
+
|
24
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
|
25
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'lib', 'right_agent', 'core_payload_types'))
|
26
|
+
|
27
|
+
module RightScale
|
28
|
+
describe RightScriptInstantiation do
|
29
|
+
let(:nickname) { 'foo' }
|
30
|
+
let(:source) { "echo 'hello world'" }
|
31
|
+
let(:parameters) { { 'ADMIN_PASSWORD' => 'clandestine' } }
|
32
|
+
let(:attachments) { [] }
|
33
|
+
let(:packages) { '' }
|
34
|
+
let(:id) { 123 }
|
35
|
+
let(:ready) { true }
|
36
|
+
let(:external_inputs) { {} }
|
37
|
+
let(:input_flags) { {} }
|
38
|
+
let(:display_version) { 'HEAD' }
|
39
|
+
|
40
|
+
context 'given all fields' do
|
41
|
+
subject do
|
42
|
+
described_class.new(
|
43
|
+
nickname, source, parameters, attachments, packages, id, ready,
|
44
|
+
external_inputs, input_flags, display_version)
|
45
|
+
end
|
46
|
+
|
47
|
+
its(:title) { should == "'#{nickname}' #{display_version}" }
|
48
|
+
its(:nickname) { should == nickname }
|
49
|
+
its(:source) { should == source }
|
50
|
+
its(:parameters) { should == parameters }
|
51
|
+
its(:attachments) { should == attachments }
|
52
|
+
its(:packages) { should == packages }
|
53
|
+
its(:id) { should == id }
|
54
|
+
its(:ready) { should == ready }
|
55
|
+
its(:external_inputs) { should == external_inputs }
|
56
|
+
its(:input_flags) { should == input_flags }
|
57
|
+
its(:display_version) { should == display_version }
|
58
|
+
end
|
59
|
+
|
60
|
+
context 'given minimal fields' do
|
61
|
+
subject do
|
62
|
+
described_class.new(
|
63
|
+
nickname, source, parameters, attachments, packages, id, ready)
|
64
|
+
end
|
65
|
+
|
66
|
+
its(:title) { should == nickname }
|
67
|
+
its(:nickname) { should == nickname }
|
68
|
+
its(:source) { should == source }
|
69
|
+
its(:parameters) { should == parameters }
|
70
|
+
its(:attachments) { should == attachments }
|
71
|
+
its(:packages) { should == packages }
|
72
|
+
its(:id) { should == id }
|
73
|
+
its(:ready) { should == ready }
|
74
|
+
its(:external_inputs) { should be_nil }
|
75
|
+
its(:input_flags) { should be_nil }
|
76
|
+
its(:display_version) { should be_nil }
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
#
|
2
|
-
# Copyright (c) 2009-
|
2
|
+
# Copyright (c) 2009-2013 RightScale Inc
|
3
3
|
#
|
4
4
|
# Permission is hereby granted, free of charge, to any person obtaining
|
5
5
|
# a copy of this software and associated documentation files (the
|
@@ -27,30 +27,36 @@ describe RightScale::CachedCertificateStoreProxy do
|
|
27
27
|
include RightScale::SpecHelper
|
28
28
|
|
29
29
|
before(:all) do
|
30
|
+
@cert, @key = issue_cert
|
30
31
|
@signer, key = issue_cert
|
31
|
-
@
|
32
|
+
@target, key = issue_cert
|
32
33
|
@store = flexmock("Store")
|
33
34
|
@proxy = RightScale::CachedCertificateStoreProxy.new(@store)
|
34
35
|
end
|
35
36
|
|
36
37
|
it 'should not raise and return nil for non existent certificates' do
|
37
38
|
res = nil
|
38
|
-
@store.should_receive(:
|
39
|
-
lambda { res = @proxy.
|
39
|
+
@store.should_receive(:get_target).with(nil).and_return(nil)
|
40
|
+
lambda { res = @proxy.get_target(nil) }.should_not raise_error
|
40
41
|
res.should == nil
|
41
42
|
@store.should_receive(:get_signer).with(nil).and_return(nil)
|
42
43
|
lambda { res = @proxy.get_signer(nil) }.should_not raise_error
|
43
44
|
res.should == nil
|
44
45
|
end
|
45
46
|
|
46
|
-
it 'should return
|
47
|
-
@store.should_receive(:
|
48
|
-
@proxy.
|
47
|
+
it 'should return target certificates' do
|
48
|
+
@store.should_receive(:get_target).with('anything').and_return(@target)
|
49
|
+
@proxy.get_target('anything').should == @target
|
49
50
|
end
|
50
51
|
|
51
52
|
it 'should return signer certificates' do
|
52
53
|
@store.should_receive(:get_signer).with('anything').and_return(@signer)
|
53
54
|
@proxy.get_signer('anything').should == @signer
|
54
55
|
end
|
55
|
-
|
56
|
+
|
57
|
+
it 'should return receiver certificate and key' do
|
58
|
+
@store.should_receive(:get_receiver).with('anything').and_return([@cert, @key])
|
59
|
+
@proxy.get_receiver('anything').should == [@cert, @key]
|
60
|
+
end
|
61
|
+
|
56
62
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
#
|
2
|
-
# Copyright (c) 2009-
|
2
|
+
# Copyright (c) 2009-2013 RightScale Inc
|
3
3
|
#
|
4
4
|
# Permission is hereby granted, free of charge, to any person obtaining
|
5
5
|
# a copy of this software and associated documentation files (the
|
@@ -28,25 +28,31 @@ describe RightScale::StaticCertificateStore do
|
|
28
28
|
|
29
29
|
before(:all) do
|
30
30
|
@signer, key = issue_cert
|
31
|
-
@
|
31
|
+
@target, key = issue_cert
|
32
32
|
@cert, @key = issue_cert
|
33
|
-
@store = RightScale::StaticCertificateStore.new(@signer, @
|
33
|
+
@store = RightScale::StaticCertificateStore.new(@cert, @key, @signer, @target)
|
34
34
|
end
|
35
35
|
|
36
36
|
it 'should not raise when passed nil objects' do
|
37
37
|
res = nil
|
38
38
|
lambda { res = @store.get_signer(nil) }.should_not raise_error
|
39
39
|
res.should == [ @signer ]
|
40
|
-
lambda { res = @store.
|
41
|
-
res.should == [ @
|
40
|
+
lambda { res = @store.get_target(nil) }.should_not raise_error
|
41
|
+
res.should == [ @target ]
|
42
|
+
lambda { res = @store.get_receiver(nil) }.should_not raise_error
|
43
|
+
res.should == [ @cert, @key ]
|
42
44
|
end
|
43
45
|
|
44
46
|
it 'should return signer certificates' do
|
45
47
|
@store.get_signer('anything').should == [ @signer ]
|
46
48
|
end
|
47
49
|
|
48
|
-
it 'should return
|
49
|
-
@store.
|
50
|
+
it 'should return target certificates' do
|
51
|
+
@store.get_target('anything').should == [ @target ]
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'should return certificate and key for decrypting' do
|
55
|
+
@store.get_receiver('anything').should == [ @cert, @key ]
|
50
56
|
end
|
51
57
|
|
52
58
|
end
|
data/spec/sender_spec.rb
CHANGED
@@ -508,7 +508,7 @@ describe RightScale::Sender do
|
|
508
508
|
before(:each) do
|
509
509
|
@timer = flexmock("timer")
|
510
510
|
flexmock(EM::Timer).should_receive(:new).and_return(@timer).by_default
|
511
|
-
@broker_id = "broker"
|
511
|
+
@broker_id = "rs-broker-host-123"
|
512
512
|
@broker_ids = [@broker_id]
|
513
513
|
@broker = flexmock("Broker", :subscribe => true, :publish => @broker_ids, :connected? => true,
|
514
514
|
:all => @broker_ids, :identity_parts => ["host", 123, 0, 0]).by_default
|
@@ -520,7 +520,7 @@ describe RightScale::Sender do
|
|
520
520
|
end
|
521
521
|
|
522
522
|
it "should validate target" do
|
523
|
-
@broker.should_receive(:publish)
|
523
|
+
@broker.should_receive(:publish).and_return(@broker_ids).once
|
524
524
|
flexmock(@instance).should_receive(:validate_target).with("target", false).once
|
525
525
|
@instance.send_retryable_request('/foo/bar', nil, "target") {_}.should be_true
|
526
526
|
end
|
@@ -528,7 +528,7 @@ describe RightScale::Sender do
|
|
528
528
|
it "should create a Request object" do
|
529
529
|
@broker.should_receive(:publish).with(hsh(:name => "request"), on do |request|
|
530
530
|
request.class.should == RightScale::Request
|
531
|
-
end, hsh(:persistent => false, :mandatory => true)).once
|
531
|
+
end, hsh(:persistent => false, :mandatory => true)).and_return(@broker_ids).once
|
532
532
|
@instance.send_retryable_request('/welcome/aboard', 'iZac') {|_|}
|
533
533
|
end
|
534
534
|
|
@@ -541,7 +541,7 @@ describe RightScale::Sender do
|
|
541
541
|
request.from.should == 'agent'
|
542
542
|
request.target.should be_nil
|
543
543
|
request.expires_at.should == 1000100
|
544
|
-
end, hsh(:persistent => false, :mandatory => true)).once
|
544
|
+
end, hsh(:persistent => false, :mandatory => true)).and_return(@broker_ids).once
|
545
545
|
@instance.send_retryable_request('/welcome/aboard', 'iZac') {|_|}
|
546
546
|
end
|
547
547
|
|
@@ -553,14 +553,14 @@ describe RightScale::Sender do
|
|
553
553
|
flexmock(Time).should_receive(:now).and_return(Time.at(1000000))
|
554
554
|
@broker.should_receive(:publish).with(hsh(:name => "request"), on do |request|
|
555
555
|
request.expires_at.should == 0
|
556
|
-
end, hsh(:persistent => false, :mandatory => true)).once
|
556
|
+
end, hsh(:persistent => false, :mandatory => true)).and_return(@broker_ids).once
|
557
557
|
@instance.send_retryable_request('/welcome/aboard', 'iZac') {|_|}
|
558
558
|
end
|
559
559
|
|
560
560
|
it "should set the correct target if specified" do
|
561
561
|
@broker.should_receive(:publish).with(hsh(:name => "request"), on do |request|
|
562
562
|
request.target.should == 'my-target'
|
563
|
-
end, hsh(:persistent => false, :mandatory => true)).once
|
563
|
+
end, hsh(:persistent => false, :mandatory => true)).and_return(@broker_ids).once
|
564
564
|
@instance.send_retryable_request('/welcome/aboard', 'iZac', 'my-target') {|_|}
|
565
565
|
end
|
566
566
|
|
@@ -569,7 +569,7 @@ describe RightScale::Sender do
|
|
569
569
|
request.tags.should == ['tag']
|
570
570
|
request.selector.should == :any
|
571
571
|
request.scope.should == {:account => 123}
|
572
|
-
end, hsh(:persistent => false, :mandatory => true)).once
|
572
|
+
end, hsh(:persistent => false, :mandatory => true)).and_return(@broker_ids).once
|
573
573
|
@instance.send_retryable_request('/welcome/aboard', 'iZac', :tags => ['tag'], :scope => {:account => 123}) {|_|}
|
574
574
|
end
|
575
575
|
|
@@ -643,7 +643,7 @@ describe RightScale::Sender do
|
|
643
643
|
@agent.should_receive(:options).and_return({:retry_timeout => nil})
|
644
644
|
RightScale::Sender.new(@agent)
|
645
645
|
@instance = RightScale::Sender.instance
|
646
|
-
@broker.should_receive(:publish).once
|
646
|
+
@broker.should_receive(:publish).and_return(@broker_ids).once
|
647
647
|
@instance.send_retryable_request('/welcome/aboard', 'iZac') {|_|}
|
648
648
|
end
|
649
649
|
|
@@ -652,7 +652,7 @@ describe RightScale::Sender do
|
|
652
652
|
@agent.should_receive(:options).and_return({:retry_interval => nil})
|
653
653
|
RightScale::Sender.new(@agent)
|
654
654
|
@instance = RightScale::Sender.instance
|
655
|
-
@broker.should_receive(:publish).once
|
655
|
+
@broker.should_receive(:publish).and_return(@broker_ids).once
|
656
656
|
@instance.send_retryable_request('/welcome/aboard', 'iZac') {|_|}
|
657
657
|
end
|
658
658
|
|
@@ -661,8 +661,11 @@ describe RightScale::Sender do
|
|
661
661
|
@agent.should_receive(:options).and_return({:retry_timeout => 60, :retry_interval => 60})
|
662
662
|
RightScale::Sender.new(@agent)
|
663
663
|
@instance = RightScale::Sender.instance
|
664
|
-
@broker.should_receive(:publish).
|
665
|
-
@
|
664
|
+
@broker.should_receive(:publish).and_raise(Exception).once
|
665
|
+
@log.should_receive(:error).with(/Failed to publish request/, Exception, :trace).once
|
666
|
+
lambda do
|
667
|
+
@instance.send_retryable_request('/welcome/aboard', 'iZac') {|_|}
|
668
|
+
end.should raise_error(RightScale::Sender::SendFailure)
|
666
669
|
end
|
667
670
|
|
668
671
|
it "should setup for retry if retry_timeout and retry_interval not nil and publish successful" do
|
@@ -674,10 +677,6 @@ describe RightScale::Sender do
|
|
674
677
|
@instance.send_retryable_request('/welcome/aboard', 'iZac') {|_|}
|
675
678
|
end
|
676
679
|
|
677
|
-
it "should adjust retry interval by recent request duration" do
|
678
|
-
|
679
|
-
end
|
680
|
-
|
681
680
|
it "should succeed after retrying once" do
|
682
681
|
EM.run do
|
683
682
|
token = 'abc'
|
@@ -704,6 +703,78 @@ describe RightScale::Sender do
|
|
704
703
|
end
|
705
704
|
end
|
706
705
|
|
706
|
+
it "should respond with retry if publish fails with no brokers when retrying" do
|
707
|
+
EM.run do
|
708
|
+
token = 'abc'
|
709
|
+
result = RightScale::OperationResult.non_delivery(RightScale::OperationResult::RETRY_TIMEOUT)
|
710
|
+
flexmock(RightScale::AgentIdentity).should_receive(:generate).and_return(token).twice
|
711
|
+
@agent.should_receive(:options).and_return({:retry_timeout => 0.3, :retry_interval => 0.1})
|
712
|
+
RightScale::Sender.new(@agent)
|
713
|
+
@instance = RightScale::Sender.instance
|
714
|
+
flexmock(@instance.connectivity_checker).should_receive(:check).never
|
715
|
+
@broker.should_receive(:publish).and_return(@broker_ids).ordered.once
|
716
|
+
@broker.should_receive(:publish).and_raise(RightAMQP::HABrokerClient::NoConnectedBrokers).ordered.once
|
717
|
+
@log.should_receive(:error).with(/Failed to publish request/, RightAMQP::HABrokerClient::NoConnectedBrokers).once
|
718
|
+
@log.should_receive(:error).with(/Failed retry for.*temporarily offline/).once
|
719
|
+
@instance.send_retryable_request('/welcome/aboard', 'iZac') do |response|
|
720
|
+
result = RightScale::OperationResult.from_results(response)
|
721
|
+
result.retry?.should be_true
|
722
|
+
result.content.should == "lost connectivity"
|
723
|
+
end
|
724
|
+
EM.add_timer(0.15) do
|
725
|
+
EM.stop
|
726
|
+
result.retry?.should be_true
|
727
|
+
@instance.pending_requests.empty?.should be_true
|
728
|
+
end
|
729
|
+
end
|
730
|
+
end
|
731
|
+
|
732
|
+
it "should respond with non-delivery if publish fails in unknown way when retrying" do
|
733
|
+
EM.run do
|
734
|
+
token = 'abc'
|
735
|
+
result = RightScale::OperationResult.non_delivery(RightScale::OperationResult::RETRY_TIMEOUT)
|
736
|
+
flexmock(RightScale::AgentIdentity).should_receive(:generate).and_return(token).twice
|
737
|
+
@agent.should_receive(:options).and_return({:retry_timeout => 0.3, :retry_interval => 0.1})
|
738
|
+
RightScale::Sender.new(@agent)
|
739
|
+
@instance = RightScale::Sender.instance
|
740
|
+
flexmock(@instance.connectivity_checker).should_receive(:check).never
|
741
|
+
@broker.should_receive(:publish).and_return(@broker_ids).ordered.once
|
742
|
+
@broker.should_receive(:publish).and_raise(Exception.new).ordered.once
|
743
|
+
@log.should_receive(:error).with(/Failed to publish request/, Exception, :trace).once
|
744
|
+
@log.should_receive(:error).with(/Failed retry for.*send failure/).once
|
745
|
+
@instance.send_retryable_request('/welcome/aboard', 'iZac') do |response|
|
746
|
+
result = RightScale::OperationResult.from_results(response)
|
747
|
+
result.non_delivery?.should be_true
|
748
|
+
result.content.should == "retry failed"
|
749
|
+
end
|
750
|
+
EM.add_timer(0.15) do
|
751
|
+
EM.stop
|
752
|
+
result.non_delivery?.should be_true
|
753
|
+
@instance.pending_requests.empty?.should be_true
|
754
|
+
end
|
755
|
+
end
|
756
|
+
end
|
757
|
+
|
758
|
+
it "should not respond if retry mechanism fails in unknown way" do
|
759
|
+
EM.run do
|
760
|
+
token = 'abc'
|
761
|
+
result = nil
|
762
|
+
flexmock(RightScale::AgentIdentity).should_receive(:generate).and_return(token).twice
|
763
|
+
@agent.should_receive(:options).and_return({:retry_timeout => 0.3, :retry_interval => 0.1})
|
764
|
+
RightScale::Sender.new(@agent)
|
765
|
+
@instance = RightScale::Sender.instance
|
766
|
+
flexmock(@instance.connectivity_checker).should_receive(:check).and_raise(Exception).once
|
767
|
+
@broker.should_receive(:publish).and_return(@broker_ids).twice
|
768
|
+
@log.should_receive(:error).with(/Failed retry for.*without responding/, Exception, :trace).once
|
769
|
+
@instance.send_retryable_request('/welcome/aboard', 'iZac') {_}
|
770
|
+
EM.add_timer(0.15) do
|
771
|
+
EM.stop
|
772
|
+
result.should be_nil
|
773
|
+
@instance.pending_requests.empty?.should be_false
|
774
|
+
end
|
775
|
+
end
|
776
|
+
end
|
777
|
+
|
707
778
|
it "should timeout after retrying twice" do
|
708
779
|
pending 'Too difficult to get timing right for Windows' if RightScale::Platform.windows?
|
709
780
|
EM.run do
|
@@ -727,6 +798,32 @@ describe RightScale::Sender do
|
|
727
798
|
end
|
728
799
|
end
|
729
800
|
|
801
|
+
it "should return non-delivery after timeout if any attempt failed due to non-delivery" do
|
802
|
+
pending 'Too difficult to get timing right for Windows' if RightScale::Platform.windows?
|
803
|
+
EM.run do
|
804
|
+
result = RightScale::OperationResult.success
|
805
|
+
@log.should_receive(:warning).once
|
806
|
+
@agent.should_receive(:options).and_return({:retry_timeout => 0.6, :retry_interval => 0.1})
|
807
|
+
RightScale::Sender.new(@agent)
|
808
|
+
@instance = RightScale::Sender.instance
|
809
|
+
flexmock(@instance.connectivity_checker).should_receive(:check).once
|
810
|
+
@broker.should_receive(:publish).and_return(@broker_ids).times(3)
|
811
|
+
@instance.send_retryable_request('/welcome/aboard', 'iZac') do |response|
|
812
|
+
result = RightScale::OperationResult.from_results(response)
|
813
|
+
end
|
814
|
+
@instance.pending_requests.empty?.should be_false
|
815
|
+
token = @instance.pending_requests.keys.last
|
816
|
+
non_delivery = RightScale::OperationResult.non_delivery(RightScale::OperationResult::TTL_EXPIRATION)
|
817
|
+
@instance.handle_response(RightScale::Result.new(token, 'iZac', non_delivery, "from"))
|
818
|
+
EM.add_timer(1) do
|
819
|
+
EM.stop
|
820
|
+
result.non_delivery?.should be_true
|
821
|
+
result.content.should == non_delivery.content
|
822
|
+
@instance.pending_requests.empty?.should be_true
|
823
|
+
end
|
824
|
+
end
|
825
|
+
end
|
826
|
+
|
730
827
|
it "should retry with same request expires_at value" do
|
731
828
|
EM.run do
|
732
829
|
token = 'abc'
|
@@ -746,7 +843,7 @@ describe RightScale::Sender do
|
|
746
843
|
|
747
844
|
describe "and checking connection status" do
|
748
845
|
before(:each) do
|
749
|
-
@broker_id = "broker"
|
846
|
+
@broker_id = "rs-broker-host-123"
|
750
847
|
@broker_ids = [@broker_id]
|
751
848
|
end
|
752
849
|
|
@@ -805,7 +902,7 @@ describe RightScale::Sender do
|
|
805
902
|
before(:each) do
|
806
903
|
@timer = flexmock("timer")
|
807
904
|
flexmock(EM::Timer).should_receive(:new).and_return(@timer).by_default
|
808
|
-
@broker_id = "broker"
|
905
|
+
@broker_id = "rs-broker-host-123"
|
809
906
|
@broker_ids = [@broker_id]
|
810
907
|
@broker = flexmock("Broker", :subscribe => true, :publish => @broker_ids, :connected? => true,
|
811
908
|
:identity_parts => ["host", 123, 0, 0]).by_default
|