waistband 0.8.5 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,24 +0,0 @@
1
- require 'active_support/core_ext/hash/keys'
2
-
3
- module Waistband
4
- class QueryResult
5
-
6
- attr_reader :source, :_id, :score
7
-
8
- def initialize(row)
9
- @source = row['_source'].stringify_keys
10
- @_id = row['_id']
11
- @score = row['_score']
12
- end
13
-
14
- def method_missing(method_name, *args, &block)
15
- @source[method_name.to_s]
16
- end
17
-
18
- def respond_to_missing?(method_name, include_private = false)
19
- return true if @source.has_key?(method_name.to_s)
20
- super
21
- end
22
-
23
- end
24
- end
@@ -1,9 +0,0 @@
1
- module Waistband
2
- class QuickError < Array
3
-
4
- def full_messages
5
- self
6
- end
7
-
8
- end
9
- end
@@ -1,419 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Waistband::Connection do
4
-
5
- let(:connection) { Waistband::Connection.new(index) }
6
- let(:search_connection) { Waistband::Connection.new(index_search) }
7
- let(:index) { ::Waistband::Index.new('events') }
8
- let(:index_search) { ::Waistband::Index.new('search') }
9
-
10
- def blacklist_server!
11
- connection.send(:blacklist!, Waistband.config.servers.first)
12
- end
13
-
14
- it "constructs the settings json" do
15
- connection.send(:settings_json).should eql '{"index":{"number_of_replicas":1}}'
16
- end
17
-
18
- it "constructs the index json" do
19
- connection.send(:index_json).should eql '{"settings":{"index":{"number_of_shards":1,"number_of_replicas":1}},"mappings":{"event":{"_source":{"includes":["*"]}}}}'
20
- end
21
-
22
- describe 'urls for subindexes' do
23
-
24
- let(:index) { ::Waistband::Index.new('events', subs: %w(2013 01)) }
25
- let(:connection) { Waistband::Connection.new(index, orderly: true) }
26
-
27
- describe '#destroy!' do
28
-
29
- it "targets the correct url" do
30
- RestClient.should_receive(:send).with('delete', "http://localhost:9200/events_test__2013_01", nil).once
31
- connection.destroy!
32
- end
33
-
34
- end
35
-
36
- describe '#create!' do
37
-
38
- it "targets the correct url" do
39
- RestClient.should_receive(:send).with('post', "http://localhost:9200/events_test__2013_01", index.config_json).once
40
- connection.create!
41
- end
42
-
43
- end
44
-
45
- describe '#update_settings!' do
46
-
47
- it "targets the correct url" do
48
- RestClient.should_receive(:send).with('put', "http://localhost:9200/events_test__2013_01/_settings", connection.send(:settings_json)).once
49
- connection.update_settings!
50
- end
51
-
52
- end
53
-
54
- describe '#refresh!' do
55
-
56
- it "targets the correct url" do
57
- RestClient.should_receive(:send).with('post', "http://localhost:9200/events_test__2013_01/_refresh", {}).once
58
- connection.refresh!
59
- end
60
-
61
- end
62
-
63
- describe '#read' do
64
-
65
- it "targets the correct url" do
66
- index.refresh
67
- RestClient.should_receive(:send).with('get', "http://localhost:9200/events_test__2013_01/event/my_key", nil).once.and_call_original
68
- connection.read 'my_key'
69
- end
70
-
71
- end
72
-
73
- describe '#put' do
74
-
75
- it "targets the correct url" do
76
- RestClient.should_receive(:send).with('put', "http://localhost:9200/events_test__2013_01/event/my_key", {oh_yeah: true}.to_json).once.and_call_original
77
- connection.put 'my_key', {oh_yeah: true}
78
- end
79
-
80
- end
81
-
82
- describe '#delete!' do
83
-
84
- it "targets the correct url" do
85
- RestClient.should_receive(:send).with('delete', "http://localhost:9200/events_test__2013_01/event/my_key", nil).once.and_call_original
86
- connection.delete 'my_key'
87
- end
88
-
89
- end
90
-
91
- describe '#search_url' do
92
-
93
- it "targets the correct url" do
94
- connection.search_url.should eql "http://localhost:9200/events_test__2013_01/_search"
95
- end
96
-
97
- end
98
-
99
- describe '#alias!' do
100
-
101
- it "targets the correct url with a specific alias_name" do
102
- RestClient.should_receive(:send).with('put', "http://localhost:9200/events_test__2013_01/_alias/all_events_test", nil).once.and_call_original
103
- connection.alias! 'all_events'
104
- end
105
-
106
- end
107
-
108
- end
109
-
110
- describe '#full_alias_name' do
111
-
112
- it "returns the alias name with the env" do
113
- connection.full_alias_name('all_events').should eql 'all_events_test'
114
- end
115
-
116
- it "if the index has a custom name, the alias name doesn't automatically append the env" do
117
- connection.instance_variable_get('@index').stub(:config).and_return({
118
- 'name' => 'super_custom'
119
- })
120
- connection.full_alias_name('all_events').should eql 'all_events'
121
- end
122
-
123
- end
124
-
125
- describe 'urls' do
126
-
127
- let(:connection) { Waistband::Connection.new(index, orderly: true) }
128
-
129
- describe '#destroy!' do
130
-
131
- it "targets the correct url" do
132
- RestClient.should_receive(:send).with('delete', "http://localhost:9200/events_test", nil).once
133
- connection.destroy!
134
- end
135
-
136
- end
137
-
138
- describe '#create!' do
139
-
140
- it "targets the correct url" do
141
- RestClient.should_receive(:send).with('post', "http://localhost:9200/events_test", index.config_json).once
142
- connection.create!
143
- end
144
-
145
- end
146
-
147
- describe '#update_settings!' do
148
-
149
- it "targets the correct url" do
150
- RestClient.should_receive(:send).with('put', "http://localhost:9200/events_test/_settings", connection.send(:settings_json)).once
151
- connection.update_settings!
152
- end
153
-
154
- end
155
-
156
- describe '#refresh!' do
157
-
158
- it "targets the correct url" do
159
- RestClient.should_receive(:send).with('post', "http://localhost:9200/events_test/_refresh", {}).once
160
- connection.refresh!
161
- end
162
-
163
- end
164
-
165
- describe '#read' do
166
-
167
- it "targets the correct url" do
168
- RestClient.should_receive(:send).with('get', "http://localhost:9200/events_test/event/my_key", nil).once.and_call_original
169
- connection.read 'my_key'
170
- end
171
-
172
- end
173
-
174
- describe '#put' do
175
-
176
- it "targets the correct url" do
177
- RestClient.should_receive(:send).with('put', "http://localhost:9200/events_test/event/my_key", {oh_yeah: true}.to_json).once.and_call_original
178
- connection.put 'my_key', {oh_yeah: true}
179
- end
180
-
181
- end
182
-
183
- describe '#delete!' do
184
-
185
- it "targets the correct url" do
186
- connection.put 'my_key', {oh_yeah: true}
187
-
188
- RestClient.should_receive(:send).with('delete', "http://localhost:9200/events_test/event/my_key", nil).once.and_call_original
189
- connection.delete! 'my_key'
190
- end
191
-
192
- end
193
-
194
- describe '#search_url' do
195
-
196
- it "targets the correct url" do
197
- connection.search_url.should eql "http://localhost:9200/events_test/_search"
198
- end
199
-
200
- end
201
-
202
- describe '#alias!' do
203
-
204
- it "targets the correct url with a specific alias_name" do
205
- RestClient.should_receive(:send).with('put', "http://localhost:9200/events_test/_alias/all_events_test", nil).once.and_call_original
206
- connection.alias! 'all_events'
207
- end
208
-
209
- end
210
-
211
- end
212
-
213
- describe '#alias!' do
214
-
215
- it "creates an alias for the index" do
216
- connection.alias! 'all_events'
217
- aliases = connection.fetch_alias 'all_events'
218
- aliases.should eql({"events_test"=>{"aliases"=>{"all_events_test"=>{}}}})
219
- end
220
-
221
- end
222
-
223
- describe '#execute!' do
224
-
225
- it "wraps directly to rest client" do
226
- connection = Waistband::Connection.new(index, orderly: true)
227
-
228
- RestClient.should_receive(:get).with('http://localhost:9200/somekey', nil).once
229
- connection.send(:execute!, 'get', 'somekey')
230
- end
231
-
232
- describe 'failures' do
233
-
234
- [Timeout::Error, Errno::EHOSTUNREACH, Errno::ECONNREFUSED, Errno::ECONNRESET].each do |exception|
235
- it "blacklists the server when #{exception}" do
236
- connection = Waistband::Connection.new(index, retry_on_fail: false)
237
-
238
- RestClient.should_receive(:get).with(kind_of(String), nil).and_raise exception
239
- connection.send(:execute!, 'get', 'somekey')
240
-
241
- connection.send(:available_servers).size.should eql 1
242
- end
243
- end
244
-
245
- it "blacklists correctly when server is not responding" do
246
- ::Waistband.config.stub(:servers).and_return(
247
- [
248
- {
249
- host: "http://localhost",
250
- port: 9123,
251
- _id: "567890a5ce74182e5cd123e299993ab510c56123"
252
- }.with_indifferent_access,
253
- {
254
- host: "http://localhost",
255
- port: 9200,
256
- _id: "282f32a5ce74182e5cd628e298b93ab510c5660c"
257
- }.with_indifferent_access
258
- ]
259
- )
260
-
261
- connection = Waistband::Connection.new(index, orderly: true)
262
- expect { connection.refresh }.to_not raise_error
263
-
264
- connection.instance_variable_get('@blacklist').should eql ['567890a5ce74182e5cd123e299993ab510c56123']
265
- end
266
-
267
- it "keeps retrying till out of servers when retry_on_fail is true" do
268
- RestClient.should_receive(:get).with('http://localhost:9200/somekey', nil).once.and_raise(Timeout::Error)
269
- RestClient.should_receive(:get).with('http://127.0.0.1:9200/somekey', nil).once.and_raise(Timeout::Error)
270
-
271
- expect {
272
- connection.send(:execute!, 'get', 'somekey')
273
- }.to raise_error(
274
- Waistband::Connection::Error::NoMoreServers,
275
- "No available servers remain"
276
- )
277
- end
278
-
279
- end
280
-
281
- end
282
-
283
- describe '#relative_url_for_key' do
284
-
285
- it "returns the relative url for a key" do
286
- url = search_connection.send(:relative_url_for_key, 'key123')
287
- url.should match /^search_test\/search\/key123$/
288
-
289
- url = connection.send(:relative_url_for_key, '9986')
290
- url.should match /^events_test\/event\/9986$/
291
- end
292
-
293
- end
294
-
295
- describe '#url' do
296
-
297
- it "returns url string for the selected server" do
298
- url = connection.send(:url)
299
- url.should match /^http\:\/\//
300
- url.should match /\:9200$/
301
- end
302
-
303
- end
304
-
305
- describe '#pick_server' do
306
-
307
- it "randomly picks a server" do
308
- server = connection.send :pick_server
309
- server['host'].should match /http\:\/\//
310
- server['port'].should eql 9200
311
- end
312
-
313
- it "never picks blacklisted servers" do
314
- blacklist_server!
315
-
316
- 200.times do
317
- server = connection.send :pick_server
318
-
319
- server['host'].should eql 'http://127.0.0.1'
320
- end
321
- end
322
-
323
- it "blows up when no more servers remain" do
324
- blacklist_server!
325
-
326
- expect {
327
- connection.send(:blacklist!, Waistband.config.servers.last)
328
- }.to raise_error(
329
- Waistband::Connection::Error::NoMoreServers,
330
- "No available servers remain"
331
- )
332
- end
333
-
334
- end
335
-
336
- describe '#blacklist!' do
337
-
338
- it "blacklists a server" do
339
- connection.instance_variable_get('@blacklist').should be_empty
340
-
341
- blacklist_server!
342
-
343
- connection.instance_variable_get('@blacklist').size.should eql 1
344
- connection.instance_variable_get('@blacklist').first.should eql Waistband.config.servers.first['_id']
345
- end
346
-
347
- it "doesn't keep duplicate servers" do
348
- connection.instance_variable_get('@blacklist').should be_empty
349
-
350
- blacklist_server!
351
-
352
- connection.instance_variable_get('@blacklist').size.should eql 1
353
-
354
- blacklist_server!
355
-
356
- connection.instance_variable_get('@blacklist').size.should eql 1
357
- end
358
-
359
- end
360
-
361
- describe '#available_servers' do
362
-
363
- it "returns an array of servers" do
364
- connection.send(:available_servers).should be_an Array
365
- connection.send(:available_servers).size.should eql 2
366
- end
367
-
368
- it "doesn't include blacklisted servers" do
369
- blacklist_server!
370
-
371
- connection.send(:available_servers).should be_an Array
372
- connection.send(:available_servers).size.should eql 1
373
-
374
- ids = connection.send(:available_servers).map{|s| s['_id']}
375
- ids.should include Waistband.config.servers.last['_id']
376
- ids.should_not include Waistband.config.servers.first['_id']
377
- end
378
-
379
- end
380
-
381
- describe "storing" do
382
-
383
- let(:attrs) { {'other_ok' => {'yeah' => true}} }
384
-
385
- it "stores data" do
386
- connection.put('__test_write', {'ok' => 'yeah'})
387
- index.read('__test_write').should eql({'ok' => 'yeah'})
388
- end
389
-
390
- it "data is indirectly accessible" do
391
- connection.put('__test_not_string', attrs)
392
- index.read('__test_not_string')[:other_ok][:yeah].should eql true
393
- end
394
-
395
- it "deletes data" do
396
- connection.put('__test_write', attrs)
397
- connection.delete!('__test_write')
398
- index.read('__test_write').should be_nil
399
- end
400
-
401
- it "blows up when trying to delete non-existent data" do
402
- expect { connection.delete!('__test_write') }.to raise_error
403
- end
404
-
405
- it "returns nil on 404" do
406
- index.read('__not_here').should be_nil
407
- end
408
-
409
- it "doesn't mix data between two indexes" do
410
- connection.put('__test_write', {'data' => 'index_1'})
411
- search_connection.put('__test_write', {'data' => 'index_2'})
412
-
413
- index.read('__test_write').should eql({'data' => 'index_1'})
414
- index_search.read('__test_write').should eql({'data' => 'index_2'})
415
- end
416
-
417
- end
418
-
419
- end