right_agent 0.6.6 → 0.9.3
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/lib/right_agent/agent.rb +26 -25
- data/lib/right_agent/agent_config.rb +28 -2
- data/lib/right_agent/command/command_constants.rb +2 -2
- data/lib/right_agent/core_payload_types/executable_bundle.rb +3 -21
- data/lib/right_agent/core_payload_types/login_user.rb +19 -4
- data/lib/right_agent/core_payload_types/recipe_instantiation.rb +7 -1
- data/lib/right_agent/core_payload_types/right_script_instantiation.rb +7 -1
- data/lib/right_agent/dispatcher.rb +6 -19
- data/lib/right_agent/idempotent_request.rb +72 -17
- data/lib/right_agent/monkey_patches/ruby_patch.rb +0 -1
- data/lib/right_agent/monkey_patches.rb +0 -1
- data/lib/right_agent/operation_result.rb +27 -4
- data/lib/right_agent/packets.rb +47 -23
- data/lib/right_agent/platform/darwin.rb +33 -2
- data/lib/right_agent/platform/linux.rb +98 -2
- data/lib/right_agent/platform/windows.rb +41 -6
- data/lib/right_agent/platform.rb +11 -2
- data/lib/right_agent/scripts/agent_controller.rb +2 -1
- data/lib/right_agent/scripts/agent_deployer.rb +2 -2
- data/lib/right_agent/scripts/stats_manager.rb +7 -3
- data/lib/right_agent/sender.rb +45 -28
- data/lib/right_agent.rb +2 -5
- data/right_agent.gemspec +5 -3
- data/spec/agent_config_spec.rb +1 -1
- data/spec/agent_spec.rb +26 -20
- data/spec/core_payload_types/login_user_spec.rb +7 -3
- data/spec/idempotent_request_spec.rb +218 -48
- data/spec/operation_result_spec.rb +19 -0
- data/spec/packets_spec.rb +42 -1
- data/spec/platform/darwin.rb +11 -0
- data/spec/platform/linux.rb +23 -0
- data/spec/platform/linux_volume_manager_spec.rb +43 -43
- data/spec/platform/platform_spec.rb +35 -32
- data/spec/platform/windows.rb +11 -0
- data/spec/sender_spec.rb +21 -25
- metadata +47 -40
- data/lib/right_agent/broker_client.rb +0 -686
- data/lib/right_agent/ha_broker_client.rb +0 -1327
- data/lib/right_agent/monkey_patches/amqp_patch.rb +0 -274
- data/lib/right_agent/monkey_patches/ruby_patch/string_patch.rb +0 -107
- data/lib/right_agent/stats_helper.rb +0 -745
- data/spec/broker_client_spec.rb +0 -962
- data/spec/ha_broker_client_spec.rb +0 -1695
- data/spec/monkey_patches/amqp_patch_spec.rb +0 -100
- data/spec/monkey_patches/string_patch_spec.rb +0 -99
- data/spec/stats_helper_spec.rb +0 -686
data/spec/stats_helper_spec.rb
DELETED
@@ -1,686 +0,0 @@
|
|
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 File.expand_path(File.join(File.dirname(__FILE__), 'spec_helper'))
|
24
|
-
|
25
|
-
describe RightScale::StatsHelper do
|
26
|
-
|
27
|
-
before(:all) do
|
28
|
-
@original_recent_size = RightScale::StatsHelper::ActivityStats::RECENT_SIZE
|
29
|
-
RightScale::StatsHelper::ActivityStats.const_set(:RECENT_SIZE, 10)
|
30
|
-
end
|
31
|
-
|
32
|
-
after(:all) do
|
33
|
-
RightScale::StatsHelper::ActivityStats.const_set(:RECENT_SIZE, @original_recent_size)
|
34
|
-
end
|
35
|
-
|
36
|
-
include FlexMock::ArgumentTypes
|
37
|
-
|
38
|
-
describe "ActivityStats" do
|
39
|
-
|
40
|
-
before(:each) do
|
41
|
-
@now = 1000000
|
42
|
-
flexmock(Time).should_receive(:now).and_return(@now).by_default
|
43
|
-
@stats = RightScale::StatsHelper::ActivityStats.new
|
44
|
-
end
|
45
|
-
|
46
|
-
it "should initialize stats data" do
|
47
|
-
@stats.instance_variable_get(:@interval).should == 0.0
|
48
|
-
@stats.instance_variable_get(:@last_start_time).should == @now
|
49
|
-
@stats.instance_variable_get(:@avg_duration).should be_nil
|
50
|
-
@stats.instance_variable_get(:@total).should == 0
|
51
|
-
@stats.instance_variable_get(:@count_per_type).should == {}
|
52
|
-
end
|
53
|
-
|
54
|
-
it "should update count and interval information" do
|
55
|
-
flexmock(Time).should_receive(:now).and_return(1000010)
|
56
|
-
@stats.update
|
57
|
-
@stats.instance_variable_get(:@interval).should == 1.0
|
58
|
-
@stats.instance_variable_get(:@last_start_time).should == @now + 10
|
59
|
-
@stats.instance_variable_get(:@avg_duration).should be_nil
|
60
|
-
@stats.instance_variable_get(:@total).should == 1
|
61
|
-
@stats.instance_variable_get(:@count_per_type).should == {}
|
62
|
-
end
|
63
|
-
|
64
|
-
it "should update weight the average interval toward recent activity" do
|
65
|
-
end
|
66
|
-
|
67
|
-
it "should update counts per type when type provided" do
|
68
|
-
flexmock(Time).should_receive(:now).and_return(1000010)
|
69
|
-
@stats.update("test")
|
70
|
-
@stats.instance_variable_get(:@interval).should == 1.0
|
71
|
-
@stats.instance_variable_get(:@last_start_time).should == @now + 10
|
72
|
-
@stats.instance_variable_get(:@avg_duration).should be_nil
|
73
|
-
@stats.instance_variable_get(:@total).should == 1
|
74
|
-
@stats.instance_variable_get(:@count_per_type).should == {"test" => 1}
|
75
|
-
end
|
76
|
-
|
77
|
-
it "should not update counts when type contains 'stats'" do
|
78
|
-
flexmock(Time).should_receive(:now).and_return(1000010)
|
79
|
-
@stats.update("my stats")
|
80
|
-
@stats.instance_variable_get(:@interval).should == 0.0
|
81
|
-
@stats.instance_variable_get(:@last_start_time).should == @now
|
82
|
-
@stats.instance_variable_get(:@avg_duration).should be_nil
|
83
|
-
@stats.instance_variable_get(:@total).should == 0
|
84
|
-
@stats.instance_variable_get(:@count_per_type).should == {}
|
85
|
-
end
|
86
|
-
|
87
|
-
it "should limit length of type string when submitting update" do
|
88
|
-
flexmock(Time).should_receive(:now).and_return(1000010)
|
89
|
-
@stats.update("test 12345678901234567890123456789012345678901234567890123456789")
|
90
|
-
@stats.instance_variable_get(:@total).should == 1
|
91
|
-
@stats.instance_variable_get(:@count_per_type).should ==
|
92
|
-
{"test 1234567890123456789012345678901234567890123456789012..." => 1}
|
93
|
-
end
|
94
|
-
|
95
|
-
it "should not convert symbol or boolean to string when submitting update" do
|
96
|
-
flexmock(Time).should_receive(:now).and_return(1000010)
|
97
|
-
@stats.update(:test)
|
98
|
-
@stats.update(true)
|
99
|
-
@stats.update(false)
|
100
|
-
@stats.instance_variable_get(:@total).should == 3
|
101
|
-
@stats.instance_variable_get(:@count_per_type).should == {:test => 1, true => 1, false => 1}
|
102
|
-
end
|
103
|
-
|
104
|
-
it "should convert arbitrary type value to limited-length string when submitting update" do
|
105
|
-
flexmock(Time).should_receive(:now).and_return(1000010)
|
106
|
-
@stats.update({1 => 11, 2 => 22})
|
107
|
-
@stats.update({1 => 11, 2 => 22, 3 => 12345678901234567890123456789012345678901234567890123456789})
|
108
|
-
@stats.instance_variable_get(:@total).should == 2
|
109
|
-
@stats.instance_variable_get(:@count_per_type).should == {"{1=>11, 2=>22}" => 1,
|
110
|
-
"{1=>11, 2=>22, 3=>123456789012345678901234567890123456789..." => 1}
|
111
|
-
end
|
112
|
-
|
113
|
-
it "should not measure rate if disabled" do
|
114
|
-
@stats = RightScale::StatsHelper::ActivityStats.new(false)
|
115
|
-
flexmock(Time).should_receive(:now).and_return(1000010)
|
116
|
-
@stats.update
|
117
|
-
@stats.instance_variable_get(:@interval).should == 0.0
|
118
|
-
@stats.instance_variable_get(:@last_start_time).should == @now + 10
|
119
|
-
@stats.instance_variable_get(:@avg_duration).should be_nil
|
120
|
-
@stats.instance_variable_get(:@total).should == 1
|
121
|
-
@stats.instance_variable_get(:@count_per_type).should == {}
|
122
|
-
@stats.all.should == {"last" => {"elapsed"=>0}, "total" => 1}
|
123
|
-
end
|
124
|
-
|
125
|
-
it "should update duration when finish using internal start time by default" do
|
126
|
-
flexmock(Time).should_receive(:now).and_return(1000010)
|
127
|
-
@stats.finish
|
128
|
-
@stats.instance_variable_get(:@interval).should == 0.0
|
129
|
-
@stats.instance_variable_get(:@last_start_time).should == @now
|
130
|
-
@stats.instance_variable_get(:@avg_duration).should == 1.0
|
131
|
-
@stats.instance_variable_get(:@total).should == 0
|
132
|
-
@stats.instance_variable_get(:@count_per_type).should == {}
|
133
|
-
end
|
134
|
-
|
135
|
-
it "should update duration when finish using specified start time" do
|
136
|
-
flexmock(Time).should_receive(:now).and_return(1000030)
|
137
|
-
@stats.avg_duration.should be_nil
|
138
|
-
@stats.finish(1000010)
|
139
|
-
@stats.instance_variable_get(:@interval).should == 0.0
|
140
|
-
@stats.instance_variable_get(:@last_start_time).should == @now
|
141
|
-
@stats.instance_variable_get(:@avg_duration).should == 2.0
|
142
|
-
@stats.instance_variable_get(:@total).should == 0
|
143
|
-
@stats.instance_variable_get(:@count_per_type).should == {}
|
144
|
-
end
|
145
|
-
|
146
|
-
it "should convert interval to rate" do
|
147
|
-
flexmock(Time).should_receive(:now).and_return(1000020)
|
148
|
-
@stats.avg_rate.should be_nil
|
149
|
-
@stats.update
|
150
|
-
@stats.instance_variable_get(:@interval).should == 2.0
|
151
|
-
@stats.avg_rate.should == 0.5
|
152
|
-
end
|
153
|
-
|
154
|
-
it "should report number of seconds since last update or nil if no updates" do
|
155
|
-
flexmock(Time).should_receive(:now).and_return(1000010)
|
156
|
-
@stats.last.should be_nil
|
157
|
-
@stats.update
|
158
|
-
@stats.last.should == {"elapsed" => 0}
|
159
|
-
end
|
160
|
-
|
161
|
-
it "should report number of seconds since last update and last type" do
|
162
|
-
@stats.update("test")
|
163
|
-
flexmock(Time).should_receive(:now).and_return(1000010)
|
164
|
-
@stats.last.should == {"elapsed" => 10, "type" => "test"}
|
165
|
-
end
|
166
|
-
|
167
|
-
it "should report whether last activity is still active" do
|
168
|
-
@stats.update("test", "token")
|
169
|
-
flexmock(Time).should_receive(:now).and_return(1000010)
|
170
|
-
@stats.last.should == {"elapsed" => 10, "type" => "test", "active" => true}
|
171
|
-
@stats.finish(@now - 10, "token")
|
172
|
-
@stats.last.should == {"elapsed" => 10, "type" => "test", "active" => false}
|
173
|
-
@stats.instance_variable_get(:@avg_duration).should == 2.0
|
174
|
-
end
|
175
|
-
|
176
|
-
it "should convert count per type to percentages" do
|
177
|
-
flexmock(Time).should_receive(:now).and_return(1000010)
|
178
|
-
@stats.update("foo")
|
179
|
-
@stats.instance_variable_get(:@total).should == 1
|
180
|
-
@stats.instance_variable_get(:@count_per_type).should == {"foo" => 1}
|
181
|
-
@stats.percentage.should == {"total" => 1, "percent" => {"foo" => 100.0}}
|
182
|
-
@stats.update("bar")
|
183
|
-
@stats.instance_variable_get(:@total).should == 2
|
184
|
-
@stats.instance_variable_get(:@count_per_type).should == {"foo" => 1, "bar" => 1}
|
185
|
-
@stats.percentage.should == {"total" => 2, "percent" => {"foo" => 50.0, "bar" => 50.0}}
|
186
|
-
@stats.update("foo")
|
187
|
-
@stats.update("foo")
|
188
|
-
@stats.instance_variable_get(:@total).should == 4
|
189
|
-
@stats.instance_variable_get(:@count_per_type).should == {"foo" => 3, "bar" => 1}
|
190
|
-
@stats.percentage.should == {"total" => 4, "percent" => {"foo" => 75.0, "bar" => 25.0}}
|
191
|
-
end
|
192
|
-
|
193
|
-
end # ActivityStats
|
194
|
-
|
195
|
-
describe "ExceptionStats" do
|
196
|
-
|
197
|
-
before(:each) do
|
198
|
-
@now = 1000000
|
199
|
-
flexmock(Time).should_receive(:now).and_return(@now).by_default
|
200
|
-
@stats = RightScale::StatsHelper::ExceptionStats.new
|
201
|
-
@exception = Exception.new("Test error")
|
202
|
-
end
|
203
|
-
|
204
|
-
it "should initialize stats data" do
|
205
|
-
@stats.stats.should be_nil
|
206
|
-
@stats.instance_variable_get(:@callback).should be_nil
|
207
|
-
end
|
208
|
-
|
209
|
-
it "should track submitted exception information by category" do
|
210
|
-
@stats.track("testing", @exception)
|
211
|
-
@stats.stats.should == {"testing" => {"total" => 1,
|
212
|
-
"recent" => [{"count" => 1, "type" => "Exception", "message" => "Test error",
|
213
|
-
"when" => @now, "where" => nil}]}}
|
214
|
-
end
|
215
|
-
|
216
|
-
it "should recognize and count repeated exceptions" do
|
217
|
-
@stats.track("testing", @exception)
|
218
|
-
@stats.stats.should == {"testing" => {"total" => 1,
|
219
|
-
"recent" => [{"count" => 1, "type" => "Exception", "message" => "Test error",
|
220
|
-
"when" => @now, "where" => nil}]}}
|
221
|
-
flexmock(Time).should_receive(:now).and_return(1000010)
|
222
|
-
category = "another"
|
223
|
-
backtrace = ["here", "and", "there"]
|
224
|
-
4.times do |i|
|
225
|
-
begin
|
226
|
-
raise ArgumentError, "badarg"
|
227
|
-
rescue Exception => e
|
228
|
-
flexmock(e).should_receive(:backtrace).and_return(backtrace)
|
229
|
-
@stats.track(category, e)
|
230
|
-
backtrace.shift(2) if i == 1
|
231
|
-
category = "testing" if i == 2
|
232
|
-
end
|
233
|
-
end
|
234
|
-
@stats.stats.should == {"testing" => {"total" => 2,
|
235
|
-
"recent" => [{"count" => 1, "type" => "Exception", "message" => "Test error",
|
236
|
-
"when" => @now, "where" => nil},
|
237
|
-
{"count" => 1, "type" => "ArgumentError", "message" => "badarg",
|
238
|
-
"when" => @now + 10, "where" => "there"}]},
|
239
|
-
"another" => {"total" => 3,
|
240
|
-
"recent" => [{"count" => 2, "type" => "ArgumentError", "message" => "badarg",
|
241
|
-
"when" => @now + 10, "where" => "here"},
|
242
|
-
{"count" => 1, "type" => "ArgumentError", "message" => "badarg",
|
243
|
-
"when" => @now + 10, "where" => "there"}]}}
|
244
|
-
end
|
245
|
-
|
246
|
-
it "should limit the number of exceptions stored by eliminating older exceptions" do
|
247
|
-
(RightScale::StatsHelper::ExceptionStats::MAX_RECENT_EXCEPTIONS + 1).times do |i|
|
248
|
-
begin
|
249
|
-
raise ArgumentError, "badarg"
|
250
|
-
rescue Exception => e
|
251
|
-
flexmock(e).should_receive(:backtrace).and_return([i.to_s])
|
252
|
-
@stats.track("testing", e)
|
253
|
-
end
|
254
|
-
end
|
255
|
-
stats = @stats.stats
|
256
|
-
stats["testing"]["total"].should == RightScale::StatsHelper::ExceptionStats::MAX_RECENT_EXCEPTIONS + 1
|
257
|
-
stats["testing"]["recent"].size.should == RightScale::StatsHelper::ExceptionStats::MAX_RECENT_EXCEPTIONS
|
258
|
-
stats["testing"]["recent"][0]["where"].should == "1"
|
259
|
-
end
|
260
|
-
|
261
|
-
it "should make callback if callback and message defined" do
|
262
|
-
called = 0
|
263
|
-
callback = lambda do |exception, message, server|
|
264
|
-
called += 1
|
265
|
-
exception.should == @exception
|
266
|
-
message.should == "message"
|
267
|
-
server.should == "server"
|
268
|
-
end
|
269
|
-
@stats = RightScale::StatsHelper::ExceptionStats.new("server", callback)
|
270
|
-
@stats.track("testing", @exception, "message")
|
271
|
-
@stats.stats.should == {"testing" => {"total" => 1,
|
272
|
-
"recent" => [{"count" => 1, "type" => "Exception", "message" => "Test error",
|
273
|
-
"when" => @now, "where" => nil}]}}
|
274
|
-
called.should == 1
|
275
|
-
end
|
276
|
-
|
277
|
-
it "should catch any exceptions raised internally" do
|
278
|
-
flexmock(RightScale::Log).should_receive(:error).with(/Failed to track exception/).once
|
279
|
-
flexmock(@exception).should_receive(:backtrace).and_raise(Exception)
|
280
|
-
@stats = RightScale::StatsHelper::ExceptionStats.new
|
281
|
-
@stats.track("testing", @exception, "message")
|
282
|
-
@stats.stats["testing"]["total"].should == 1
|
283
|
-
end
|
284
|
-
|
285
|
-
end # ExceptionStats
|
286
|
-
|
287
|
-
describe "Formatting" do
|
288
|
-
|
289
|
-
include RightScale::StatsHelper
|
290
|
-
|
291
|
-
before(:each) do
|
292
|
-
@now = 1000000
|
293
|
-
flexmock(Time).should_receive(:now).and_return(@now).by_default
|
294
|
-
@exceptions = RightScale::StatsHelper::ExceptionStats.new
|
295
|
-
@brokers = {"brokers"=> [{"alias" => "b0", "identity" => "rs-broker-localhost-5672", "status" => "connected",
|
296
|
-
"disconnect last" => nil,"disconnects" => nil, "failure last" => nil, "failures" => nil,
|
297
|
-
"retries" => nil},
|
298
|
-
{"alias" => "b1", "identity" => "rs-broker-localhost-5673", "status" => "disconnected",
|
299
|
-
"disconnect last" => {"elapsed" => 1000}, "disconnects" => 2,
|
300
|
-
"failure last" => nil, "failures" => nil, "retries" => nil},
|
301
|
-
{"alias" => "b2", "identity" => "rs-broker-localhost-5674", "status" => "failed",
|
302
|
-
"disconnect last" => nil, "disconnects" => nil,
|
303
|
-
"failure last" => {"elapsed" => 1000}, "failures" => 3, "retries" => 2}],
|
304
|
-
"heartbeat" => nil,
|
305
|
-
"exceptions" => {}}
|
306
|
-
end
|
307
|
-
|
308
|
-
it "should convert values to percentages" do
|
309
|
-
stats = {"first" => 1, "second" => 4, "third" => 3}
|
310
|
-
result = percentage(stats)
|
311
|
-
result.should == {"total" => 8, "percent" => {"first" => 12.5, "second" => 50.0, "third" => 37.5}}
|
312
|
-
end
|
313
|
-
|
314
|
-
it "should convert 0 to nil" do
|
315
|
-
nil_if_zero(0).should be_nil
|
316
|
-
nil_if_zero(0.0).should be_nil
|
317
|
-
nil_if_zero(1).should == 1
|
318
|
-
nil_if_zero(1.0).should == 1.0
|
319
|
-
end
|
320
|
-
|
321
|
-
it "should sort hash by key into array with integer conversion of keys if possible" do
|
322
|
-
sort_key({"c" => 3, "a" => 1, "b" => 2}).should == [["a", 1], ["b", 2], ["c", 3]]
|
323
|
-
sort_key({3 => "c", 1 => "a", 2 => "b"}).should == [[1, "a"], [2, "b"], [3, "c"]]
|
324
|
-
sort_key({11 => "c", 9 => "a", 10 => "b"}).should == [[9, "a"], [10, "b"], [11, "c"]]
|
325
|
-
sort_key({"append_info" => 9.6, "create_new_section" => 8.5, "append_output" => 7.3, "record" => 4.7,
|
326
|
-
"update_status" => 4.4,
|
327
|
-
"declare" => 39.2, "list_agents" => 3.7, "update_tags" => 3.2, "append_error" => 3.0,
|
328
|
-
"add_user" => 2.4, "get_boot_bundle" => 1.4, "get_repositories" => 1.4,
|
329
|
-
"update_login_policy" => 1.3, "schedule_decommission" => 0.91, "update_inputs" => 0.75,
|
330
|
-
"delete_queues" => 0.75, "soft_decommission" => 0.75, "remove" => 0.66,
|
331
|
-
"get_login_policy" => 0.58, "ping" => 0.50, "update_entry" => 0.25, "query_tags" => 0.083,
|
332
|
-
"get_decommission_bundle" => 0.083, "list_queues" => 0.083}).should ==
|
333
|
-
[["add_user", 2.4], ["append_error", 3.0], ["append_info", 9.6], ["append_output", 7.3],
|
334
|
-
["create_new_section", 8.5], ["declare", 39.2], ["delete_queues", 0.75], ["get_boot_bundle", 1.4],
|
335
|
-
["get_decommission_bundle", 0.083], ["get_login_policy", 0.58], ["get_repositories", 1.4],
|
336
|
-
["list_agents", 3.7], ["list_queues", 0.083], ["ping", 0.5], ["query_tags", 0.083],
|
337
|
-
["record", 4.7], ["remove", 0.66], ["schedule_decommission", 0.91], ["soft_decommission", 0.75],
|
338
|
-
["update_entry", 0.25], ["update_inputs", 0.75],
|
339
|
-
["update_login_policy", 1.3], ["update_status", 4.4], ["update_tags", 3.2]]
|
340
|
-
end
|
341
|
-
|
342
|
-
it "should sort hash by value into array" do
|
343
|
-
sort_value({"c" => 3, "a" => 2, "b" => 1}).should == [["b", 1], ["a", 2], ["c", 3]]
|
344
|
-
sort_value({"c" => 3.0, "a" => 2, "b" => 1.0}).should == [["b", 1.0], ["a", 2], ["c", 3.0]]
|
345
|
-
sort_value({"append_info" => 9.6, "create_new_section" => 8.5, "append_output" => 7.3, "record" => 4.7,
|
346
|
-
"update_status" => 4.4,
|
347
|
-
"declare" => 39.2, "list_agents" => 3.7, "update_tags" => 3.2, "append_error" => 3.0,
|
348
|
-
"add_user" => 2.4, "get_boot_bundle" => 1.4, "get_repositories" => 1.4,
|
349
|
-
"update_login_policy" => 1.3, "schedule_decommission" => 0.91, "update_inputs" => 0.75,
|
350
|
-
"delete_queues" => 0.75, "soft_decommission" => 0.75, "remove" => 0.66,
|
351
|
-
"get_login_policy" => 0.58, "ping" => 0.50, "update_entry" => 0.25, "query_tags" => 0.083,
|
352
|
-
"get_decommission_bundle" => 0.083, "list_queues" => 0.083}).should ==
|
353
|
-
[["list_queues", 0.083], ["query_tags", 0.083], ["get_decommission_bundle", 0.083],
|
354
|
-
["update_entry", 0.25], ["ping", 0.5], ["get_login_policy", 0.58], ["remove", 0.66],
|
355
|
-
["delete_queues", 0.75], ["soft_decommission", 0.75], ["update_inputs", 0.75],
|
356
|
-
["schedule_decommission", 0.91], ["update_login_policy", 1.3], ["get_repositories", 1.4],
|
357
|
-
["get_boot_bundle", 1.4], ["add_user", 2.4], ["append_error", 3.0], ["update_tags", 3.2],
|
358
|
-
["list_agents", 3.7], ["update_status", 4.4],
|
359
|
-
["record", 4.7], ["append_output", 7.3], ["create_new_section", 8.5], ["append_info", 9.6],
|
360
|
-
["declare", 39.2]]
|
361
|
-
end
|
362
|
-
|
363
|
-
it "should wrap string by breaking it into lines at the specified separator" do
|
364
|
-
string = "Now is the time for all good men to come to the aid of their people."
|
365
|
-
result = wrap(string, 20, " ", " ")
|
366
|
-
result.should == "Now is the time for \n" +
|
367
|
-
" all good men to come \n" +
|
368
|
-
" to the aid of their \n" +
|
369
|
-
" people."
|
370
|
-
string = "dogs: 2, cats: 10, hippopotami: 99, bears: 1, ants: 100000"
|
371
|
-
result = wrap(string, 22, "--", ", ")
|
372
|
-
result.should == "dogs: 2, cats: 10, \n" +
|
373
|
-
"--hippopotami: 99, \n" +
|
374
|
-
"--bears: 1, ants: 100000"
|
375
|
-
end
|
376
|
-
|
377
|
-
it "should convert elapsed time to displayable format" do
|
378
|
-
elapsed(0).should == "0 sec"
|
379
|
-
elapsed(1).should == "1 sec"
|
380
|
-
elapsed(60).should == "60 sec"
|
381
|
-
elapsed(61).should == "1 min 1 sec"
|
382
|
-
elapsed(62).should == "1 min 2 sec"
|
383
|
-
elapsed(120).should == "2 min 0 sec"
|
384
|
-
elapsed(3600).should == "60 min 0 sec"
|
385
|
-
elapsed(3601).should == "1 hr 0 min"
|
386
|
-
elapsed(3659).should == "1 hr 0 min"
|
387
|
-
elapsed(3660).should == "1 hr 1 min"
|
388
|
-
elapsed(3720).should == "1 hr 2 min"
|
389
|
-
elapsed(7200).should == "2 hr 0 min"
|
390
|
-
elapsed(7260).should == "2 hr 1 min"
|
391
|
-
elapsed(86400).should == "24 hr 0 min"
|
392
|
-
elapsed(86401).should == "1 day 0 hr 0 min"
|
393
|
-
elapsed(86459).should == "1 day 0 hr 0 min"
|
394
|
-
elapsed(86460).should == "1 day 0 hr 1 min"
|
395
|
-
elapsed(90000).should == "1 day 1 hr 0 min"
|
396
|
-
elapsed(183546).should == "2 days 2 hr 59 min"
|
397
|
-
elapsed(125.5).should == "2 min 5 sec"
|
398
|
-
end
|
399
|
-
|
400
|
-
it "should convert floating point values to decimal digit string with at least two digit precision" do
|
401
|
-
enough_precision(100.5).should == "101"
|
402
|
-
enough_precision(100.4).should == "100"
|
403
|
-
enough_precision(99.0).should == "99"
|
404
|
-
enough_precision(10.5).should == "11"
|
405
|
-
enough_precision(10.4).should == "10"
|
406
|
-
enough_precision(9.15).should == "9.2"
|
407
|
-
enough_precision(9.1).should == "9.1"
|
408
|
-
enough_precision(1.05).should == "1.1"
|
409
|
-
enough_precision(1.01).should == "1.0"
|
410
|
-
enough_precision(1.0).should == "1.0"
|
411
|
-
enough_precision(0.995).should == "1.00"
|
412
|
-
enough_precision(0.991).should == "0.99"
|
413
|
-
enough_precision(0.0995).should == "0.100"
|
414
|
-
enough_precision(0.0991).should == "0.099"
|
415
|
-
enough_precision(0.00995).should == "0.0100"
|
416
|
-
enough_precision(0.00991).should == "0.0099"
|
417
|
-
enough_precision(0.000995).should == "0.00100"
|
418
|
-
enough_precision(0.000991).should == "0.00099"
|
419
|
-
enough_precision(0.000005).should == "0.00001"
|
420
|
-
enough_precision(0.000001).should == "0.00000"
|
421
|
-
enough_precision(0.0).should == "0"
|
422
|
-
enough_precision(55).should == "55"
|
423
|
-
enough_precision({"a" => 65.0, "b" => 23.0, "c" => 12.0}).should == {"a" => "65", "b" => "23", "c" => "12"}
|
424
|
-
enough_precision({"a" => 65.0, "b" => 33.0, "c" => 2.0}).should == {"a" => "65.0", "b" => "33.0", "c" => "2.0"}
|
425
|
-
enough_precision({"a" => 10.45, "b" => 1.0, "c" => 0.011}).should == {"a" => "10.5", "b" => "1.0", "c" => "0.011"}
|
426
|
-
enough_precision({"a" => 1000.0, "b" => 0.1, "c" => 0.0, "d" => 0.0001, "e" => 0.00001, "f" => 0.000001}).should ==
|
427
|
-
{"a" => "1000.0", "b" => "0.10", "c" => "0.0", "d" => "0.00010", "e" => "0.00001", "f" => "0.00000"}
|
428
|
-
enough_precision([["a", 65.0], ["b", 23.0], ["c", 12.0]]).should == [["a", "65"], ["b", "23"], ["c", "12"]]
|
429
|
-
enough_precision([["a", 65.0], ["b", 33.0], ["c", 2.0]]).should == [["a", "65.0"], ["b", "33.0"], ["c", "2.0"]]
|
430
|
-
enough_precision([["a", 10.45], ["b", 1.0], ["c", 0.011]]).should == [["a", "10.5"], ["b", "1.0"], ["c", "0.011"]]
|
431
|
-
enough_precision([["a", 1000.0], ["b", 0.1], ["c", 0.0], ["d", 0.0001], ["e", 0.00001], ["f", 0.000001]]).should ==
|
432
|
-
[["a", "1000.0"], ["b", "0.10"], ["c", "0.0"], ["d", "0.00010"], ["e", "0.00001"], ["f", "0.00000"]]
|
433
|
-
end
|
434
|
-
|
435
|
-
it "should convert broker status to multi-line display string" do
|
436
|
-
result = brokers_str(@brokers, 10)
|
437
|
-
result.should == "brokers : b0: rs-broker-localhost-5672 connected, disconnects: none, failures: none\n" +
|
438
|
-
" b1: rs-broker-localhost-5673 disconnected, disconnects: 2 (16 min 40 sec ago), failures: none\n" +
|
439
|
-
" b2: rs-broker-localhost-5674 failed, disconnects: none, failures: 3 (16 min 40 sec ago w/ 2 retries)\n" +
|
440
|
-
" exceptions : none\n" +
|
441
|
-
" heartbeat : none\n" +
|
442
|
-
" returns : none\n"
|
443
|
-
end
|
444
|
-
|
445
|
-
it "should display broker exceptions and returns" do
|
446
|
-
@exceptions.track("testing", Exception.new("Test error"))
|
447
|
-
@brokers["exceptions"] = @exceptions.stats
|
448
|
-
@brokers["heartbeat"] = 60
|
449
|
-
activity = RightScale::StatsHelper::ActivityStats.new
|
450
|
-
activity.update("no queue")
|
451
|
-
activity.finish(@now - 10)
|
452
|
-
activity.update("no queue consumers")
|
453
|
-
activity.update("no queue consumers")
|
454
|
-
flexmock(Time).should_receive(:now).and_return(1000010)
|
455
|
-
@brokers["returns"] = activity.all
|
456
|
-
result = brokers_str(@brokers, 10)
|
457
|
-
result.should == "brokers : b0: rs-broker-localhost-5672 connected, disconnects: none, failures: none\n" +
|
458
|
-
" b1: rs-broker-localhost-5673 disconnected, disconnects: 2 (16 min 40 sec ago), failures: none\n" +
|
459
|
-
" b2: rs-broker-localhost-5674 failed, disconnects: none, failures: 3 (16 min 40 sec ago w/ 2 retries)\n" +
|
460
|
-
" exceptions : testing total: 1, most recent:\n" +
|
461
|
-
" (1) Mon Jan 12 05:46:40 Exception: Test error\n" +
|
462
|
-
" \n" +
|
463
|
-
" heartbeat : 60 sec\n" +
|
464
|
-
" returns : no queue consumers: 67%, no queue: 33%, total: 3, \n" +
|
465
|
-
" last: no queue consumers (10 sec ago), rate: 0/sec\n"
|
466
|
-
end
|
467
|
-
|
468
|
-
it 'should convert activity stats to string' do
|
469
|
-
activity = RightScale::StatsHelper::ActivityStats.new
|
470
|
-
activity.update("testing")
|
471
|
-
activity.finish(@now - 10)
|
472
|
-
activity.update("more testing")
|
473
|
-
activity.update("more testing")
|
474
|
-
activity.update("more testing")
|
475
|
-
flexmock(Time).should_receive(:now).and_return(1000010)
|
476
|
-
activity_str(activity.all).should == "more testing: 75%, testing: 25%, total: 4, last: more testing (10 sec ago), " +
|
477
|
-
"rate: 0/sec"
|
478
|
-
end
|
479
|
-
|
480
|
-
it 'should convert last activity stats to string' do
|
481
|
-
activity = RightScale::StatsHelper::ActivityStats.new
|
482
|
-
activity.update("testing")
|
483
|
-
activity.finish(@now - 10)
|
484
|
-
activity.update("more testing")
|
485
|
-
flexmock(Time).should_receive(:now).and_return(1000010)
|
486
|
-
last_activity_str(activity.last).should == "more testing: 10 sec ago"
|
487
|
-
last_activity_str(activity.last, single_item = true).should == "more testing (10 sec ago)"
|
488
|
-
end
|
489
|
-
|
490
|
-
it "should convert exception stats to multi-line string" do
|
491
|
-
@exceptions.track("testing", Exception.new("This is a very long exception message that should be truncated " +
|
492
|
-
"to a reasonable length"))
|
493
|
-
flexmock(Time).should_receive(:now).and_return(1000010)
|
494
|
-
category = "another"
|
495
|
-
backtrace = ["It happened here", "Over there"]
|
496
|
-
4.times do |i|
|
497
|
-
begin
|
498
|
-
raise ArgumentError, "badarg"
|
499
|
-
rescue Exception => e
|
500
|
-
flexmock(e).should_receive(:backtrace).and_return(backtrace)
|
501
|
-
@exceptions.track(category, e)
|
502
|
-
backtrace.shift(1) if i == 1
|
503
|
-
category = "testing" if i == 2
|
504
|
-
end
|
505
|
-
end
|
506
|
-
|
507
|
-
result = exceptions_str(@exceptions.stats, "----")
|
508
|
-
result.should == "another total: 3, most recent:\n" +
|
509
|
-
"----(1) Mon Jan 12 05:46:50 ArgumentError: badarg\n" +
|
510
|
-
"---- Over there\n" +
|
511
|
-
"----(2) Mon Jan 12 05:46:50 ArgumentError: badarg\n" +
|
512
|
-
"---- It happened here\n" +
|
513
|
-
"----testing total: 2, most recent:\n" +
|
514
|
-
"----(1) Mon Jan 12 05:46:50 ArgumentError: badarg\n" +
|
515
|
-
"---- Over there\n" +
|
516
|
-
"----(1) Mon Jan 12 05:46:40 Exception: This is a very long exception message that should be trun...\n" +
|
517
|
-
"---- "
|
518
|
-
end
|
519
|
-
|
520
|
-
it "should convert nested hash into string with keys sorted numerically if possible, else alphabetically" do
|
521
|
-
hash = {"dogs" => 2, "cats" => 3, "hippopotami" => 99, "bears" => 1, "ants" => 100000000, "dragons" => nil,
|
522
|
-
"food" => {"apples" => "bushels", "berries" => "lots", "meat" => {"fish" => 10.54, "beef" => nil}},
|
523
|
-
"versions" => { "1" => 10, "5" => 50, "10" => 100} }
|
524
|
-
result = hash_str(hash)
|
525
|
-
result.should == "ants: 100000000, bears: 1, cats: 3, dogs: 2, dragons: none, " +
|
526
|
-
"food: [ apples: bushels, berries: lots, meat: [ beef: none, fish: 11 ] ], " +
|
527
|
-
"hippopotami: 99, versions: [ 1: 10, 5: 50, 10: 100 ]"
|
528
|
-
result = wrap(result, 20, "----", ", ")
|
529
|
-
result.should == "ants: 100000000, \n" +
|
530
|
-
"----bears: 1, cats: 3, \n" +
|
531
|
-
"----dogs: 2, \n" +
|
532
|
-
"----dragons: none, \n" +
|
533
|
-
"----food: [ apples: bushels, \n" +
|
534
|
-
"----berries: lots, \n" +
|
535
|
-
"----meat: [ beef: none, \n" +
|
536
|
-
"----fish: 11 ] ], \n" +
|
537
|
-
"----hippopotami: 99, \n" +
|
538
|
-
"----versions: [ 1: 10, \n" +
|
539
|
-
"----5: 50, 10: 100 ]"
|
540
|
-
end
|
541
|
-
|
542
|
-
it "should convert sub-stats to a display string" do
|
543
|
-
@exceptions.track("testing", Exception.new("Test error"))
|
544
|
-
activity1 = RightScale::StatsHelper::ActivityStats.new
|
545
|
-
activity2 = RightScale::StatsHelper::ActivityStats.new
|
546
|
-
activity3 = RightScale::StatsHelper::ActivityStats.new
|
547
|
-
activity2.update("stats")
|
548
|
-
activity2.update("testing")
|
549
|
-
activity2.update("more testing")
|
550
|
-
activity2.update("more testing")
|
551
|
-
activity2.update("more testing")
|
552
|
-
activity3.update("testing forever", "id")
|
553
|
-
flexmock(Time).should_receive(:now).and_return(1002800)
|
554
|
-
|
555
|
-
stats = {"exceptions" => @exceptions.stats,
|
556
|
-
"empty_hash" => {},
|
557
|
-
"float_value" => 3.15,
|
558
|
-
"some % percent" => 3.54,
|
559
|
-
"some time" => 0.675,
|
560
|
-
"some rate" => 4.72,
|
561
|
-
"some age" => 125,
|
562
|
-
"activity1 %" => activity1.percentage,
|
563
|
-
"activity1 last" => activity1.last,
|
564
|
-
"activity2 %" => activity2.percentage,
|
565
|
-
"activity2 last" => activity2.last,
|
566
|
-
"activity3 last" => activity3.last,
|
567
|
-
"some hash" => {"dogs" => 2, "cats" => 3, "hippopotami" => 99, "bears" => 1,
|
568
|
-
"ants" => 100000000, "dragons" => nil, "leopards" => 25}}
|
569
|
-
|
570
|
-
result = sub_stats_str("my sub-stats", stats, 13)
|
571
|
-
result.should == "my sub-stats : activity1 % : none\n" +
|
572
|
-
" activity1 last : none\n" +
|
573
|
-
" activity2 % : more testing: 75%, testing: 25%, total: 4\n" +
|
574
|
-
" activity2 last : more testing: 46 min 40 sec ago\n" +
|
575
|
-
" activity3 last : testing forever: 46 min 40 sec ago and still active\n" +
|
576
|
-
" empty_hash : none\n" +
|
577
|
-
" exceptions : testing total: 1, most recent:\n" +
|
578
|
-
" (1) Mon Jan 12 05:46:40 Exception: Test error\n" +
|
579
|
-
" \n" +
|
580
|
-
" float_value : 3.2\n" +
|
581
|
-
" some % : 3.5%\n" +
|
582
|
-
" some age : 2 min 5 sec\n" +
|
583
|
-
" some hash : ants: 100000000, bears: 1, cats: 3, dogs: 2, dragons: none, hippopotami: 99, \n" +
|
584
|
-
" leopards: 25\n" +
|
585
|
-
" some rate : 4.7/sec\n" +
|
586
|
-
" some time : 0.68 sec\n"
|
587
|
-
end
|
588
|
-
|
589
|
-
it "should convert stats to a display string with special formatting for generic keys" do
|
590
|
-
@exceptions.track("testing", Exception.new("Test error"))
|
591
|
-
activity = RightScale::StatsHelper::ActivityStats.new
|
592
|
-
activity.update("testing")
|
593
|
-
flexmock(Time).should_receive(:now).and_return(1000010)
|
594
|
-
sub_stats = {"exceptions" => @exceptions.stats,
|
595
|
-
"empty_hash" => {},
|
596
|
-
"float_value" => 3.15,
|
597
|
-
"activity %" => activity.percentage,
|
598
|
-
"activity last" => activity.last,
|
599
|
-
"some hash" => {"dogs" => 2, "cats" => 3, "hippopotami" => 99, "bears" => 1,
|
600
|
-
"ants" => 100000000, "dragons" => nil, "leopards" => 25}}
|
601
|
-
stats = {"stat time" => @now,
|
602
|
-
"last reset time" => @now,
|
603
|
-
"service uptime" => 3720,
|
604
|
-
"machine uptime" => 183546,
|
605
|
-
"version" => 10,
|
606
|
-
"brokers" => @brokers,
|
607
|
-
"hostname" => "localhost",
|
608
|
-
"identity" => "unit tester",
|
609
|
-
"stuff stats" => sub_stats}
|
610
|
-
|
611
|
-
result = stats_str(stats)
|
612
|
-
result.should == "identity : unit tester\n" +
|
613
|
-
"hostname : localhost\n" +
|
614
|
-
"stat time : Mon Jan 12 05:46:40\n" +
|
615
|
-
"last reset : Mon Jan 12 05:46:40\n" +
|
616
|
-
"service up : 1 hr 2 min\n" +
|
617
|
-
"machine up : 2 days 2 hr 59 min\n" +
|
618
|
-
"version : 10\n" +
|
619
|
-
"brokers : b0: rs-broker-localhost-5672 connected, disconnects: none, failures: none\n" +
|
620
|
-
" b1: rs-broker-localhost-5673 disconnected, disconnects: 2 (16 min 40 sec ago), failures: none\n" +
|
621
|
-
" b2: rs-broker-localhost-5674 failed, disconnects: none, failures: 3 (16 min 40 sec ago w/ 2 retries)\n" +
|
622
|
-
" exceptions : none\n" +
|
623
|
-
" heartbeat : none\n" +
|
624
|
-
" returns : none\n" +
|
625
|
-
"stuff : activity % : testing: 100%, total: 1\n" +
|
626
|
-
" activity last : testing: 10 sec ago\n" +
|
627
|
-
" empty_hash : none\n" +
|
628
|
-
" exceptions : testing total: 1, most recent:\n" +
|
629
|
-
" (1) Mon Jan 12 05:46:40 Exception: Test error\n" +
|
630
|
-
" \n" +
|
631
|
-
" float_value : 3.2\n" +
|
632
|
-
" some hash : ants: 100000000, bears: 1, cats: 3, dogs: 2, dragons: none, hippopotami: 99, \n" +
|
633
|
-
" leopards: 25\n"
|
634
|
-
end
|
635
|
-
|
636
|
-
it "should treat broker status, version, and machine uptime as optional" do
|
637
|
-
sub_stats = {"exceptions" => @exceptions.stats,
|
638
|
-
"empty_hash" => {},
|
639
|
-
"float_value" => 3.15}
|
640
|
-
|
641
|
-
stats = {"stat time" => @now,
|
642
|
-
"last reset time" => @now,
|
643
|
-
"service uptime" => 1000,
|
644
|
-
"hostname" => "localhost",
|
645
|
-
"identity" => "unit tester",
|
646
|
-
"stuff stats" => sub_stats}
|
647
|
-
|
648
|
-
result = stats_str(stats)
|
649
|
-
result.should == "identity : unit tester\n" +
|
650
|
-
"hostname : localhost\n" +
|
651
|
-
"stat time : Mon Jan 12 05:46:40\n" +
|
652
|
-
"last reset : Mon Jan 12 05:46:40\n" +
|
653
|
-
"service up : 16 min 40 sec\n" +
|
654
|
-
"stuff : empty_hash : none\n" +
|
655
|
-
" exceptions : none\n" +
|
656
|
-
" float_value : 3.2\n"
|
657
|
-
end
|
658
|
-
|
659
|
-
it "should display name if provided" do
|
660
|
-
sub_stats = {"exceptions" => @exceptions.stats,
|
661
|
-
"empty_hash" => {},
|
662
|
-
"float_value" => 3.15}
|
663
|
-
|
664
|
-
stats = {"stat time" => @now,
|
665
|
-
"last reset time" => @now,
|
666
|
-
"service uptime" => 1000,
|
667
|
-
"hostname" => "localhost",
|
668
|
-
"identity" => "unit tester",
|
669
|
-
"name" => "tester_1",
|
670
|
-
"stuff stats" => sub_stats}
|
671
|
-
|
672
|
-
result = stats_str(stats)
|
673
|
-
result.should == "name : tester_1\n" +
|
674
|
-
"identity : unit tester\n" +
|
675
|
-
"hostname : localhost\n" +
|
676
|
-
"stat time : Mon Jan 12 05:46:40\n" +
|
677
|
-
"last reset : Mon Jan 12 05:46:40\n" +
|
678
|
-
"service up : 16 min 40 sec\n" +
|
679
|
-
"stuff : empty_hash : none\n" +
|
680
|
-
" exceptions : none\n" +
|
681
|
-
" float_value : 3.2\n"
|
682
|
-
end
|
683
|
-
|
684
|
-
end # Formatting
|
685
|
-
|
686
|
-
end # RightScale::StatsHelper
|