right_support 2.6.17 → 2.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (83) hide show
  1. data/.rspec +4 -0
  2. data/CHANGELOG.rdoc +37 -0
  3. data/Gemfile +29 -0
  4. data/Gemfile.lock +111 -0
  5. data/README.rdoc +2 -0
  6. data/Rakefile +62 -0
  7. data/VERSION +1 -0
  8. data/features/balancer_error_handling.feature +34 -0
  9. data/features/balancer_health_check.feature +33 -0
  10. data/features/continuous_integration.feature +51 -0
  11. data/features/continuous_integration_cucumber.feature +28 -0
  12. data/features/continuous_integration_rspec1.feature +28 -0
  13. data/features/continuous_integration_rspec2.feature +28 -0
  14. data/features/http_client_timeout.feature +19 -0
  15. data/features/serialization.feature +95 -0
  16. data/features/step_definitions/http_client_steps.rb +27 -0
  17. data/features/step_definitions/request_balancer_steps.rb +93 -0
  18. data/features/step_definitions/ruby_steps.rb +176 -0
  19. data/features/step_definitions/serialization_steps.rb +96 -0
  20. data/features/step_definitions/server_steps.rb +134 -0
  21. data/features/support/env.rb +138 -0
  22. data/features/support/file_utils_bundler_mixin.rb +45 -0
  23. data/lib/right_support/ci/java_cucumber_formatter.rb +22 -8
  24. data/lib/right_support/ci/java_spec_formatter.rb +26 -8
  25. data/lib/right_support/ci/rake_task.rb +3 -0
  26. data/lib/right_support/ci.rb +24 -0
  27. data/lib/right_support/crypto/signed_hash.rb +22 -0
  28. data/lib/right_support/data/serializer.rb +24 -2
  29. data/lib/right_support/net/address_helper.rb +20 -8
  30. data/lib/right_support/net/dns.rb +20 -8
  31. data/lib/right_support/net/http_client.rb +22 -0
  32. data/lib/right_support/net/request_balancer.rb +27 -21
  33. data/lib/right_support/net/s3_helper.rb +20 -8
  34. data/lib/right_support/net/ssl/open_ssl_patch.rb +22 -0
  35. data/lib/right_support/net/ssl.rb +20 -8
  36. data/lib/right_support/ruby/easy_singleton.rb +22 -0
  37. data/lib/right_support/ruby/object_extensions.rb +22 -0
  38. data/lib/right_support/ruby/string_extensions.rb +1 -1
  39. data/lib/right_support.rb +13 -10
  40. data/right_support.gemspec +180 -18
  41. data/right_support.rconf +8 -0
  42. data/spec/config/feature_set_spec.rb +83 -0
  43. data/spec/crypto/signed_hash_spec.rb +60 -0
  44. data/spec/data/hash_tools_spec.rb +471 -0
  45. data/spec/data/uuid_spec.rb +45 -0
  46. data/spec/db/cassandra_model_part1_spec.rb +84 -0
  47. data/spec/db/cassandra_model_part2_spec.rb +73 -0
  48. data/spec/db/cassandra_model_spec.rb +359 -0
  49. data/spec/fixtures/encrypted_priv_rsa.pem +30 -0
  50. data/spec/fixtures/good_priv_dsa.pem +12 -0
  51. data/spec/fixtures/good_priv_rsa.pem +15 -0
  52. data/spec/fixtures/good_pub_dsa.ssh +1 -0
  53. data/spec/fixtures/good_pub_rsa.pem +5 -0
  54. data/spec/fixtures/good_pub_rsa.ssh +1 -0
  55. data/spec/log/exception_logger_spec.rb +76 -0
  56. data/spec/log/filter_logger_spec.rb +8 -0
  57. data/spec/log/mixin_spec.rb +62 -0
  58. data/spec/log/multiplexer_spec.rb +54 -0
  59. data/spec/log/null_logger_spec.rb +36 -0
  60. data/spec/log/system_logger_spec.rb +92 -0
  61. data/spec/net/address_helper_spec.rb +57 -0
  62. data/spec/net/balancing/health_check_spec.rb +382 -0
  63. data/spec/net/balancing/round_robin_spec.rb +15 -0
  64. data/spec/net/balancing/sticky_policy_spec.rb +92 -0
  65. data/spec/net/dns_spec.rb +152 -0
  66. data/spec/net/http_client_spec.rb +171 -0
  67. data/spec/net/request_balancer_spec.rb +579 -0
  68. data/spec/net/s3_helper_spec.rb +160 -0
  69. data/spec/net/ssl_spec.rb +42 -0
  70. data/spec/net/string_encoder_spec.rb +58 -0
  71. data/spec/rack/log_setter_spec.rb +5 -0
  72. data/spec/rack/request_logger_spec.rb +68 -0
  73. data/spec/rack/request_tracker_spec.rb +5 -0
  74. data/spec/ruby/easy_singleton_spec.rb +72 -0
  75. data/spec/ruby/object_extensions_spec.rb +27 -0
  76. data/spec/ruby/string_extensions_spec.rb +98 -0
  77. data/spec/spec_helper.rb +181 -0
  78. data/spec/stats/activity_spec.rb +193 -0
  79. data/spec/stats/exceptions_spec.rb +123 -0
  80. data/spec/stats/helpers_spec.rb +603 -0
  81. data/spec/validation/openssl_spec.rb +37 -0
  82. data/spec/validation/ssh_spec.rb +39 -0
  83. metadata +218 -19
@@ -0,0 +1,603 @@
1
+ #
2
+ # Copyright (c) 2009-2012 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 RightSupport::Stats do
26
+
27
+ include FlexMock::ArgumentTypes
28
+
29
+ before(:all) do
30
+ @helpers = RightSupport::Stats
31
+ @original_recent_size = RightSupport::Stats::Activity::RECENT_SIZE
32
+ RightSupport::Stats::Activity.const_set(:RECENT_SIZE, 10)
33
+ end
34
+
35
+ after(:all) do
36
+ RightSupport::Stats::Activity.const_set(:RECENT_SIZE, @original_recent_size)
37
+ end
38
+
39
+ before(:each) do
40
+ @hr = sprintf("%02d", 13 + (Time.now.utc_offset / 3600) + (Time.now.dst? ? -1 : 0))
41
+ @now = 1000000
42
+ flexmock(Time).should_receive(:now).and_return(@now).by_default
43
+ @exceptions = RightSupport::Stats::Exceptions.new
44
+ @brokers = {"brokers"=> [{"alias" => "b0", "identity" => "rs-broker-localhost-5672", "status" => "connected",
45
+ "disconnect last" => nil,"disconnects" => nil, "failure last" => nil, "failures" => nil,
46
+ "retries" => nil},
47
+ {"alias" => "b1", "identity" => "rs-broker-localhost-5673", "status" => "disconnected",
48
+ "disconnect last" => {"elapsed" => 1000}, "disconnects" => 2,
49
+ "failure last" => nil, "failures" => nil, "retries" => nil},
50
+ {"alias" => "b2", "identity" => "rs-broker-localhost-5674", "status" => "failed",
51
+ "disconnect last" => nil, "disconnects" => nil,
52
+ "failure last" => {"elapsed" => 1000}, "failures" => 3, "retries" => 2}],
53
+ "heartbeat" => nil,
54
+ "exceptions" => {}}
55
+ end
56
+
57
+ context "percentage" do
58
+ it "converts values to percentages" do
59
+ stats = {"first" => 1, "second" => 4, "third" => 3}
60
+ result = @helpers.percentage(stats)
61
+ result.should == {"total" => 8, "percent" => {"first" => 12.5, "second" => 50.0, "third" => 37.5}}
62
+ end
63
+ end
64
+
65
+ context "nil_if_zero" do
66
+ it "converts 0 to nil" do
67
+ @helpers.nil_if_zero(0).should be_nil
68
+ @helpers.nil_if_zero(0.0).should be_nil
69
+ @helpers.nil_if_zero(1).should == 1
70
+ @helpers.nil_if_zero(1.0).should == 1.0
71
+ end
72
+ end
73
+
74
+ context "elapsed" do
75
+ it "converts elapsed time to displayable format" do
76
+ @helpers.elapsed(0).should == "0 sec"
77
+ @helpers.elapsed(1).should == "1 sec"
78
+ @helpers.elapsed(60).should == "60 sec"
79
+ @helpers.elapsed(61).should == "1 min 1 sec"
80
+ @helpers.elapsed(62).should == "1 min 2 sec"
81
+ @helpers.elapsed(120).should == "2 min 0 sec"
82
+ @helpers.elapsed(3600).should == "60 min 0 sec"
83
+ @helpers.elapsed(3601).should == "1 hr 0 min"
84
+ @helpers.elapsed(3659).should == "1 hr 0 min"
85
+ @helpers.elapsed(3660).should == "1 hr 1 min"
86
+ @helpers.elapsed(3720).should == "1 hr 2 min"
87
+ @helpers.elapsed(7200).should == "2 hr 0 min"
88
+ @helpers.elapsed(7260).should == "2 hr 1 min"
89
+ @helpers.elapsed(86400).should == "24 hr 0 min"
90
+ @helpers.elapsed(86401).should == "1 day 0 hr 0 min"
91
+ @helpers.elapsed(86459).should == "1 day 0 hr 0 min"
92
+ @helpers.elapsed(86460).should == "1 day 0 hr 1 min"
93
+ @helpers.elapsed(90000).should == "1 day 1 hr 0 min"
94
+ @helpers.elapsed(183546).should == "2 days 2 hr 59 min"
95
+ @helpers.elapsed(125.5).should == "2 min 5 sec"
96
+ end
97
+ end
98
+
99
+ context "enough_precision" do
100
+ it "converts floating point values to decimal digit string with at least two digit precision" do
101
+ @helpers.enough_precision(100.5).should == "101"
102
+ @helpers.enough_precision(-100.5).should == "-101"
103
+ @helpers.enough_precision(100.4).should == "100"
104
+ @helpers.enough_precision(-100.4).should == "-100"
105
+ @helpers.enough_precision(99.0).should == "99"
106
+ @helpers.enough_precision(-99.0).should == "-99"
107
+ @helpers.enough_precision(10.5).should == "11"
108
+ @helpers.enough_precision(-10.5).should == "-11"
109
+ @helpers.enough_precision(10.4).should == "10"
110
+ @helpers.enough_precision(-10.4).should == "-10"
111
+ @helpers.enough_precision(9.15).should == "9.2"
112
+ @helpers.enough_precision(-9.15).should == "-9.2"
113
+ @helpers.enough_precision(9.1).should == "9.1"
114
+ @helpers.enough_precision(-9.1).should == "-9.1"
115
+ @helpers.enough_precision(1.05).should == "1.1"
116
+ @helpers.enough_precision(-1.05).should == "-1.1"
117
+ @helpers.enough_precision(1.01).should == "1.0"
118
+ @helpers.enough_precision(-1.01).should == "-1.0"
119
+ @helpers.enough_precision(1.0).should == "1.0"
120
+ @helpers.enough_precision(-1.0).should == "-1.0"
121
+ @helpers.enough_precision(0.995).should == "1.00"
122
+ @helpers.enough_precision(-0.995).should == "-1.00"
123
+ @helpers.enough_precision(0.991).should == "0.99"
124
+ @helpers.enough_precision(-0.991).should == "-0.99"
125
+ @helpers.enough_precision(0.0995).should == "0.100"
126
+ @helpers.enough_precision(-0.0995).should == "-0.100"
127
+ @helpers.enough_precision(0.0991).should == "0.099"
128
+ @helpers.enough_precision(-0.0991).should == "-0.099"
129
+ @helpers.enough_precision(0.00995).should == "0.0100"
130
+ @helpers.enough_precision(-0.00995).should == "-0.0100"
131
+ @helpers.enough_precision(0.00991).should == "0.0099"
132
+ @helpers.enough_precision(-0.00991).should == "-0.0099"
133
+ @helpers.enough_precision(0.000995).should == "0.00100"
134
+ @helpers.enough_precision(-0.000995).should == "-0.00100"
135
+ @helpers.enough_precision(0.000991).should == "0.00099"
136
+ @helpers.enough_precision(-0.000991).should == "-0.00099"
137
+ @helpers.enough_precision(0.0000995).should == "0.000100"
138
+ @helpers.enough_precision(-0.0000995).should == "-0.000100"
139
+ @helpers.enough_precision(0.0000991).should == "0.000099"
140
+ @helpers.enough_precision(-0.0000991).should == "-0.000099"
141
+ @helpers.enough_precision(0.0000005).should == "0.000001"
142
+ @helpers.enough_precision(-0.0000005).should == "-0.000001"
143
+ @helpers.enough_precision(0.0000001).should == "0"
144
+ @helpers.enough_precision(-0.0000001).should == "0"
145
+ @helpers.enough_precision(0.0).should == "0"
146
+ @helpers.enough_precision(55).should == "55"
147
+ @helpers.enough_precision(-55).should == "-55"
148
+ @helpers.enough_precision({"a" => 65.0, "b" => 23.0, "c" => 12.0}).should == {"a" => "65", "b" => "23", "c" => "12"}
149
+ @helpers.enough_precision({"a" => 65.0, "b" => 33.0, "c" => 2.0}).should == {"a" => "65.0", "b" => "33.0", "c" => "2.0"}
150
+ @helpers.enough_precision({"a" => 10.45, "b" => 1.0, "c" => 0.011}).should == {"a" => "10.5", "b" => "1.0", "c" => "0.011"}
151
+ @helpers.enough_precision({"a" => 1000.0, "b" => 0.1, "c" => 0.0, "d" => 0.0001, "e" => 0.00001, "f" => 0.0000001}).should ==
152
+ {"a" => "1000.0", "b" => "0.10", "c" => "0.0", "d" => "0.00010", "e" => "0.000010", "f" => "0.0"}
153
+ @helpers.enough_precision([["a", 65.0], ["b", 23.0], ["c", 12.0]]).should == [["a", "65"], ["b", "23"], ["c", "12"]]
154
+ @helpers.enough_precision([["a", 65.0], ["b", 33.0], ["c", 2.0]]).should == [["a", "65.0"], ["b", "33.0"], ["c", "2.0"]]
155
+ @helpers.enough_precision([["a", 10.45], ["b", 1.0], ["c", 0.011]]).should == [["a", "10.5"], ["b", "1.0"], ["c", "0.011"]]
156
+ @helpers.enough_precision([["a", 1000.0], ["b", 0.1], ["c", 0.0], ["d", 0.0001], ["e", 0.00001], ["f", 0.0000001]]).should ==
157
+ [["a", "1000.0"], ["b", "0.10"], ["c", "0.0"], ["d", "0.00010"], ["e", "0.000010"], ["f", "0.0"]]
158
+ end
159
+ end
160
+
161
+ context "wrap" do
162
+ it "wraps string by breaking it into lines at the specified separator" do
163
+ string = "Now is the time for all good men to come to the aid of their people."
164
+ indent = " " * 4
165
+ result = @helpers.wrap(string, 20, indent, / /)
166
+ result.should == "Now is the time for \n" +
167
+ " all good men to \n" +
168
+ " come to the aid \n" +
169
+ " of their people."
170
+ result.split("\n").select { |l| (l.chomp.size - indent.size) > 20 }.should be_empty
171
+
172
+ string = "dogs: 2, cats: 10, hippopotami: 99, bears: 1, ants: 100000"
173
+ indent = "--"
174
+ result = @helpers.wrap(string, 22, indent, /, /)
175
+ result.should == "dogs: 2, cats: 10, \n" +
176
+ "--hippopotami: 99, \n" +
177
+ "--bears: 1, \n" +
178
+ "--ants: 100000"
179
+ result.split("\n").select { |l| (l.chomp.size - indent.size) > 22 }.should be_empty
180
+ end
181
+
182
+ it "wraps string by breaking into lines while ignoring encoding for color when measuring length" do
183
+ string = "Now is the time for all good men to come to the aid of their people."
184
+ colors = [:red, :blue, :green]
185
+ c = 0
186
+ string = string.split(" ").map { |s| s.send(colors[c = (c + 1) % 3]) }.join(" ")
187
+ result = @helpers.wrap(string, 20, " " * 4, / /)
188
+ result.gsub(/\e\[[0-9]*m/, "").should == "Now is the time for \n" +
189
+ " all good men to \n" +
190
+ " come to the aid \n" +
191
+ " of their people."
192
+ end
193
+
194
+ it "wraps string by breaking into lines with multiple separators" do
195
+ string = "Failed receiving from queue request on b0 (RightScale::Serializer::SerializationError: Could not load " +
196
+ "packet using [RightScale::SecureSerializer] (Failed to load with RightScale::SecureSerializer " +
197
+ "(RightScale::SecureSerializer::InvalidSignature: Failed signature check for signer " +
198
+ "rs-instance-1368fe0b6d4663dc1c92c54e05a8c37b3bd66be7-207607183 in " +
199
+ "/home/rails/right_net/shared/bundle/ruby/1.9.1/bundler/gems/right_agent-aab761e02a9e/" +
200
+ "lib/right_agent/serialize/secure_serializer.rb:136:in `load')) IN /Users/leekirchhoff/" +
201
+ ".rightscale/right_net/ruby/1.8/bundler/gems/right_agent-4459d22fc542/lib/right_agent/" +
202
+ "serialize/serializer.rb:133:in `cascade_serializers')"
203
+ result = @helpers.wrap(string, 80, "", / |\/\/|\/|::|\.|-/)
204
+ result.should == "Failed receiving from queue request on b0 (RightScale::Serializer::\n" +
205
+ "SerializationError: Could not load packet using [RightScale::SecureSerializer] \n" +
206
+ "(Failed to load with RightScale::SecureSerializer (RightScale::\n" +
207
+ "SecureSerializer::InvalidSignature: Failed signature check for signer rs-\n" +
208
+ "instance-1368fe0b6d4663dc1c92c54e05a8c37b3bd66be7-207607183 in /home/rails/\n" +
209
+ "right_net/shared/bundle/ruby/1.9.1/bundler/gems/right_agent-aab761e02a9e/lib/\n" +
210
+ "right_agent/serialize/secure_serializer.rb:136:in `load')) IN /Users/\n" +
211
+ "leekirchhoff/.rightscale/right_net/ruby/1.8/bundler/gems/right_agent-\n" +
212
+ "4459d22fc542/lib/right_agent/serialize/serializer.rb:133:in \n" +
213
+ "`cascade_serializers')"
214
+ result.split("\n").select { |l| l.chomp.size > 80 }.should be_empty
215
+ end
216
+ end
217
+
218
+ context "sort_key" do
219
+ it "sorts hash by key into array with integer conversion of keys if possible" do
220
+ @helpers.sort_key({"c" => 3, "a" => 1, "b" => 2}).should == [["a", 1], ["b", 2], ["c", 3]]
221
+ @helpers.sort_key({3 => "c", 1 => "a", 2 => "b"}).should == [[1, "a"], [2, "b"], [3, "c"]]
222
+ @helpers.sort_key({11 => "c", 9 => "a", 10 => "b"}).should == [[9, "a"], [10, "b"], [11, "c"]]
223
+ @helpers.sort_key({"append_info" => 9.6, "create_new_section" => 8.5, "append_output" => 7.3, "record" => 4.7,
224
+ "update_status" => 4.4,
225
+ "declare" => 39.2, "list_agents" => 3.7, "update_tags" => 3.2, "append_error" => 3.0,
226
+ "add_user" => 2.4, "get_boot_bundle" => 1.4, "get_repositories" => 1.4,
227
+ "update_login_policy" => 1.3, "schedule_decommission" => 0.91, "update_inputs" => 0.75,
228
+ "delete_queues" => 0.75, "soft_decommission" => 0.75, "remove" => 0.66,
229
+ "get_login_policy" => 0.58, "ping" => 0.50, "update_entry" => 0.25, "query_tags" => 0.083,
230
+ "get_decommission_bundle" => 0.083, "list_queues" => 0.083}).should ==
231
+ [["add_user", 2.4], ["append_error", 3.0], ["append_info", 9.6], ["append_output", 7.3],
232
+ ["create_new_section", 8.5], ["declare", 39.2], ["delete_queues", 0.75], ["get_boot_bundle", 1.4],
233
+ ["get_decommission_bundle", 0.083], ["get_login_policy", 0.58], ["get_repositories", 1.4],
234
+ ["list_agents", 3.7], ["list_queues", 0.083], ["ping", 0.5], ["query_tags", 0.083],
235
+ ["record", 4.7], ["remove", 0.66], ["schedule_decommission", 0.91], ["soft_decommission", 0.75],
236
+ ["update_entry", 0.25], ["update_inputs", 0.75],
237
+ ["update_login_policy", 1.3], ["update_status", 4.4], ["update_tags", 3.2]]
238
+ end
239
+ end
240
+
241
+ context "sort_value" do
242
+ it "sorts hash by value into array" do
243
+ @helpers.sort_value({"c" => 3, "a" => 2, "b" => 1}).should == [["b", 1], ["a", 2], ["c", 3]]
244
+ @helpers.sort_value({"c" => 3.0, "a" => 2, "b" => 1.0}).should == [["b", 1.0], ["a", 2], ["c", 3.0]]
245
+ @helpers.sort_value({"append_info" => 9.6, "create_new_section" => 8.5, "append_output" => 7.3, "record" => 4.7,
246
+ "update_status" => 4.4,
247
+ "declare" => 39.2, "list_agents" => 3.7, "update_tags" => 3.2, "append_error" => 3.0,
248
+ "add_user" => 2.4, "get_boot_bundle" => 1.5, "get_repositories" => 1.4,
249
+ "update_login_policy" => 1.3, "schedule_decommission" => 0.91, "update_inputs" => 0.77,
250
+ "delete_queues" => 0.75, "soft_decommission" => 0.76, "remove" => 0.66,
251
+ "get_login_policy" => 0.58, "ping" => 0.50, "update_entry" => 0.25, "query_tags" => 0.082,
252
+ "get_decommission_bundle" => 0.083, "list_queues" => 0.081}).should ==
253
+ [["list_queues", 0.081], ["query_tags", 0.082], ["get_decommission_bundle", 0.083],
254
+ ["update_entry", 0.25], ["ping", 0.5], ["get_login_policy", 0.58], ["remove", 0.66],
255
+ ["delete_queues", 0.75], ["soft_decommission", 0.76], ["update_inputs", 0.77],
256
+ ["schedule_decommission", 0.91], ["update_login_policy", 1.3], ["get_repositories", 1.4],
257
+ ["get_boot_bundle", 1.5], ["add_user", 2.4], ["append_error", 3.0], ["update_tags", 3.2],
258
+ ["list_agents", 3.7], ["update_status", 4.4],
259
+ ["record", 4.7], ["append_output", 7.3], ["create_new_section", 8.5], ["append_info", 9.6],
260
+ ["declare", 39.2]]
261
+ end
262
+ end
263
+
264
+ context "service_up_str" do
265
+ it "converts service up stats to string when it is an integer" do
266
+ result = @helpers.service_up_str(75)
267
+ result.should == "1 min 15 sec"
268
+ end
269
+
270
+ it "converts service up stats to string when it is a hash" do
271
+ result = @helpers.service_up_str("uptime" => 75)
272
+ result.should == "1 min 15 sec"
273
+ end
274
+
275
+ it "converts service up stats to string that includes restarts" do
276
+ result = @helpers.service_up_str("uptime" => 75, "total_uptime" => 86401, "restarts" => 10, "graceful_exits" => 10)
277
+ result.should == "1 min 15 sec, restarts: 10 (up 1 day 0 hr 0 min total)"
278
+ end
279
+
280
+ it "converts service up stats to string that includes restarts and non-graceful exits" do
281
+ result = @helpers.service_up_str("uptime" => 75, "total_uptime" => 90061, "restarts" => 10, "graceful_exits" => 8)
282
+ result.should == "1 min 15 sec, restarts: 10 (2 non-graceful, up 1 day 1 hr 1 min total)"
283
+ end
284
+
285
+ it "converts service up stats to string that includes crashes" do
286
+ flexmock(Time).should_receive(:now).and_return(1000000)
287
+ result = @helpers.service_up_str("uptime" => 75, "total_uptime" => 90061, "crashes" => 1, "last_crash_time" => 996340)
288
+ result.should == "1 min 15 sec, crashes: 1 (last 1 hr 1 min ago)"
289
+ end
290
+
291
+ it "converts service up stats to string that includes restarts and crashes" do
292
+ flexmock(Time).should_receive(:now).and_return(1000000)
293
+ result = @helpers.service_up_str("uptime" => 75, "total_uptime" => 90061, "restarts" => 10, "graceful_exits" => 8,
294
+ "crashes" => 1, "last_crash_time" => 996340)
295
+ result.should == "1 min 15 sec, restarts: 10 (2 non-graceful, up 1 day 1 hr 1 min total), crashes: 1 (last 1 hr 1 min ago)"
296
+ end
297
+ end
298
+
299
+ context "brokers_str" do
300
+ it "converts broker status to multi-line display string" do
301
+ result = @helpers.brokers_str(@brokers, :name_width => 10)
302
+ result.should == "brokers : b0: rs-broker-localhost-5672 connected, disconnects: none, failures: none\n" +
303
+ " b1: rs-broker-localhost-5673 disconnected, disconnects: 2 (16 min 40 sec ago), failures: none\n" +
304
+ " b2: rs-broker-localhost-5674 failed, disconnects: none, failures: 3 (16 min 40 sec ago w/ 2 retries)\n" +
305
+ " exceptions : none\n" +
306
+ " heartbeat : none\n" +
307
+ " returns : none\n"
308
+ end
309
+
310
+ it "displays broker exceptions and returns" do
311
+ @exceptions.track("testing", Exception.new("Test error"))
312
+ @brokers["exceptions"] = @exceptions.stats
313
+ @brokers["heartbeat"] = 60
314
+ activity = RightSupport::Stats::Activity.new
315
+ activity.update("no queue")
316
+ activity.finish(@now - 10)
317
+ activity.update("no queue consumers")
318
+ activity.update("no queue consumers")
319
+ flexmock(Time).should_receive(:now).and_return(1000010)
320
+ @brokers["returns"] = activity.all
321
+ result = @helpers.brokers_str(@brokers, :name_width => 10)
322
+ result.should == "brokers : b0: rs-broker-localhost-5672 connected, disconnects: none, failures: none\n" +
323
+ " b1: rs-broker-localhost-5673 disconnected, disconnects: 2 (16 min 40 sec ago), failures: none\n" +
324
+ " b2: rs-broker-localhost-5674 failed, disconnects: none, failures: 3 (16 min 40 sec ago w/ 2 retries)\n" +
325
+ " exceptions : testing total: 1, most recent:\n" +
326
+ " (1) Mon Jan 12 #{@hr}:46:40 Exception: Test error\n" +
327
+ " heartbeat : 60 sec\n" +
328
+ " returns : no queue consumers: 67%, no queue: 33%, total: 3, \n" +
329
+ " last: no queue consumers (10 sec ago), rate: 0/sec\n"
330
+ end
331
+ end
332
+
333
+ context "activity_str" do
334
+ it 'converts activity stats to string' do
335
+ activity = RightSupport::Stats::Activity.new
336
+ activity.update("testing")
337
+ activity.finish(@now - 10)
338
+ activity.update("more testing")
339
+ activity.update("more testing")
340
+ activity.update("more testing")
341
+ flexmock(Time).should_receive(:now).and_return(1000010)
342
+ @helpers.activity_str(activity.all).should == "more testing: 75%, testing: 25%, total: 4, last: more testing (10 sec ago), " +
343
+ "rate: 0/sec"
344
+ end
345
+
346
+ it 'converts last activity stats to string' do
347
+ activity = RightSupport::Stats::Activity.new
348
+ activity.update("testing")
349
+ activity.finish(@now - 10)
350
+ activity.update("more testing")
351
+ flexmock(Time).should_receive(:now).and_return(1000010)
352
+ @helpers.last_activity_str(activity.last).should == "more testing: 10 sec ago"
353
+ @helpers.last_activity_str(activity.last, single_item = true).should == "more testing (10 sec ago)"
354
+ end
355
+ end
356
+
357
+ context "exceptions_str" do
358
+ it "converts exception stats to multi-line string" do
359
+ @exceptions.track("testing", Exception.new("This is a very long exception message that should be wrapped " +
360
+ "so that it stays within the maximum line length"))
361
+ flexmock(Time).should_receive(:now).and_return(1000010)
362
+ category = "another"
363
+ backtrace = ["It happened here", "Over there"]
364
+ 4.times do |i|
365
+ begin
366
+ raise ArgumentError, "badarg"
367
+ rescue Exception => e
368
+ flexmock(e).should_receive(:backtrace).and_return(backtrace)
369
+ @exceptions.track(category, e)
370
+ backtrace.shift(1) if i == 1
371
+ category = "testing" if i == 2
372
+ end
373
+ end
374
+
375
+ result = @helpers.exceptions_str(@exceptions.stats, "----")
376
+ result.should == "another total: 3, most recent:\n" +
377
+ "----(1) Mon Jan 12 #{@hr}:46:50 ArgumentError: badarg IN Over there\n" +
378
+ "----(2) Mon Jan 12 #{@hr}:46:50 ArgumentError: badarg IN It happened here\n" +
379
+ "----testing total: 2, most recent:\n" +
380
+ "----(1) Mon Jan 12 #{@hr}:46:50 ArgumentError: badarg IN Over there\n" +
381
+ "----(1) Mon Jan 12 #{@hr}:46:40 Exception: This is a very long exception message that \n" +
382
+ "---- should be wrapped so that it stays within the maximum line length"
383
+ end
384
+ end
385
+
386
+ context "hash_str" do
387
+ it "converts nested hash into string with keys sorted numerically if possible, else alphabetically" do
388
+ hash = {"dogs" => 2, "cats" => 3, "hippopotami" => 99, "bears" => 1, "ants" => 100000000, "dragons" => nil,
389
+ "food" => {"apples" => "bushels", "berries" => "lots", "meat" => {"fish" => 10.54, "beef" => nil}},
390
+ "versions" => { "1" => 10, "5" => 50, "10" => 100} }
391
+ result = @helpers.hash_str(hash)
392
+ result.should == "ants: 100000000, bears: 1, cats: 3, dogs: 2, dragons: none, " +
393
+ "food: [ apples: bushels, berries: lots, meat: [ beef: none, fish: 11 ] ], " +
394
+ "hippopotami: 99, versions: [ 1: 10, 5: 50, 10: 100 ]"
395
+ result = @helpers.wrap(result, 24, "----", /, /)
396
+ result.should == "ants: 100000000, \n" +
397
+ "----bears: 1, cats: 3, \n" +
398
+ "----dogs: 2, \n" +
399
+ "----dragons: none, \n" +
400
+ "----food: [ apples: bushels, \n" +
401
+ "----berries: lots, \n" +
402
+ "----meat: [ beef: none, \n" +
403
+ "----fish: 11 ] ], \n" +
404
+ "----hippopotami: 99, \n" +
405
+ "----versions: [ 1: 10, \n" +
406
+ "----5: 50, 10: 100 ]"
407
+ end
408
+ end
409
+
410
+ context "sub_stats_str" do
411
+ it "converts sub-stats to a display string" do
412
+ @exceptions.track("testing", Exception.new("Test error"))
413
+ activity1 = RightSupport::Stats::Activity.new
414
+ activity2 = RightSupport::Stats::Activity.new
415
+ activity3 = RightSupport::Stats::Activity.new
416
+ activity2.update("stats")
417
+ activity2.update("testing")
418
+ activity2.update("more testing")
419
+ activity2.update("more testing")
420
+ activity2.update("more testing")
421
+ activity3.update("testing forever", "id")
422
+ flexmock(Time).should_receive(:now).and_return(1002800)
423
+
424
+ stats = {"exceptions" => @exceptions.stats,
425
+ "empty_hash" => {},
426
+ "float_value" => 3.15,
427
+ "some % percent" => 3.54,
428
+ "some time" => 0.675,
429
+ "some rate" => 4.72,
430
+ "some age" => 125,
431
+ "activity1 %" => activity1.percentage,
432
+ "activity1 last" => activity1.last,
433
+ "activity2 %" => activity2.percentage,
434
+ "activity2 last" => activity2.last,
435
+ "activity3 last" => activity3.last,
436
+ "some hash" => {"dogs" => 2, "cats" => 3, "hippopotami" => 99, "bears" => 1,
437
+ "ants" => 100000000, "dragons" => nil, "leopards" => 25}}
438
+
439
+ result = @helpers.sub_stats_str("my sub-stats", stats, :name_width => 13, :sub_stat_value_width => 60)
440
+ result.should == "my sub-stats : activity1 % : none\n" +
441
+ " activity1 last : none\n" +
442
+ " activity2 % : more testing: 75%, testing: 25%, total: 4\n" +
443
+ " activity2 last : more testing: 46 min 40 sec ago\n" +
444
+ " activity3 last : testing forever: 46 min 40 sec ago and still active\n" +
445
+ " empty_hash : none\n" +
446
+ " exceptions : testing total: 1, most recent:\n" +
447
+ " (1) Mon Jan 12 #{@hr}:46:40 Exception: Test error\n" +
448
+ " float_value : 3.2\n" +
449
+ " some % : 3.5%\n" +
450
+ " some age : 2 min 5 sec\n" +
451
+ " some hash : ants: 100000000, bears: 1, cats: 3, dogs: 2, dragons: none, \n" +
452
+ " hippopotami: 99, leopards: 25\n" +
453
+ " some rate : 4.7/sec\n" +
454
+ " some time : 0.68 sec\n"
455
+ end
456
+ end
457
+
458
+ context "stats_str" do
459
+ it "converts stats to a display string with special formatting for generic keys" do
460
+ @exceptions.track("testing", Exception.new("Test error"))
461
+ activity = RightSupport::Stats::Activity.new
462
+ activity.update("testing")
463
+ flexmock(Time).should_receive(:now).and_return(1000010)
464
+ sub_stats = {"exceptions" => @exceptions.stats,
465
+ "empty_hash" => {},
466
+ "float_value" => 3.15,
467
+ "activity %" => activity.percentage,
468
+ "activity last" => activity.last,
469
+ "some hash" => {"dogs" => 2, "cats" => 3, "hippopotami" => 99, "bears" => 1,
470
+ "ants" => 100000000, "dragons" => nil, "leopards" => 25}}
471
+ stats = {"stat time" => @now,
472
+ "last reset time" => @now,
473
+ "service uptime" => 3720,
474
+ "machine uptime" => 183546,
475
+ "version" => 10,
476
+ "brokers" => @brokers,
477
+ "hostname" => "localhost",
478
+ "identity" => "unit tester",
479
+ "stuff stats" => sub_stats}
480
+
481
+ result = @helpers.stats_str(stats)
482
+ result.should == "identity : unit tester\n" +
483
+ "hostname : localhost\n" +
484
+ "stat time : Mon Jan 12 #{@hr}:46:40 1970\n" +
485
+ "last reset : Mon Jan 12 #{@hr}:46:40 1970\n" +
486
+ "service up : 1 hr 2 min\n" +
487
+ "machine up : 2 days 2 hr 59 min\n" +
488
+ "version : 10\n" +
489
+ "brokers : b0: rs-broker-localhost-5672 connected, disconnects: none, failures: none\n" +
490
+ " b1: rs-broker-localhost-5673 disconnected, disconnects: 2 (16 min 40 sec ago), failures: none\n" +
491
+ " b2: rs-broker-localhost-5674 failed, disconnects: none, failures: 3 (16 min 40 sec ago w/ 2 retries)\n" +
492
+ " exceptions : none\n" +
493
+ " heartbeat : none\n" +
494
+ " returns : none\n" +
495
+ "stuff : activity % : testing: 100%, total: 1\n" +
496
+ " activity last : testing: 10 sec ago\n" +
497
+ " empty_hash : none\n" +
498
+ " exceptions : testing total: 1, most recent:\n" +
499
+ " (1) Mon Jan 12 #{@hr}:46:40 Exception: Test error\n" +
500
+ " float_value : 3.2\n" +
501
+ " some hash : ants: 100000000, bears: 1, cats: 3, dogs: 2, dragons: none, hippopotami: 99, \n" +
502
+ " leopards: 25\n"
503
+ end
504
+
505
+ it "treats broker status, version, and machine uptime as optional" do
506
+ sub_stats = {"exceptions" => @exceptions.stats,
507
+ "empty_hash" => {},
508
+ "float_value" => 3.15}
509
+
510
+ stats = {"stat time" => @now,
511
+ "last reset time" => @now,
512
+ "service uptime" => 1000,
513
+ "hostname" => "localhost",
514
+ "identity" => "unit tester",
515
+ "stuff stats" => sub_stats}
516
+
517
+ result = @helpers.stats_str(stats)
518
+ result.should == "identity : unit tester\n" +
519
+ "hostname : localhost\n" +
520
+ "stat time : Mon Jan 12 #{@hr}:46:40 1970\n" +
521
+ "last reset : Mon Jan 12 #{@hr}:46:40 1970\n" +
522
+ "service up : 16 min 40 sec\n" +
523
+ "stuff : empty_hash : none\n" +
524
+ " exceptions : none\n" +
525
+ " float_value : 3.2\n"
526
+ end
527
+
528
+ it "displays name if provided" do
529
+ sub_stats = {"exceptions" => @exceptions.stats,
530
+ "empty_hash" => {},
531
+ "float_value" => 3.15}
532
+
533
+ stats = {"stat time" => @now,
534
+ "last reset time" => @now,
535
+ "service uptime" => 1000,
536
+ "hostname" => "localhost",
537
+ "identity" => "unit tester",
538
+ "name" => "tester_1",
539
+ "stuff stats" => sub_stats}
540
+
541
+ result = @helpers.stats_str(stats)
542
+ result.should == "name : tester_1\n" +
543
+ "identity : unit tester\n" +
544
+ "hostname : localhost\n" +
545
+ "stat time : Mon Jan 12 #{@hr}:46:40 1970\n" +
546
+ "last reset : Mon Jan 12 #{@hr}:46:40 1970\n" +
547
+ "service up : 16 min 40 sec\n" +
548
+ "stuff : empty_hash : none\n" +
549
+ " exceptions : none\n" +
550
+ " float_value : 3.2\n"
551
+ end
552
+
553
+ it "sorts stats using optional prefix" do
554
+ sub_stats = {"empty_hash" => {},
555
+ "float_value" => 3.15}
556
+
557
+ stats = {"stat time" => @now,
558
+ "last reset time" => @now,
559
+ "service uptime" => 1000,
560
+ "hostname" => "localhost",
561
+ "identity" => "unit tester",
562
+ "stuff stats" => sub_stats,
563
+ "other stuff stats" => sub_stats,
564
+ "/data stats" => sub_stats}
565
+
566
+ result = @helpers.stats_str(stats, :sub_name_width => 11)
567
+ result.should == "identity : unit tester\n" +
568
+ "hostname : localhost\n" +
569
+ "stat time : Mon Jan 12 #{@hr}:46:40 1970\n" +
570
+ "last reset : Mon Jan 12 #{@hr}:46:40 1970\n" +
571
+ "service up : 16 min 40 sec\n" +
572
+ "/data : empty_hash : none\n" +
573
+ " float_value : 3.2\n" +
574
+ "other stuff : empty_hash : none\n" +
575
+ " float_value : 3.2\n" +
576
+ "stuff : empty_hash : none\n" +
577
+ " float_value : 3.2\n"
578
+
579
+ stats = {"stat time" => @now,
580
+ "last reset time" => @now,
581
+ "service uptime" => 1000,
582
+ "hostname" => "localhost",
583
+ "identity" => "unit tester",
584
+ "stuff 0stats" => sub_stats,
585
+ "other stuff 1stats" => sub_stats,
586
+ "/data stats" => sub_stats}
587
+
588
+ result = @helpers.stats_str(stats, :name_width => 15)
589
+ result.should == "identity : unit tester\n" +
590
+ "hostname : localhost\n" +
591
+ "stat time : Mon Jan 12 #{@hr}:46:40 1970\n" +
592
+ "last reset : Mon Jan 12 #{@hr}:46:40 1970\n" +
593
+ "service up : 16 min 40 sec\n" +
594
+ "stuff : empty_hash : none\n" +
595
+ " float_value : 3.2\n" +
596
+ "other stuff : empty_hash : none\n" +
597
+ " float_value : 3.2\n" +
598
+ "/data : empty_hash : none\n" +
599
+ " float_value : 3.2\n"
600
+ end
601
+ end
602
+
603
+ end # RightSupport::Stats
@@ -0,0 +1,37 @@
1
+ require 'spec_helper'
2
+
3
+ describe RightSupport::Validation::OpenSSL do
4
+ GOOD_PEM_PUB_RSA = read_fixture('good_pub_rsa.pem')
5
+ GOOD_PEM_PRIV_RSA = read_fixture('good_priv_rsa.pem')
6
+ GOOD_ENCRYPTED_PEM_PRIV_RSA = read_fixture('encrypted_priv_rsa.pem')
7
+ GOOD_SSH_PUB_RSA = read_fixture('good_pub_rsa.ssh')
8
+ GOOD_SSH_PUB_DSA = read_fixture('good_pub_dsa.ssh')
9
+ GOOD_PEM_PRIV_DSA = read_fixture('good_priv_dsa.pem')
10
+
11
+ context :pem_public_key? do
12
+ it 'recognizes valid keys' do
13
+ RightSupport::Validation.pem_public_key?(GOOD_PEM_PUB_RSA).should == true
14
+ end
15
+ it 'recognizes bad keys' do
16
+ RightSupport::Validation.pem_public_key?(corrupt(GOOD_PEM_PUB_RSA)).should == false
17
+ RightSupport::Validation.pem_public_key?(nil).should == false
18
+ RightSupport::Validation.pem_public_key?('').should == false
19
+ end
20
+ end
21
+
22
+ context :pem_private_key? do
23
+ it 'recognizes valid keys' do
24
+ RightSupport::Validation.pem_private_key?(GOOD_PEM_PRIV_RSA).should == true
25
+ RightSupport::Validation.pem_private_key?(GOOD_PEM_PRIV_DSA).should == true
26
+ end
27
+ it 'considers encrypted keys to be "bad" (not usable)' do
28
+ RightSupport::Validation.pem_private_key?(GOOD_ENCRYPTED_PEM_PRIV_RSA).should == false
29
+ end
30
+ it 'recognizes bad keys' do
31
+ RightSupport::Validation.pem_private_key?(corrupt(GOOD_PEM_PRIV_RSA)).should == false
32
+ RightSupport::Validation.pem_private_key?(corrupt(GOOD_PEM_PRIV_RSA, 16)).should == false
33
+ RightSupport::Validation.pem_private_key?(nil).should == false
34
+ RightSupport::Validation.pem_private_key?('').should == false
35
+ end
36
+ end
37
+ end