right_support 2.6.17 → 2.7.0
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/.rspec +4 -0
- data/CHANGELOG.rdoc +37 -0
- data/Gemfile +29 -0
- data/Gemfile.lock +111 -0
- data/README.rdoc +2 -0
- data/Rakefile +62 -0
- data/VERSION +1 -0
- data/features/balancer_error_handling.feature +34 -0
- data/features/balancer_health_check.feature +33 -0
- data/features/continuous_integration.feature +51 -0
- data/features/continuous_integration_cucumber.feature +28 -0
- data/features/continuous_integration_rspec1.feature +28 -0
- data/features/continuous_integration_rspec2.feature +28 -0
- data/features/http_client_timeout.feature +19 -0
- data/features/serialization.feature +95 -0
- data/features/step_definitions/http_client_steps.rb +27 -0
- data/features/step_definitions/request_balancer_steps.rb +93 -0
- data/features/step_definitions/ruby_steps.rb +176 -0
- data/features/step_definitions/serialization_steps.rb +96 -0
- data/features/step_definitions/server_steps.rb +134 -0
- data/features/support/env.rb +138 -0
- data/features/support/file_utils_bundler_mixin.rb +45 -0
- data/lib/right_support/ci/java_cucumber_formatter.rb +22 -8
- data/lib/right_support/ci/java_spec_formatter.rb +26 -8
- data/lib/right_support/ci/rake_task.rb +3 -0
- data/lib/right_support/ci.rb +24 -0
- data/lib/right_support/crypto/signed_hash.rb +22 -0
- data/lib/right_support/data/serializer.rb +24 -2
- data/lib/right_support/net/address_helper.rb +20 -8
- data/lib/right_support/net/dns.rb +20 -8
- data/lib/right_support/net/http_client.rb +22 -0
- data/lib/right_support/net/request_balancer.rb +27 -21
- data/lib/right_support/net/s3_helper.rb +20 -8
- data/lib/right_support/net/ssl/open_ssl_patch.rb +22 -0
- data/lib/right_support/net/ssl.rb +20 -8
- data/lib/right_support/ruby/easy_singleton.rb +22 -0
- data/lib/right_support/ruby/object_extensions.rb +22 -0
- data/lib/right_support/ruby/string_extensions.rb +1 -1
- data/lib/right_support.rb +13 -10
- data/right_support.gemspec +180 -18
- data/right_support.rconf +8 -0
- data/spec/config/feature_set_spec.rb +83 -0
- data/spec/crypto/signed_hash_spec.rb +60 -0
- data/spec/data/hash_tools_spec.rb +471 -0
- data/spec/data/uuid_spec.rb +45 -0
- data/spec/db/cassandra_model_part1_spec.rb +84 -0
- data/spec/db/cassandra_model_part2_spec.rb +73 -0
- data/spec/db/cassandra_model_spec.rb +359 -0
- data/spec/fixtures/encrypted_priv_rsa.pem +30 -0
- data/spec/fixtures/good_priv_dsa.pem +12 -0
- data/spec/fixtures/good_priv_rsa.pem +15 -0
- data/spec/fixtures/good_pub_dsa.ssh +1 -0
- data/spec/fixtures/good_pub_rsa.pem +5 -0
- data/spec/fixtures/good_pub_rsa.ssh +1 -0
- data/spec/log/exception_logger_spec.rb +76 -0
- data/spec/log/filter_logger_spec.rb +8 -0
- data/spec/log/mixin_spec.rb +62 -0
- data/spec/log/multiplexer_spec.rb +54 -0
- data/spec/log/null_logger_spec.rb +36 -0
- data/spec/log/system_logger_spec.rb +92 -0
- data/spec/net/address_helper_spec.rb +57 -0
- data/spec/net/balancing/health_check_spec.rb +382 -0
- data/spec/net/balancing/round_robin_spec.rb +15 -0
- data/spec/net/balancing/sticky_policy_spec.rb +92 -0
- data/spec/net/dns_spec.rb +152 -0
- data/spec/net/http_client_spec.rb +171 -0
- data/spec/net/request_balancer_spec.rb +579 -0
- data/spec/net/s3_helper_spec.rb +160 -0
- data/spec/net/ssl_spec.rb +42 -0
- data/spec/net/string_encoder_spec.rb +58 -0
- data/spec/rack/log_setter_spec.rb +5 -0
- data/spec/rack/request_logger_spec.rb +68 -0
- data/spec/rack/request_tracker_spec.rb +5 -0
- data/spec/ruby/easy_singleton_spec.rb +72 -0
- data/spec/ruby/object_extensions_spec.rb +27 -0
- data/spec/ruby/string_extensions_spec.rb +98 -0
- data/spec/spec_helper.rb +181 -0
- data/spec/stats/activity_spec.rb +193 -0
- data/spec/stats/exceptions_spec.rb +123 -0
- data/spec/stats/helpers_spec.rb +603 -0
- data/spec/validation/openssl_spec.rb +37 -0
- data/spec/validation/ssh_spec.rb +39 -0
- metadata +218 -19
@@ -0,0 +1,359 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe RightSupport::DB::CassandraModel do
|
4
|
+
|
5
|
+
class Cassandra
|
6
|
+
class OrderedHash < Hash
|
7
|
+
def keys
|
8
|
+
super.sort
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def init_app_state(column_family,keyspace,server,env)
|
14
|
+
ENV["RACK_ENV"] = env
|
15
|
+
RightSupport::DB::CassandraModel.column_family = column_family
|
16
|
+
RightSupport::DB::CassandraModel.keyspace = keyspace
|
17
|
+
RightSupport::DB::CassandraModel.config = {"#{env}" => {"server" => server}}
|
18
|
+
end
|
19
|
+
|
20
|
+
context "initialization" do
|
21
|
+
# This method determines the current keyspace based on the return value of the CassandraModel.keyspace method
|
22
|
+
# which looks at the value of @@current_keyspace or @@default_keyspace to determine the keyspace it is operating
|
23
|
+
# under. If a connection already exists for the keyspace it will re-use it. If a connection does not exist,
|
24
|
+
# it will create a new persistent connection for that keyspace that can be re-used with future requests
|
25
|
+
context :conn do
|
26
|
+
let(:column_family) { 'column_family' }
|
27
|
+
let(:env) { 'test' }
|
28
|
+
let(:server) { 'localhost:9160' }
|
29
|
+
let(:keyspace) { 'SatelliteService_1' }
|
30
|
+
let(:default_keyspace) { 'SatelliteService' }
|
31
|
+
let(:current_keyspace_connection) { flexmock('cassandra') }
|
32
|
+
let(:default_keyspace_connection) { flexmock('cassandra') }
|
33
|
+
|
34
|
+
before(:each) do
|
35
|
+
ENV["RACK_ENV"] = env
|
36
|
+
RightSupport::DB::CassandraModel.column_family = column_family
|
37
|
+
RightSupport::DB::CassandraModel.keyspace = default_keyspace
|
38
|
+
RightSupport::DB::CassandraModel.config = {env => {"server" => server}}
|
39
|
+
|
40
|
+
current_keyspace_connection.should_receive(:disable_node_auto_discovery!).and_return(true)
|
41
|
+
current_keyspace_connection.should_receive(:name).and_return('connection1')
|
42
|
+
|
43
|
+
default_keyspace_connection.should_receive(:disable_node_auto_discovery!).and_return(true)
|
44
|
+
default_keyspace_connection.should_receive(:name).and_return('connection2')
|
45
|
+
|
46
|
+
flexmock(Cassandra).should_receive(:new).with(keyspace + '_' + (ENV['RACK_ENV'] || 'development'), "localhost:9160", {:timeout=>10}).and_return(current_keyspace_connection)
|
47
|
+
flexmock(Cassandra).should_receive(:new).with(default_keyspace + '_' + (ENV['RACK_ENV'] || 'development'), "localhost:9160", {:timeout=>10}).and_return(default_keyspace_connection)
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'raises a meaningful exception when a config stanza is missing' do
|
51
|
+
old_rack_env = ENV['RACK_ENV']
|
52
|
+
|
53
|
+
begin
|
54
|
+
ENV['RACK_ENV'] = 'foobar_12345'
|
55
|
+
bad_proc = lambda { RightSupport::DB::CassandraModel.reconnect }
|
56
|
+
bad_proc.should raise_error(RightSupport::DB::MissingConfiguration)
|
57
|
+
# This must be the very first attempt to call #conn during the execution of this spec
|
58
|
+
bad_proc = lambda { RightSupport::DB::CassandraModel.conn }
|
59
|
+
bad_proc.should raise_error(RightSupport::DB::MissingConfiguration)
|
60
|
+
ensure
|
61
|
+
ENV['RACK_ENV'] = old_rack_env
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# This method assumes that keyspaces being requested to connect to already exist.
|
66
|
+
# If they do not exist, it should NOT create them. If the connection is able
|
67
|
+
# to be successfully established then it should be stored in a pool of connections
|
68
|
+
it 'creates a new connection if no connection exists for provided keyspace' do
|
69
|
+
RightSupport::DB::CassandraModel.conn.name.should == default_keyspace_connection.name
|
70
|
+
end
|
71
|
+
|
72
|
+
# If a connection has already been opened for a keyspace it should be re-used
|
73
|
+
it 're-uses an existing connection if it exists for provided keyspace' do
|
74
|
+
RightSupport::DB::CassandraModel.conn.name.should == RightSupport::DB::CassandraModel.conn.name
|
75
|
+
end
|
76
|
+
|
77
|
+
# The keyspace being used for the connection should be either the current keyspace or the default keyspace
|
78
|
+
it 'uses the connection that corresponds to the provided keyspace' do
|
79
|
+
RightSupport::DB::CassandraModel.with_keyspace(keyspace) do
|
80
|
+
RightSupport::DB::CassandraModel.conn.name.should == current_keyspace_connection.name
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
context "use" do
|
87
|
+
|
88
|
+
before(:each) do
|
89
|
+
@column_family = "TestApp"
|
90
|
+
@keyspace = "TestAppService"
|
91
|
+
@server = "localhost:9160"
|
92
|
+
@env = "test"
|
93
|
+
@timeout = {:timeout => RightSupport::DB::CassandraModel::DEFAULT_TIMEOUT}
|
94
|
+
|
95
|
+
init_app_state(@column_family, @keyspace, @server, @env)
|
96
|
+
|
97
|
+
@key = 'key'
|
98
|
+
@value = 'foo'
|
99
|
+
@offset = 'bar'
|
100
|
+
@attrs = {@offset => @value}
|
101
|
+
@opt = {}
|
102
|
+
@get_opt = {:count => RightSupport::DB::CassandraModel::DEFAULT_COUNT}
|
103
|
+
|
104
|
+
@instance = RightSupport::DB::CassandraModel.new(@key, @attrs)
|
105
|
+
|
106
|
+
@conn = flexmock(:connection)
|
107
|
+
flexmock(RightSupport::DB::CassandraModel).should_receive(:conn).and_return(@conn)
|
108
|
+
@conn.should_receive(:insert).with(@column_family, @key, @attrs,@opt).and_return(true)
|
109
|
+
@conn.should_receive(:remove).with(@column_family, @key).and_return(true)
|
110
|
+
@conn.should_receive(:get).with(@column_family, @key, @get_opt).and_return(@attrs).by_default
|
111
|
+
@conn.should_receive(:multi_get).with(@column_family, [1,2], @opt).and_return(Hash.new)
|
112
|
+
end
|
113
|
+
|
114
|
+
describe "instance methods" do
|
115
|
+
context :save do
|
116
|
+
it 'saves the row' do
|
117
|
+
@instance.save.should be_true
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
context :destroy do
|
122
|
+
it 'destroys the row' do
|
123
|
+
@instance.destroy.should be_true
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
context :reload do
|
128
|
+
it 'returns a new object for the row' do
|
129
|
+
@instance.reload.should be_a_kind_of(RightSupport::DB::CassandraModel)
|
130
|
+
@instance.reload!.should be_a_kind_of(RightSupport::DB::CassandraModel)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
describe "class methods" do
|
136
|
+
# We want to remain backward-compatible for existing services so we expect this call to be made
|
137
|
+
# as such: RightSupport::DB::CassandraModel.keyspace = "SatelliteService" and CassandraModel
|
138
|
+
# will append the RACK_ENV to the end of it. Ex: "SatelliteService_development"
|
139
|
+
context :keyspace= do
|
140
|
+
let(:keyspace) { 'SatelliteService' }
|
141
|
+
|
142
|
+
it 'appends the environment to the keyspace provided' do
|
143
|
+
RightSupport::DB::CassandraModel.keyspace = keyspace
|
144
|
+
RightSupport::DB::CassandraModel.send(:class_variable_get, :@@default_keyspace).should == (keyspace + "_" + (ENV['RACK_ENV'] || 'development'))
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
# If a current keyspace is provided it takes precedence over the default keyspace. If none is
|
149
|
+
# provided, the default keyspace should be returned.
|
150
|
+
context :keyspace do
|
151
|
+
let(:keyspace) { 'SatelliteService_' + ENV['RACK_ENV'] }
|
152
|
+
|
153
|
+
it 'returns the default keyspace if no current keyspace is set' do
|
154
|
+
RightSupport::DB::CassandraModel.send(:class_variable_set, :@@current_keyspace, nil)
|
155
|
+
RightSupport::DB::CassandraModel.send(:class_variable_set, :@@default_keyspace, keyspace)
|
156
|
+
RightSupport::DB::CassandraModel.keyspace.should == keyspace
|
157
|
+
end
|
158
|
+
|
159
|
+
it 'returns the current keyspace if a current keyspace is set' do
|
160
|
+
RightSupport::DB::CassandraModel.send(:class_variable_set, :@@current_keyspace, keyspace)
|
161
|
+
RightSupport::DB::CassandraModel.send(:class_variable_set, :@@default_keyspace, nil)
|
162
|
+
RightSupport::DB::CassandraModel.keyspace.should == keyspace
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
# This method assumes that a valid keyspace is passed in. If the keyspace does not exist we do NOT
|
167
|
+
# want to create it. CassandraModel should use the keyspace provided for the duration of the code
|
168
|
+
# executed within the block. Any requests processed outside of the block should execute using the
|
169
|
+
# default keyspace.
|
170
|
+
context :with_keyspace do
|
171
|
+
let(:keyspace) { 'SatelliteService_1' }
|
172
|
+
let(:default_keyspace) { 'SatelliteService' }
|
173
|
+
|
174
|
+
before(:each) do
|
175
|
+
RightSupport::DB::CassandraModel.keyspace = default_keyspace
|
176
|
+
end
|
177
|
+
|
178
|
+
it 'sets the current keyspace to the keyspace provided for execution within the block' do
|
179
|
+
RightSupport::DB::CassandraModel.with_keyspace(keyspace) do
|
180
|
+
RightSupport::DB::CassandraModel.keyspace.should == keyspace + "_" + 'test'
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
it 'resets back to the default keyspace for execution outside of the block' do
|
185
|
+
RightSupport::DB::CassandraModel.with_keyspace(keyspace) {}
|
186
|
+
RightSupport::DB::CassandraModel.keyspace.should == default_keyspace + "_" + 'test'
|
187
|
+
end
|
188
|
+
context 'append_env parameter' do
|
189
|
+
it 'appends the environment by default' do
|
190
|
+
RightSupport::DB::CassandraModel.with_keyspace('Monkey') do
|
191
|
+
RightSupport::DB::CassandraModel.keyspace.should == 'Monkey_test'
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
it 'appends the environment when append_env == true' do
|
196
|
+
RightSupport::DB::CassandraModel.with_keyspace('Monkey', true) do
|
197
|
+
RightSupport::DB::CassandraModel.keyspace.should == 'Monkey_test'
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
it 'does NOT append the environment when append_env == false' do
|
202
|
+
RightSupport::DB::CassandraModel.with_keyspace('Monkey_notatest', false) do
|
203
|
+
RightSupport::DB::CassandraModel.keyspace.should == 'Monkey_notatest'
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
it 'avoids double-appending the environment' do
|
208
|
+
RightSupport::DB::CassandraModel.with_keyspace('Monkey_test') do
|
209
|
+
RightSupport::DB::CassandraModel.keyspace.should == 'Monkey_test'
|
210
|
+
end
|
211
|
+
end
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
context :insert do
|
216
|
+
it 'inserts a row by using the class method' do
|
217
|
+
RightSupport::DB::CassandraModel.insert(@key, @attrs, @opt).should be_true
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
context :remove do
|
222
|
+
it 'removes a row by using the class method' do
|
223
|
+
RightSupport::DB::CassandraModel.remove(@key).should be_true
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
context :all do
|
228
|
+
it 'returns all existing rows for the specified array of keys' do
|
229
|
+
RightSupport::DB::CassandraModel.all([1, 2]).should be_a_kind_of(Hash)
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
context :get do
|
234
|
+
it 'returns row for the specified key' do
|
235
|
+
RightSupport::DB::CassandraModel.get(@key).should be_a_kind_of(RightSupport::DB::CassandraModel)
|
236
|
+
end
|
237
|
+
|
238
|
+
it 'returns only number of columns requested' do
|
239
|
+
attrs = {@offset + '1' => @value, @offset + '2' => @value}
|
240
|
+
get_opt = {:count => 2}
|
241
|
+
@conn.should_receive(:get).with(@column_family, @key, get_opt).and_return(attrs).once
|
242
|
+
RightSupport::DB::CassandraModel.get(@key, get_opt).attributes.should == attrs
|
243
|
+
end
|
244
|
+
|
245
|
+
it 'returns all columns for the specified key if no count specified' do
|
246
|
+
pending "Unpredictable behavior on ruby < 1.9" unless RUBY_VERSION >= "1.9"
|
247
|
+
default_count = RightSupport::DB::CassandraModel::DEFAULT_COUNT
|
248
|
+
|
249
|
+
RightSupport::DB::CassandraModel.instance_eval { remove_const :DEFAULT_COUNT }
|
250
|
+
RightSupport::DB::CassandraModel.const_set(:DEFAULT_COUNT, 2)
|
251
|
+
begin
|
252
|
+
|
253
|
+
attrs1 = {@offset + '1' => @value, @offset + '2' => @value}
|
254
|
+
attrs2 = {@offset + '3' => @value}
|
255
|
+
attrs = attrs1.merge(attrs2)
|
256
|
+
get_opt1 = {:count => 2}
|
257
|
+
get_opt2 = {:count => 2, :start => @offset + '2'}
|
258
|
+
@conn.should_receive(:get).with(@column_family, @key, get_opt1).and_return(attrs1).once
|
259
|
+
@conn.should_receive(:get).with(@column_family, @key, get_opt2).and_return(attrs2).once
|
260
|
+
RightSupport::DB::CassandraModel.get(@key).attributes.should == attrs
|
261
|
+
ensure
|
262
|
+
RightSupport::DB::CassandraModel.instance_eval { remove_const :DEFAULT_COUNT }
|
263
|
+
RightSupport::DB::CassandraModel.const_set(:DEFAULT_COUNT, default_count)
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
it 'returns nil if key not found' do
|
268
|
+
@conn.should_receive(:get).with(@column_family, @key, @get_opt).and_return({})
|
269
|
+
RightSupport::DB::CassandraModel.get(@key).should be_nil
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
def real_get_indexed(index, key, columns = nil, opt = {})
|
274
|
+
rows = {}
|
275
|
+
start = ""
|
276
|
+
count = DEFAULT_COUNT
|
277
|
+
expr = do_op(:create_idx_expr, index, key, "EQ")
|
278
|
+
opt = opt[:consistency] ? {:consistency => opt[:consistency]} : {}
|
279
|
+
while true
|
280
|
+
clause = do_op(:create_idx_clause, [expr], start, count)
|
281
|
+
chunk = do_op(:get_indexed_slices, column_family, clause, columns, opt)
|
282
|
+
rows.merge!(chunk)
|
283
|
+
if chunk.size == count
|
284
|
+
# Assume there are more chunks, use last key as start of next get
|
285
|
+
start = chunk.keys.last
|
286
|
+
else
|
287
|
+
# This must be the last chunk
|
288
|
+
break
|
289
|
+
end
|
290
|
+
end
|
291
|
+
rows
|
292
|
+
end
|
293
|
+
|
294
|
+
context :get_indexed do
|
295
|
+
|
296
|
+
before(:each) do
|
297
|
+
@column = flexmock(:column, :name => 'foo', :value => 'bar')
|
298
|
+
@column_or_super = flexmock(:column_or_super, :column => @column)
|
299
|
+
@rows = {@key => [@column_or_super]}
|
300
|
+
@index = 'index'
|
301
|
+
@index_key = 'index_key'
|
302
|
+
@start = ""
|
303
|
+
@count = RightSupport::DB::CassandraModel::DEFAULT_COUNT
|
304
|
+
@expr = flexmock(:expr)
|
305
|
+
@conn.should_receive(:create_idx_expr).and_return(@expr)
|
306
|
+
@clause = flexmock(:clause)
|
307
|
+
@conn.should_receive(:create_idx_clause).with([@expr], @start, @count).and_return(@clause).by_default
|
308
|
+
@conn.should_receive(:get_indexed_slices).with(@column_family, @clause, nil, {}).and_return(@rows).by_default
|
309
|
+
end
|
310
|
+
|
311
|
+
it 'returns row for the specified key' do
|
312
|
+
rows = RightSupport::DB::CassandraModel.get_indexed(@index, @index_key)
|
313
|
+
rows.should be_a_kind_of(Array)
|
314
|
+
rows.size.should == 1
|
315
|
+
rows.first.should be_a_kind_of(RightSupport::DB::CassandraModel)
|
316
|
+
end
|
317
|
+
|
318
|
+
it 'returns all rows for the specified key if no count specified' do
|
319
|
+
pending "Unpredictable behavior on ruby < 1.9" unless RUBY_VERSION >= "1.9"
|
320
|
+
|
321
|
+
default_count = RightSupport::DB::CassandraModel::DEFAULT_COUNT
|
322
|
+
|
323
|
+
RightSupport::DB::CassandraModel.instance_eval { remove_const :DEFAULT_COUNT }
|
324
|
+
RightSupport::DB::CassandraModel.const_set(:DEFAULT_COUNT, 2)
|
325
|
+
begin
|
326
|
+
key1 = @key + '8'
|
327
|
+
key2 = @key + '12'
|
328
|
+
key3 = @key + '13'
|
329
|
+
cols = {'foo' => 'bar'}
|
330
|
+
rows1 = {key1 => [@column_or_super], key2 => [@column_or_super]}
|
331
|
+
rows2 = {key3 => [@column_or_super]}
|
332
|
+
@conn.should_receive(:create_idx_clause).with([@expr], @start, 2).and_return(@clause).once
|
333
|
+
@conn.should_receive(:get_indexed_slices).with(@column_family, @clause, nil, {}).and_return(rows1).once
|
334
|
+
@conn.should_receive(:create_idx_clause).with([@expr], key2, 2).and_return(@clause).once
|
335
|
+
@conn.should_receive(:get_indexed_slices).with(@column_family, @clause, nil, {}).and_return(rows2).once
|
336
|
+
rows = RightSupport::DB::CassandraModel.get_indexed(@index, @index_key)
|
337
|
+
rows.size.should == 3
|
338
|
+
rows.inject({}) { |s, r| s[r.key] = r.attributes; s }.should == {key1 => cols, key2 => cols, key3 => cols}
|
339
|
+
ensure
|
340
|
+
RightSupport::DB::CassandraModel.instance_eval { remove_const :DEFAULT_COUNT }
|
341
|
+
RightSupport::DB::CassandraModel.const_set(:DEFAULT_COUNT, default_count)
|
342
|
+
end
|
343
|
+
end
|
344
|
+
|
345
|
+
it 'returns empty array if no rows found for key' do
|
346
|
+
@conn.should_receive(:get_indexed_slices).with(@column_family, @clause, nil, {}).and_return({}).once
|
347
|
+
RightSupport::DB::CassandraModel.get_indexed(@index, @index_key).should == []
|
348
|
+
end
|
349
|
+
end
|
350
|
+
end
|
351
|
+
end
|
352
|
+
|
353
|
+
context '.calculate_random_partitioner_token' do
|
354
|
+
it 'works' do
|
355
|
+
expected = 73001115008341200964825964898370608784
|
356
|
+
described_class.calculate_random_partitioner_token('71:foomonkeys').should == expected
|
357
|
+
end
|
358
|
+
end
|
359
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
-----BEGIN RSA PRIVATE KEY-----
|
2
|
+
Proc-Type: 4,ENCRYPTED
|
3
|
+
DEK-Info: DES-EDE3-CBC,61C0BBB816A708D4
|
4
|
+
|
5
|
+
SQ/Y+U7z51OL/hx4YnfVPl6uqsOjpSjU2w4NFqB6EyBtMFgOoqW6ryuIi6ycHgWJ
|
6
|
+
YabUlMPdnexU+1BGqu9P2M9kQejfVddBFmbE09s54dwamk7q6RjaARN0UvHq6Ms9
|
7
|
+
r5/nqRBrinWtOeU/+7cV5qGp2/HbWC2bHAUCCwBcq+ymEpLOw/dpHpxjuiB5ZOLt
|
8
|
+
QzcEJ8ePlNDYvPxw4Wjvb5IDjS4MSoJfA5Y2ZXwVSI1d7mhx4Cekx3CkTMWKYIU8
|
9
|
+
FS6hO39tfPTcxb4os3FYl8D8TlRHv5atrsptKqYE4DKhZhoDA5yFbFJHZlEp+G6H
|
10
|
+
t+snMyuzEWNWq3wGI/gaglatUMq6airA50qticbw8kvz+67pPh2gkAgMXBHEGgPW
|
11
|
+
m0xnqaWf+MyQCUfaxjvxAq68Ced+H9ULLYFrzWAIuSh1M+QartuvP1ZOIcDpY83i
|
12
|
+
RybTJC5MLgGE0COM7oOtPfXO/rvdf6jqTr54HhYwq18aWrqjnacZi0JzNEFRtpNa
|
13
|
+
5FNbwbQGT4Y8J1rOgbyjrd712oRhfjMAU39w4b6gEIATB4zDnMVkdb/Rde/nB7i4
|
14
|
+
CqDB9iSEbtQN4Ev5fXpIDrmhbdT/CURpzRvIt68x08qvX8KQwqDbLz39luocApxN
|
15
|
+
lnTihGiYAiNflMpDvhNL8MSLxYgL5Or2KVF/Ppc+1Qw23BEYDlaRRzc71PWdrVr8
|
16
|
+
UxEdFtqQnnthO7PabrwmLiPeArIGL4U8wrbXA3GbkbDtClftWMaC9JrzVJvXp1z7
|
17
|
+
sXZPhdZzSCg3n3ZbAGKYUx/G8AHojLKfAF3BHufnU9qM+6TS/KtTnhrvHSgYPcBn
|
18
|
+
etI7DWZ/mUnLwnsWfiQ3n5PeeUq/nU+IFJT+Y3r+TfFVCiGPW60XpfLzH1U4otKq
|
19
|
+
KaEnCQX6S7p1Jinx+FHL9fg1I50E6QUNO+N8XO4ay3Jzumz2yjZeudyt+uy954Hq
|
20
|
+
RfmDGYImqrkYrzd8d6hNUTBGnUfUTvq2k/orKhvcxtX+tr9WhNshnJcK18SgBRKT
|
21
|
+
6XLybyioikVSpUGsL95kIhrspryO8v7/M1igWWrLu9fe/jUJLCFzlbGSRYDn+QTp
|
22
|
+
z7qpbBvxHPgu1fKurZ96nCcigVxQgY5rPwpQvG+mkD6YOhgDvSAjTos7Fagz6nb6
|
23
|
+
01MufCVvFx+BBZEsol0Ag23RhXeJXvxkcF//hcPseCA/oB9Aqzyu+ml9mgp4v6P+
|
24
|
+
AgVopgGCfZR31CQ2b9AxdSARFCj2AFE9AdeNy268KSx8wLWAlzUcnGi57eK8WJM3
|
25
|
+
KTDOwJZDgZkjYyMZATpxOj8w3euAflQjQmyXpN1/Q0BW66Mj9+XzVk2yEpF2S0iE
|
26
|
+
xKzPcNEzlGMo1xo6mqVE/kIuRSodXuGp5Eoo8ITvpYWcSdtCTSKJNxAUqry/k9bg
|
27
|
+
9sf3jSmSHzUd92pdM02p8A42HcaPGLmbuFjIfZPK7KoYmIdhJqy7s08CFUlk9XI/
|
28
|
+
PxdYph5J4WkAbeomPGUTFxEWV1cM2lvW4hotrx8MS50WLVZxxY1p7D+JxN3KeJyc
|
29
|
+
mytYpg2dxr8UF64NFKuyEmunkDTdYH2Oi7B7mAcw/QlBN+qCARP+tA==
|
30
|
+
-----END RSA PRIVATE KEY-----
|
@@ -0,0 +1,12 @@
|
|
1
|
+
-----BEGIN DSA PRIVATE KEY-----
|
2
|
+
MIIBvAIBAAKBgQC1RlSYmT8VVtunF3xcpSdJfihaHAGzLH0nf2ooHcKIH6PyxjCe
|
3
|
+
Q93rFB69uyGPUJVawz3w0Y1B7B6h5eXI4SEKA4iqmSHXdFonO7wvOT5DTkzQl3yX
|
4
|
+
B1s4xU8+GW1MtUNKxHPzFpX40797Z1enO/EZRNLYt0P4IG86s/O+BqD6IwIVAJ24
|
5
|
+
m8A6ZFqsunyy2L5o9UInE+gfAoGAPuEeCrIginLFwSdwyrxEwC/gblKvOf/9+iMB
|
6
|
+
Jo+5fN2E9AHKrCsCa53E2lnUbXOdSKDR6yVmUQSB3EsBDoLqDOVJh/BWVTABebIO
|
7
|
+
WwnjQZX9UBGnsJwD4zpvtXLU4qnyFywSr1kdLDHMsGS3WVocJ9jOEH7Rh0xMM423
|
8
|
+
yYS4bUQCgYEApxLO5sTQS/Ej8+BFJQrMS3xHpONQxiMnTLE3q6qZXJRgHDgsqqwZ
|
9
|
+
pAfZCjRxvvfUfBGzjKwJlGQOLZVaGZOArGQF7NRtOfCHZtMBg1vubewXs64gmH5G
|
10
|
+
aXvJ17D6W2vCO04R/vXh43qKLDcPu7wGng+eWNaw/LkbdfC4k8uVfp4CFQCHe0yn
|
11
|
+
rgxFphSFqf8Spchmsg/coA==
|
12
|
+
-----END DSA PRIVATE KEY-----
|
@@ -0,0 +1,15 @@
|
|
1
|
+
-----BEGIN RSA PRIVATE KEY-----
|
2
|
+
MIICWwIBAAKBgQDm4VY+mDoYUsH+7idaNXP6Bq+YIXwqGNar6zgbPEe6qgpF9nSQ
|
3
|
+
B98gMObcZ9H7qGm3e/bQTCrlBAB/jMUQQbTyPsEy3pIKeWoPl7GTQpcSS9WZoHYX
|
4
|
+
yf4TN8MMOeJ3rGbyGb8Xm13R+SBpOMOZfnT3KUJLznIYVtBvv+uFz/C9ewIDAQAB
|
5
|
+
AoGAMJzLkvxsZwitziaI5KaSl9dmi4qpYRe/w40QUDO+CqCY7yg4XMc7hMSnJ0s4
|
6
|
+
3FsWf0q7qhoPgg74p+KU75pWJbEHoYor6LqDuxov4DSx/2SfqmDBIAb9IQ4KWDr2
|
7
|
+
WU/o2/ivbHJ89FxCCroMzNg+qm8pAHVYQ72E/w/1sSRuQPECQQD4fes0OrE8qlJ0
|
8
|
+
0UCxiTbotreNY7N/pKPIFqL/+ODcXJIHCyvVAMXw469r9KacrC/t8qKNatWk3mP1
|
9
|
+
uZzfoAJJAkEA7dsxOJcTqMAncOzbP2cXPkGvzyS06mUoziuZWDc+NAOy4R/V/xHW
|
10
|
+
+CUleXs06G9c/LoZ+E80MP600YvPtKUBowJAZXXMfnPkgDevGUGDX7n98IECazml
|
11
|
+
Rd3sfbs4bLmq3m7xtOyLxhnduGDO9I5dJSVtIIPseT+A4iNnvyI9elVz+QJALTBe
|
12
|
+
mpTBTGctVxv4z4Pje5V5NE6R/JI5fWn1GThtne4x9ulYe7xE7iIIi5rnw10c+nrU
|
13
|
+
4kMR9Fj/u2vnizdqJwJACb7DY5rKZa/xgzgLtE5jW60zZWvwS9LYUs+1ND6CeiFy
|
14
|
+
s3EiH2z+zbSO+cnMtCutdRKIHk3wy6tyRKOq0EMafA==
|
15
|
+
-----END RSA PRIVATE KEY-----
|
@@ -0,0 +1 @@
|
|
1
|
+
ssh-dss AAAAB3NzaC1kc3MAAACBALVGVJiZPxVW26cXfFylJ0l+KFocAbMsfSd/aigdwogfo/LGMJ5D3esUHr27IY9QlVrDPfDRjUHsHqHl5cjhIQoDiKqZIdd0Wic7vC85PkNOTNCXfJcHWzjFTz4ZbUy1Q0rEc/MWlfjTv3tnV6c78RlE0ti3Q/ggbzqz874GoPojAAAAFQCduJvAOmRarLp8sti+aPVCJxPoHwAAAIA+4R4KsiCKcsXBJ3DKvETAL+BuUq85//36IwEmj7l83YT0AcqsKwJrncTaWdRtc51IoNHrJWZRBIHcSwEOguoM5UmH8FZVMAF5sg5bCeNBlf1QEaewnAPjOm+1ctTiqfIXLBKvWR0sMcywZLdZWhwn2M4QftGHTEwzjbfJhLhtRAAAAIEApxLO5sTQS/Ej8+BFJQrMS3xHpONQxiMnTLE3q6qZXJRgHDgsqqwZpAfZCjRxvvfUfBGzjKwJlGQOLZVaGZOArGQF7NRtOfCHZtMBg1vubewXs64gmH5GaXvJ17D6W2vCO04R/vXh43qKLDcPu7wGng+eWNaw/LkbdfC4k8uVfp4= user@host
|
@@ -0,0 +1 @@
|
|
1
|
+
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEApfGJ2lzcKgWq50u4yhZyP7yDjA4CF2pV19TUOlXg4a40FCuKi7JIqPCyixmrWYrvRFz+5zY+gHWOHkCfjNaDryUgPsBMzk2DZDD8fsrJ5KU7QDAa1RMbixnWsWTDcXGhHxC7jtRV7qKFvribLYEoUfVbWZYQR3Wl9kfc78sF6Z2TZuL2Fb9YJc5f2uDz6+I6oy8LtGci4Y2hKVYxrN5tgvFcwkE8JsRaAnjWicfoHRUIBZ/tdT76EMhBEKdO63hO9AZ8phTyZoJyLzykDRaelBUYXjG0LQXTq4jiJhKa07kv0XIgNwnz4zB9qtiOHXm6KZZDxy7xnVXOFum+JqcUxQ== user@host
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe RightSupport::Log::ExceptionLogger do
|
4
|
+
before(:all) do
|
5
|
+
@actual_logger = Logger.new(StringIO.new)
|
6
|
+
@logger = RightSupport::Log::ExceptionLogger.new(@actual_logger)
|
7
|
+
@exception = Exception.new('message')
|
8
|
+
end
|
9
|
+
|
10
|
+
context :exception do
|
11
|
+
it 'logs an error with exception information' do
|
12
|
+
flexmock(@actual_logger).should_receive(:fatal)
|
13
|
+
@logger.exception('desc', @exception)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
context 'class methods' do
|
18
|
+
context :format_exception do
|
19
|
+
it 'includes the description' do
|
20
|
+
RightSupport::Log::ExceptionLogger.format_exception('desc').should == 'desc'
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'includes the exception message if present' do
|
24
|
+
e = ArgumentError.new("err")
|
25
|
+
RightSupport::Log::ExceptionLogger.format_exception('desc', e).should =~ /desc \(ArgumentError: err.*/
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'includes the exception string if present' do
|
29
|
+
RightSupport::Log::ExceptionLogger.format_exception('desc', 'err', :no_trace).should == 'desc (err)'
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'with backtrace=:no_trace' do
|
33
|
+
it 'does not include a backtrace' do
|
34
|
+
e = ArgumentError.new("err")
|
35
|
+
RightSupport::Log::ExceptionLogger.format_exception('desc', e, :no_trace).should == 'desc (ArgumentError: err)'
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'with backtrace=:caller' do
|
40
|
+
it 'includes a single line of backtrace' do
|
41
|
+
begin
|
42
|
+
raise ArgumentError.new("err")
|
43
|
+
rescue Exception => e
|
44
|
+
RightSupport::Log::ExceptionLogger.format_exception('desc', e, :caller).should == "desc (ArgumentError: err IN #{e.backtrace[0]})"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'defaults to :caller trace' do
|
49
|
+
begin
|
50
|
+
raise ArgumentError.new("err")
|
51
|
+
rescue Exception => e
|
52
|
+
RightSupport::Log::ExceptionLogger.format_exception('desc', e).should == "desc (ArgumentError: err IN #{e.backtrace[0]})"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'excludes backtrace if the exception does not respond to backtrace' do
|
57
|
+
RightSupport::Log::ExceptionLogger.format_exception('desc', 'err').should == "desc (err)"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
context 'with backtrace=:trace' do
|
62
|
+
it 'includes a full backtrace' do
|
63
|
+
begin
|
64
|
+
raise ArgumentError.new("err")
|
65
|
+
rescue Exception => e
|
66
|
+
RightSupport::Log::ExceptionLogger.format_exception('desc', e, :trace).should == "desc (ArgumentError: err IN\n " + e.backtrace.join("\n ") + ")"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'excludes backtrace if the exception does not respond to backtrace' do
|
71
|
+
RightSupport::Log::ExceptionLogger.format_exception('desc', 'err').should == "desc (err)"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class InnocentVictim
|
4
|
+
include RightSupport::Log::Mixin
|
5
|
+
end
|
6
|
+
|
7
|
+
describe RightSupport::Log::Mixin do
|
8
|
+
context 'when mixed into a base class' do
|
9
|
+
before(:each) do
|
10
|
+
@victim = InnocentVictim.new
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'provides a class-level accessor' do
|
14
|
+
@victim.class.should respond_to(:logger)
|
15
|
+
@victim.class.should respond_to(:logger=)
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'provides an instance-level accessor' do
|
19
|
+
@victim.should respond_to(:logger)
|
20
|
+
end
|
21
|
+
|
22
|
+
context :logger do
|
23
|
+
context 'without a logger' do
|
24
|
+
before(:each) do
|
25
|
+
@victim.class.logger = nil
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'uses the default logger' do
|
29
|
+
flexmock(RightSupport::Log::Mixin.default_logger).should_receive(:info).twice.and_return(true)
|
30
|
+
@victim.class.logger.info('lalalala').should be_true
|
31
|
+
@victim.logger.info('lalalala').should be_true
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context 'with class logger' do
|
36
|
+
before(:each) do
|
37
|
+
@logger = mock_logger
|
38
|
+
@victim.class.logger = @logger
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'uses class logger' do
|
42
|
+
@logger.should_receive(:info).and_return(true).twice
|
43
|
+
@victim.class.logger.info('lalalala').should be_true
|
44
|
+
@victim.logger.info('lalalala').should be_true
|
45
|
+
end
|
46
|
+
|
47
|
+
context 'with instance logger' do
|
48
|
+
before(:each) do
|
49
|
+
@instance_logger = mock_logger
|
50
|
+
@victim.logger = @instance_logger
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'uses instance logger' do
|
54
|
+
@instance_logger.should_receive(:info).and_return(true).once
|
55
|
+
@logger.should_receive(:info).never
|
56
|
+
@victim.logger.info('lalalala').should be_true
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,54 @@
|
|
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 'spec_helper'
|
24
|
+
|
25
|
+
describe RightSupport::Log::Multiplexer do
|
26
|
+
|
27
|
+
before(:all) do
|
28
|
+
@target1 = RightSupport::Log::NullLogger.new
|
29
|
+
@target2 = RightSupport::Log::NullLogger.new
|
30
|
+
@target3 = RightSupport::Log::NullLogger.new
|
31
|
+
@multiplexer = RightSupport::Log::Multiplexer.new(@target1, @target2, @target3)
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'multiplexes method calls to all callers' do
|
35
|
+
flexmock(@target1).should_receive(:some_method).with('arg', 'arg2').once
|
36
|
+
flexmock(@target2).should_receive(:some_method).with('arg', 'arg2').once
|
37
|
+
flexmock(@target3).should_receive(:some_method).with('arg', 'arg2').once
|
38
|
+
@multiplexer.some_method('arg', 'arg2')
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'returns the result returned by the first target' do
|
42
|
+
flexmock(@target1).should_receive(:some_method).with('arg', 'arg2').and_return('res1').once
|
43
|
+
flexmock(@target2).should_receive(:some_method).with('arg', 'arg2').and_return('res2').once
|
44
|
+
flexmock(@target3).should_receive(:some_method).with('arg', 'arg2').and_return('res3').once
|
45
|
+
@multiplexer.some_method('arg', 'arg2').should == 'res1'
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'multiplexes #warn by undefining Object#warn' do
|
49
|
+
flexmock(@target1).should_receive(:warn).with('arg').and_return('res1')
|
50
|
+
flexmock(@target2).should_receive(:warn).with('arg').and_return('res2')
|
51
|
+
flexmock(@target3).should_receive(:warn).with('arg').and_return('res3')
|
52
|
+
@multiplexer.warn('arg').should == 'res1'
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe RightSupport::Log::NullLogger do
|
4
|
+
before(:each) do
|
5
|
+
@logger = RightSupport::Log::NullLogger.new
|
6
|
+
end
|
7
|
+
|
8
|
+
context 'log levels' do
|
9
|
+
[:debug, :info, :warn, :error, :fatal].each do |method|
|
10
|
+
it "responds to ##{method}" do
|
11
|
+
block_called = false
|
12
|
+
@logger.__send__(method, 'lalalala').should be_true
|
13
|
+
@logger.__send__(method) { block_called = true ; 'lalalala' }.should be_true
|
14
|
+
block_called.should be_true
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
context '<< method' do
|
20
|
+
it 'responds like Logger' do
|
21
|
+
(@logger << 'lalalala').should == 8
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context :close do
|
26
|
+
it 'responds' do
|
27
|
+
@logger.close.should be_nil
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'is idempotent' do
|
31
|
+
@logger.close.should be_nil
|
32
|
+
@logger.close.should be_nil
|
33
|
+
@logger.close.should be_nil
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|