right_agent 1.0.1 → 2.0.7
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 +10 -8
- data/Rakefile +31 -5
- data/lib/right_agent.rb +6 -1
- data/lib/right_agent/actor.rb +4 -20
- data/lib/right_agent/actors/agent_manager.rb +1 -1
- data/lib/right_agent/agent.rb +357 -144
- data/lib/right_agent/agent_config.rb +7 -6
- data/lib/right_agent/agent_identity.rb +13 -11
- data/lib/right_agent/agent_tag_manager.rb +60 -64
- data/{spec/results_mock.rb → lib/right_agent/clients.rb} +10 -24
- data/lib/right_agent/clients/api_client.rb +383 -0
- data/lib/right_agent/clients/auth_client.rb +247 -0
- data/lib/right_agent/clients/balanced_http_client.rb +369 -0
- data/lib/right_agent/clients/base_retry_client.rb +495 -0
- data/lib/right_agent/clients/right_http_client.rb +279 -0
- data/lib/right_agent/clients/router_client.rb +493 -0
- data/lib/right_agent/command/command_io.rb +4 -4
- data/lib/right_agent/command/command_parser.rb +2 -2
- data/lib/right_agent/command/command_runner.rb +1 -1
- data/lib/right_agent/connectivity_checker.rb +179 -0
- data/lib/right_agent/core_payload_types/secure_document_location.rb +2 -2
- data/lib/right_agent/dispatcher.rb +12 -10
- data/lib/right_agent/enrollment_result.rb +16 -12
- data/lib/right_agent/exceptions.rb +34 -20
- data/lib/right_agent/history.rb +10 -5
- data/lib/right_agent/log.rb +5 -5
- data/lib/right_agent/minimal.rb +1 -0
- data/lib/right_agent/multiplexer.rb +1 -1
- data/lib/right_agent/offline_handler.rb +270 -0
- data/lib/right_agent/packets.rb +7 -7
- data/lib/right_agent/payload_formatter.rb +1 -1
- data/lib/right_agent/pending_requests.rb +128 -0
- data/lib/right_agent/platform.rb +1 -1
- data/lib/right_agent/protocol_version_mixin.rb +69 -0
- data/lib/right_agent/{idempotent_request.rb → retryable_request.rb} +7 -7
- data/lib/right_agent/scripts/agent_controller.rb +28 -26
- data/lib/right_agent/scripts/agent_deployer.rb +37 -22
- data/lib/right_agent/scripts/common_parser.rb +10 -3
- data/lib/right_agent/secure_identity.rb +1 -1
- data/lib/right_agent/sender.rb +299 -785
- data/lib/right_agent/serialize/secure_serializer.rb +3 -1
- data/lib/right_agent/serialize/secure_serializer_initializer.rb +2 -2
- data/lib/right_agent/serialize/serializable.rb +8 -3
- data/right_agent.gemspec +49 -18
- data/spec/agent_config_spec.rb +7 -7
- data/spec/agent_identity_spec.rb +7 -4
- data/spec/agent_spec.rb +43 -7
- data/spec/agent_tag_manager_spec.rb +72 -83
- data/spec/clients/api_client_spec.rb +423 -0
- data/spec/clients/auth_client_spec.rb +272 -0
- data/spec/clients/balanced_http_client_spec.rb +576 -0
- data/spec/clients/base_retry_client_spec.rb +635 -0
- data/spec/clients/router_client_spec.rb +594 -0
- data/spec/clients/spec_helper.rb +111 -0
- data/spec/command/command_io_spec.rb +1 -1
- data/spec/command/command_parser_spec.rb +1 -1
- data/spec/connectivity_checker_spec.rb +83 -0
- data/spec/dispatcher_spec.rb +3 -2
- data/spec/enrollment_result_spec.rb +2 -2
- data/spec/history_spec.rb +51 -39
- data/spec/offline_handler_spec.rb +340 -0
- data/spec/pending_requests_spec.rb +136 -0
- data/spec/{idempotent_request_spec.rb → retryable_request_spec.rb} +73 -73
- data/spec/sender_spec.rb +835 -1052
- data/spec/serialize/secure_serializer_spec.rb +3 -2
- data/spec/spec_helper.rb +54 -1
- metadata +71 -12
@@ -0,0 +1,111 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2009-2011 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
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
|
23
|
+
require 'restclient'
|
24
|
+
|
25
|
+
require ::File.expand_path('../../spec_helper', __FILE__)
|
26
|
+
|
27
|
+
# Mock auth client providing basic support needed by various clients
|
28
|
+
class AuthClientMock < RightScale::AuthClient
|
29
|
+
attr_reader :test_url, :expired_called, :redirect_location
|
30
|
+
|
31
|
+
def initialize(url, auth_header, state = nil, account_id = nil, identity = nil)
|
32
|
+
@test_url = @api_url = @router_url = url
|
33
|
+
@auth_header = auth_header
|
34
|
+
@account_id = account_id
|
35
|
+
@identity = identity || "rs-agent-1-1"
|
36
|
+
@state = :authorized if state
|
37
|
+
end
|
38
|
+
|
39
|
+
def identity
|
40
|
+
@identity
|
41
|
+
end
|
42
|
+
|
43
|
+
def headers
|
44
|
+
auth_header
|
45
|
+
end
|
46
|
+
|
47
|
+
def auth_header
|
48
|
+
@auth_header
|
49
|
+
end
|
50
|
+
|
51
|
+
def expired
|
52
|
+
@expired_called = true
|
53
|
+
end
|
54
|
+
|
55
|
+
def redirect(location)
|
56
|
+
@redirect_location = location
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# Mock WebSocket event
|
61
|
+
class WebSocketEventMock
|
62
|
+
attr_reader :code, :data, :reason
|
63
|
+
|
64
|
+
def initialize(data, code = nil, reason = nil)
|
65
|
+
@code = code
|
66
|
+
@data = data
|
67
|
+
@reason = reason
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
# Mock of WebSocket so that can call on methods
|
72
|
+
class WebSocketClientMock
|
73
|
+
attr_reader :sent, :closed, :code, :reason
|
74
|
+
|
75
|
+
def send(event)
|
76
|
+
@sent = @sent.nil? ? event : (@sent.is_a?(Array) ? @sent << event : [@sent, event])
|
77
|
+
end
|
78
|
+
|
79
|
+
def close(code = nil, reason = nil)
|
80
|
+
@code = code
|
81
|
+
@reason = reason
|
82
|
+
@closed = true
|
83
|
+
end
|
84
|
+
|
85
|
+
def onclose=(block)
|
86
|
+
@close_block = block
|
87
|
+
end
|
88
|
+
|
89
|
+
def onclose(code, reason = nil)
|
90
|
+
@event = WebSocketEventMock.new(nil, code, reason)
|
91
|
+
@close_block.call(@event)
|
92
|
+
end
|
93
|
+
|
94
|
+
def onerror=(block)
|
95
|
+
@error_block = block
|
96
|
+
end
|
97
|
+
|
98
|
+
def onerror(data)
|
99
|
+
@event = WebSocketEventMock.new(data)
|
100
|
+
@error_block.call(@event)
|
101
|
+
end
|
102
|
+
|
103
|
+
def onmessage=(block)
|
104
|
+
@message_block = block
|
105
|
+
end
|
106
|
+
|
107
|
+
def onmessage(data)
|
108
|
+
@event = WebSocketEventMock.new(data)
|
109
|
+
@message_block.call(@event)
|
110
|
+
end
|
111
|
+
end
|
@@ -53,7 +53,7 @@ describe RightScale::CommandIO do
|
|
53
53
|
end
|
54
54
|
|
55
55
|
it 'should detect missing blocks' do
|
56
|
-
lambda { RightScale::CommandIO.instance.listen(@socket_port) }.should raise_error(
|
56
|
+
lambda { RightScale::CommandIO.instance.listen(@socket_port) }.should raise_error(ArgumentError)
|
57
57
|
end
|
58
58
|
|
59
59
|
it 'should receive a command' do
|
@@ -25,7 +25,7 @@ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
|
|
25
25
|
describe RightScale::CommandParser do
|
26
26
|
|
27
27
|
it 'should detect missing block' do
|
28
|
-
lambda { RightScale::CommandParser.new }.should raise_error(
|
28
|
+
lambda { RightScale::CommandParser.new }.should raise_error(ArgumentError)
|
29
29
|
end
|
30
30
|
|
31
31
|
it 'should parse' do
|
@@ -0,0 +1,83 @@
|
|
1
|
+
#
|
2
|
+
# 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
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
|
23
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'spec_helper'))
|
24
|
+
|
25
|
+
describe RightScale::ConnectivityChecker do
|
26
|
+
|
27
|
+
include FlexMock::ArgumentTypes
|
28
|
+
|
29
|
+
#describe "and checking connection status" do
|
30
|
+
# before(:each) do
|
31
|
+
# @broker_id = "rs-broker-host-123"
|
32
|
+
# @broker_ids = [@broker_id]
|
33
|
+
# end
|
34
|
+
#
|
35
|
+
# it "should not check connection if check already in progress" do
|
36
|
+
# flexmock(EM::Timer).should_receive(:new).and_return(@timer).never
|
37
|
+
# @instance.connectivity_checker.ping_timer = true
|
38
|
+
# flexmock(@instance).should_receive(:publish).never
|
39
|
+
# @instance.connectivity_checker.check(@broker_ids)
|
40
|
+
# end
|
41
|
+
#
|
42
|
+
# it "should publish ping to router" do
|
43
|
+
# flexmock(EM::Timer).should_receive(:new).and_return(@timer).once
|
44
|
+
# flexmock(@instance).should_receive(:publish).with(on { |request| request.type.should == "/router/ping" },
|
45
|
+
# @broker_ids).and_return(@broker_ids).once
|
46
|
+
# @instance.connectivity_checker.check(@broker_id)
|
47
|
+
# @instance.pending_requests.size.should == 1
|
48
|
+
# end
|
49
|
+
#
|
50
|
+
# it "should not make any connection changes if receive ping response" do
|
51
|
+
# flexmock(RightScale::AgentIdentity).should_receive(:generate).and_return('abc').once
|
52
|
+
# @timer.should_receive(:cancel).once
|
53
|
+
# flexmock(EM::Timer).should_receive(:new).and_return(@timer).once
|
54
|
+
# flexmock(@instance).should_receive(:publish).and_return(@broker_ids).once
|
55
|
+
# @instance.connectivity_checker.check(@broker_id)
|
56
|
+
# @instance.connectivity_checker.ping_timer.should == @timer
|
57
|
+
# @instance.pending_requests.size.should == 1
|
58
|
+
# @instance.pending_requests['abc'].response_handler.call(nil)
|
59
|
+
# @instance.connectivity_checker.ping_timer.should == nil
|
60
|
+
# end
|
61
|
+
#
|
62
|
+
# it "should try to reconnect if ping times out repeatedly" do
|
63
|
+
# @log.should_receive(:warning).with(/timed out after 30 seconds/).twice
|
64
|
+
# @log.should_receive(:error).with(/reached maximum of 3 timeouts/).once
|
65
|
+
# flexmock(EM::Timer).should_receive(:new).and_yield.times(3)
|
66
|
+
# flexmock(@agent).should_receive(:connect).once
|
67
|
+
# @instance.connectivity_checker.check(@broker_id)
|
68
|
+
# @instance.connectivity_checker.check(@broker_id)
|
69
|
+
# @instance.connectivity_checker.check(@broker_id)
|
70
|
+
# @instance.connectivity_checker.ping_timer.should == nil
|
71
|
+
# end
|
72
|
+
#
|
73
|
+
# it "should log error if attempt to reconnect fails" do
|
74
|
+
# @log.should_receive(:warning).with(/timed out after 30 seconds/).twice
|
75
|
+
# @log.should_receive(:error).with(/Failed to reconnect/, Exception, :trace).once
|
76
|
+
# flexmock(@agent).should_receive(:connect).and_raise(Exception)
|
77
|
+
# flexmock(EM::Timer).should_receive(:new).and_yield.times(3)
|
78
|
+
# @instance.connectivity_checker.check(@broker_id)
|
79
|
+
# @instance.connectivity_checker.check(@broker_id)
|
80
|
+
# @instance.connectivity_checker.check(@broker_id)
|
81
|
+
# end
|
82
|
+
#end
|
83
|
+
end
|
data/spec/dispatcher_spec.rb
CHANGED
@@ -89,7 +89,7 @@ describe "RightScale::Dispatcher" do
|
|
89
89
|
@registry = RightScale::ActorRegistry.new
|
90
90
|
@registry.register(@actor, nil)
|
91
91
|
@agent_id = "rs-agent-1-1"
|
92
|
-
@agent = flexmock("Agent", :identity => @agent_id, :registry => @registry).by_default
|
92
|
+
@agent = flexmock("Agent", :identity => @agent_id, :registry => @registry, :exception_callback => nil).by_default
|
93
93
|
@cache = RightScale::DispatchedCache.new(@agent_id)
|
94
94
|
@dispatcher = RightScale::Dispatcher.new(@agent, @cache)
|
95
95
|
end
|
@@ -218,7 +218,8 @@ describe "RightScale::Dispatcher" do
|
|
218
218
|
flexmock(Time).should_receive(:now).and_return(Time.at(1000000)).by_default
|
219
219
|
@log.should_receive(:info).once.with(on {|arg| arg =~ /REJECT EXPIRED/})
|
220
220
|
@dispatcher = RightScale::Dispatcher.new(@agent, @cache)
|
221
|
-
req = RightScale::Request.new('/foo/bar', 'you', {:reply_to => "rs-
|
221
|
+
req = RightScale::Request.new('/foo/bar', 'you', {:reply_to => "rs-router-1-1", :expires_at => @now.to_i + 8},
|
222
|
+
[version_cannot_handle_non_delivery_result, RightScale::AgentConfig.protocol_version])
|
222
223
|
flexmock(Time).should_receive(:now).and_return(@now += 10)
|
223
224
|
res = @dispatcher.dispatch(req)
|
224
225
|
res.results.error?.should be_true
|
@@ -15,7 +15,7 @@ require File.expand_path(File.join(File.dirname(__FILE__), '..' , 'lib', 'right_
|
|
15
15
|
describe RightScale::EnrollmentResult do
|
16
16
|
before(:each) do
|
17
17
|
@key = 'topsecret'
|
18
|
-
@result = RightScale::EnrollmentResult.new(6, Time.now, '
|
18
|
+
@result = RightScale::EnrollmentResult.new(6, Time.now, 'router cert', 'my cert', 'my private key', @key)
|
19
19
|
@message = RightScale::EnrollmentResult.dump(@result)
|
20
20
|
end
|
21
21
|
|
@@ -27,7 +27,7 @@ describe RightScale::EnrollmentResult do
|
|
27
27
|
context "supporting different versions" do
|
28
28
|
RightScale::EnrollmentResult::SUPPORTED_VERSIONS.each do |v|
|
29
29
|
it "should support version #{v}" do
|
30
|
-
@result = RightScale::EnrollmentResult.new(v, Time.now, '
|
30
|
+
@result = RightScale::EnrollmentResult.new(v, Time.now, 'router cert', 'my cert', 'my private key', @key)
|
31
31
|
serialized = RightScale::EnrollmentResult.dump(@result)
|
32
32
|
@result2 = RightScale::EnrollmentResult.load(serialized, @key)
|
33
33
|
@result.should == @result2
|
data/spec/history_spec.rb
CHANGED
@@ -25,19 +25,11 @@ require 'tmpdir'
|
|
25
25
|
|
26
26
|
describe RightScale::History do
|
27
27
|
|
28
|
-
# Mock Time.now with well-defined interval
|
29
|
-
def mock_time(size = 20, interval = 10)
|
30
|
-
now = Time.at(1000000)
|
31
|
-
list = []
|
32
|
-
size.times { list << (now += interval) }
|
33
|
-
flexmock(Time).should_receive(:now).and_return(*list)
|
34
|
-
end
|
35
|
-
|
36
28
|
before(:each) do
|
37
29
|
@identity = "rs-agent-1-1"
|
38
30
|
@pid = Process.pid
|
39
|
-
|
40
|
-
flexmock(Time).should_receive(:now).and_return
|
31
|
+
now = Time.at(1000000)
|
32
|
+
flexmock(Time).should_receive(:now).and_return { now += 10 }
|
41
33
|
FileUtils.mkdir_p(@test_dir = File.join(RightScale::Platform.filesystem.temp_dir, 'history_test'))
|
42
34
|
RightScale::AgentConfig.pid_dir = @test_dir
|
43
35
|
@history = RightScale::History.new(@identity)
|
@@ -51,15 +43,14 @@ describe RightScale::History do
|
|
51
43
|
|
52
44
|
it "should store event in history file" do
|
53
45
|
@history.update("some event").should be_true
|
54
|
-
@history.load.should == [{"time" =>
|
46
|
+
@history.load.should == [{"time" => 1000010, "pid" => @pid, "event" => "some event"}]
|
55
47
|
end
|
56
48
|
|
57
49
|
it "should store event in history file following previous event" do
|
58
50
|
@history.update("some event").should be_true
|
59
|
-
flexmock(Time).should_receive(:now).and_return(@now += 10)
|
60
51
|
@history.update("another event").should be_true
|
61
|
-
@history.load.should == [{"time" =>
|
62
|
-
|
52
|
+
@history.load.should == [{"time" => 1000010, "pid" => @pid, "event" => "some event"},
|
53
|
+
{"time" => 1000020, "pid" => @pid, "event" => "another event"}]
|
63
54
|
end
|
64
55
|
|
65
56
|
end
|
@@ -72,7 +63,7 @@ describe RightScale::History do
|
|
72
63
|
|
73
64
|
it "should load events from history file" do
|
74
65
|
@history.update("some event").should be_true
|
75
|
-
@history.load.should == [{"time" =>
|
66
|
+
@history.load.should == [{"time" => 1000010, "pid" => @pid, "event" => "some event"}]
|
76
67
|
end
|
77
68
|
|
78
69
|
end
|
@@ -84,29 +75,27 @@ describe RightScale::History do
|
|
84
75
|
end
|
85
76
|
|
86
77
|
it "should indicate no uptime if not yet running" do
|
87
|
-
mock_time
|
88
78
|
@history.update("start")
|
89
79
|
@history.analyze_service.should == {:uptime => 0, :total_uptime => 0}
|
90
80
|
end
|
91
81
|
|
92
82
|
it "should measure uptime starting from last run time" do
|
93
|
-
mock_time
|
94
83
|
@history.update("start")
|
95
84
|
@history.update("run")
|
96
85
|
@history.analyze_service.should == {:uptime => 10, :total_uptime => 10}
|
97
86
|
end
|
98
87
|
|
99
|
-
it "should not count initial start as a restart" do
|
100
|
-
@history.update("start")
|
101
|
-
@history.update("run")
|
102
|
-
@history.analyze_service.should == {:uptime => 0, :total_uptime => 0}
|
103
|
-
end
|
104
|
-
|
105
88
|
it "should count restarts" do
|
106
89
|
@history.update("start")
|
107
90
|
@history.update("stop")
|
108
91
|
@history.update("start")
|
109
|
-
@history.analyze_service.should ==
|
92
|
+
@history.analyze_service[:restarts].should == 1
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should not count initial start as a restart" do
|
96
|
+
@history.update("start")
|
97
|
+
@history.update("run")
|
98
|
+
@history.analyze_service[:restarts].should be_nil
|
110
99
|
end
|
111
100
|
|
112
101
|
it "should ignore repeated stops when counting restarts" do
|
@@ -114,7 +103,7 @@ describe RightScale::History do
|
|
114
103
|
@history.update("stop")
|
115
104
|
@history.update("stop")
|
116
105
|
@history.update("start")
|
117
|
-
@history.analyze_service.should ==
|
106
|
+
@history.analyze_service[:restarts].should == 1
|
118
107
|
end
|
119
108
|
|
120
109
|
it "should record number of graceful exits if there are restarts" do
|
@@ -130,11 +119,11 @@ describe RightScale::History do
|
|
130
119
|
@history.update("graceful exit")
|
131
120
|
@history.update("start")
|
132
121
|
@history.update("run")
|
133
|
-
@history.analyze_service.should ==
|
122
|
+
@history.analyze_service[:graceful_exits].should == 2
|
123
|
+
@history.analyze_service[:restarts].should == 3
|
134
124
|
end
|
135
125
|
|
136
126
|
it "should measure total uptime across restarts and include current uptime" do
|
137
|
-
mock_time
|
138
127
|
@history.update("start")
|
139
128
|
@history.update("run")
|
140
129
|
@history.update("stop")
|
@@ -153,18 +142,41 @@ describe RightScale::History do
|
|
153
142
|
it "should count crashes" do
|
154
143
|
@history.update("start")
|
155
144
|
@history.update("start")
|
156
|
-
@history.analyze_service.should ==
|
145
|
+
@history.analyze_service[:crashes].should == 1
|
146
|
+
@history.analyze_service[:last_crash_time].should == 1000020
|
147
|
+
@history.analyze_service[:crashed_last].should be_true
|
157
148
|
end
|
158
149
|
|
159
150
|
it "should record last crash age if there are crashes" do
|
160
|
-
mock_time
|
161
151
|
@history.update("start")
|
162
152
|
@history.update("start")
|
163
|
-
@history.analyze_service.should
|
153
|
+
@history.analyze_service[:crashed_last].should be_true
|
154
|
+
end
|
155
|
+
|
156
|
+
it "should determine whether crashed last time was started" do
|
157
|
+
@history.update("start")
|
158
|
+
@history.update("start")
|
159
|
+
@history.analyze_service[:crashed_last].should be_true
|
160
|
+
@history.update("run")
|
161
|
+
@history.analyze_service[:crashed_last].should be_true
|
162
|
+
@history.update("stop")
|
163
|
+
@history.analyze_service[:crashed_last].should be_false
|
164
|
+
@history.update("start")
|
165
|
+
@history.analyze_service[:crashed_last].should be_false
|
166
|
+
@history.update("stop")
|
167
|
+
@history.update("start")
|
168
|
+
@history.analyze_service[:crashed_last].should be_false
|
169
|
+
@history.update("run")
|
170
|
+
@history.update("stop")
|
171
|
+
@history.update("graceful exit")
|
172
|
+
@history.analyze_service[:crashed_last].should be_false
|
173
|
+
@history.update("start")
|
174
|
+
@history.analyze_service[:crashed_last].should be_false
|
175
|
+
@history.update("start")
|
176
|
+
@history.analyze_service[:crashed_last].should be_true
|
164
177
|
end
|
165
178
|
|
166
179
|
it "should count restarts and crashes" do
|
167
|
-
mock_time
|
168
180
|
@history.update("start")
|
169
181
|
@history.update("run")
|
170
182
|
@history.update("stop")
|
@@ -180,8 +192,10 @@ describe RightScale::History do
|
|
180
192
|
@history.update("run")
|
181
193
|
@history.update("start")
|
182
194
|
@history.update("run")
|
183
|
-
@history.analyze_service.should ==
|
184
|
-
|
195
|
+
@history.analyze_service[:crashes].should == 2
|
196
|
+
@history.analyze_service[:restarts].should == 3
|
197
|
+
@history.analyze_service[:last_crash_time].should == 1000140
|
198
|
+
@history.analyze_service[:crashed_last].should be_true
|
185
199
|
end
|
186
200
|
|
187
201
|
it "should ignore unrecognized events" do
|
@@ -195,7 +209,6 @@ describe RightScale::History do
|
|
195
209
|
end
|
196
210
|
|
197
211
|
it "should not re-analyze if there are no new events" do
|
198
|
-
mock_time
|
199
212
|
@history.update("start")
|
200
213
|
@history.update("run")
|
201
214
|
@history.analyze_service.should == {:uptime => 10, :total_uptime => 10}
|
@@ -204,7 +217,6 @@ describe RightScale::History do
|
|
204
217
|
end
|
205
218
|
|
206
219
|
it "should update uptime and total_uptime even if do not do re-analyze" do
|
207
|
-
mock_time
|
208
220
|
@history.update("start")
|
209
221
|
@history.update("run")
|
210
222
|
@history.update("start")
|
@@ -214,19 +226,19 @@ describe RightScale::History do
|
|
214
226
|
@history.update("start")
|
215
227
|
@history.update("run")
|
216
228
|
@history.analyze_service.should == {:uptime => 10, :total_uptime => 30, :restarts => 1, :graceful_exits => 1,
|
217
|
-
:crashes => 1, :last_crash_time => 1000030}
|
229
|
+
:crashes => 1, :last_crash_time => 1000030, :crashed_last => false}
|
218
230
|
@history.analyze_service.should == {:uptime => 20, :total_uptime => 40, :restarts => 1, :graceful_exits => 1,
|
219
|
-
:crashes => 1, :last_crash_time => 1000030}
|
231
|
+
:crashes => 1, :last_crash_time => 1000030, :crashed_last => false}
|
220
232
|
end
|
221
233
|
|
222
234
|
it "should re-analyze if there was a new event since last analysis" do
|
223
|
-
mock_time
|
224
235
|
@history.update("start")
|
225
236
|
@history.update("run")
|
226
237
|
@history.analyze_service.should == {:uptime => 10, :total_uptime => 10}
|
227
238
|
@history.instance_variable_set(:@pid, -1) # Simulate new process id following crash
|
228
239
|
@history.update("start")
|
229
|
-
@history.analyze_service.should == {:uptime => 0, :total_uptime => 20, :crashes => 1, :last_crash_time => 1000040
|
240
|
+
@history.analyze_service.should == {:uptime => 0, :total_uptime => 20, :crashes => 1, :last_crash_time => 1000040,
|
241
|
+
:crashed_last => true}
|
230
242
|
end
|
231
243
|
|
232
244
|
end
|