es_client 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,13 @@
1
+ require 'spec_helper'
2
+
3
+ describe EsClient::ActiveRecord::Shortcuts do
4
+ it '#es_doc' do
5
+ record = RspecUser.new.tap(&:save)
6
+ expect(record.es_doc).to eq record.es_client_document
7
+ end
8
+
9
+ it '#es_find' do
10
+ RspecUser.new(id: 1).save
11
+ expect(RspecUser.es_find(1)).to eq RspecUser.es_client.find(1)
12
+ end
13
+ end
@@ -0,0 +1,40 @@
1
+ require 'spec_helper'
2
+
3
+ describe EsClient::Index do
4
+ describe 'exists' do
5
+ it 'index not exists' do
6
+ index = EsClient::Index.new('test_index')
7
+ allow(EsClient.client).to receive(:head).with('/test_index').and_return(double(:response, success?: false))
8
+ expect(index.exists?).to eq false
9
+ end
10
+
11
+ it 'index exists' do
12
+ index = EsClient::Index.new('test_index')
13
+ allow(EsClient.client).to receive(:head).with('/test_index').and_return(double(:response, success?: true))
14
+ expect(index.exists?).to eq true
15
+ end
16
+ end
17
+
18
+ describe 'create' do
19
+ it 'create index' do
20
+ index = EsClient::Index.new('test_index')
21
+ allow(EsClient.client).to receive(:post).with('/test_index', {}).and_return(double(:response, success?: true))
22
+ expect(index.create.success?).to eq true
23
+ end
24
+ end
25
+
26
+ describe 'delete' do
27
+ it 'create index' do
28
+ index = EsClient::Index.new('test_index')
29
+ allow(EsClient.client).to receive(:delete).with('/test_index').and_return(double(:response, success?: true))
30
+ expect(index.delete.success?).to eq true
31
+ end
32
+ end
33
+
34
+ it 'recreate index' do
35
+ index = EsClient::Index.new('test_index')
36
+ expect(index).to receive(:delete)
37
+ expect(index).to receive(:create)
38
+ index.recreate
39
+ end
40
+ end
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+
3
+ describe EsClient::Logger do
4
+ it 'log request' do
5
+ Excon.stub({}, {body: '{"took": 10}'})
6
+ transport = EsClient::Client.new('http://example.com', {})
7
+ expect(EsClient.logger).to receive(:debug).with(Regexp.new(Regexp.escape('[200](10 msec) curl')))
8
+ transport.get('/example', mock: true)
9
+ end
10
+
11
+ it 'log exception' do
12
+ transport = EsClient::Client.new('http://example.com', {})
13
+ allow(transport.http).to receive(:request) { raise Excon::Errors::SocketError.new(StandardError.new) }
14
+ allow(transport).to receive(:reconnect!)
15
+ expect(EsClient.logger).to receive(:error).with(/SocketError.*?curl/m)
16
+ expect { transport.get('/example',) }.to raise_error
17
+ end
18
+ end
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+
3
+ describe EsClient::Response do
4
+ describe '#success?' do
5
+ it 'return true on success code' do
6
+ expect(EsClient::Response.new('', 200).success?).to be_truthy
7
+ end
8
+
9
+ it 'return false on failure code' do
10
+ expect(EsClient::Response.new('', 500).success?).to be_falsey
11
+ end
12
+ end
13
+
14
+ describe '#failure?' do
15
+ it 'return true on failure code' do
16
+ expect(EsClient::Response.new('', 500).failure?).to be_truthy
17
+ end
18
+ end
19
+
20
+ describe '#decoded' do
21
+ it 'return decoded json' do
22
+ expect(EsClient::Response.new('{"key": "value"}', 200).decoded).to eq('key' => 'value')
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,51 @@
1
+ require 'spec_helper'
2
+
3
+ describe EsClient::Client do
4
+ describe 'request' do
5
+ it 'initialize excon' do
6
+ expect(Excon).to receive(:new).with('http://example.com', {persistent: true}).and_return(double(:http).as_null_object)
7
+ EsClient::Client.new('http://example.com', {persistent: true}).get('/example')
8
+ end
9
+
10
+ context 'success' do
11
+ before do
12
+ Excon.stub({}, {})
13
+ end
14
+
15
+ it 'make request' do
16
+ transport = EsClient::Client.new('http://example.com', {})
17
+ expect(transport.http).to receive(:request).with(hash_including(method: :options)).and_return(double(:response).as_null_object)
18
+ transport.request(method: :options, path: '/example', mock: true)
19
+ end
20
+
21
+ it 'make get request' do
22
+ transport = EsClient::Client.new('http://example.com', {})
23
+ expect(transport.http).to receive(:request).with(hash_including(method: :get)).and_return(double(:response).as_null_object)
24
+ transport.get('/example', mock: true)
25
+ end
26
+
27
+ it 'make post request' do
28
+ transport = EsClient::Client.new('http://example.com', {})
29
+ expect(transport.http).to receive(:request).with(hash_including(method: :post)).and_return(double(:response).as_null_object)
30
+ transport.post('/example', mock: true)
31
+ end
32
+ end
33
+
34
+ context 'failure' do
35
+ it 'reconnect on failed request' do
36
+ transport = EsClient::Client.new('http://example.com', {})
37
+ allow(transport.http).to receive(:request) { raise Excon::Errors::SocketError.new(StandardError.new) }
38
+ expect(transport).to receive(:reconnect!)
39
+ expect { transport.get('/example', mock: true) }.to raise_error
40
+ end
41
+
42
+ it 'retry failed request' do
43
+ transport = EsClient::Client.new('http://example.com', {})
44
+ allow(transport.http).to receive(:request) { raise Excon::Errors::SocketError.new(StandardError.new) }
45
+ allow(transport).to receive(:reconnect!)
46
+ expect(transport.http).to receive(:request).twice
47
+ expect { transport.get('/example', mock: true) }.to raise_error
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,40 @@
1
+ require 'spec_helper'
2
+
3
+ describe EsClient do
4
+ it 'has a version number' do
5
+ expect(EsClient::VERSION).not_to be nil
6
+ end
7
+
8
+ it 'has http connection' do
9
+ expect(EsClient.client).to be_instance_of(::EsClient::Client)
10
+ end
11
+
12
+ it 'http connection persistent by default' do
13
+ expect(EsClient.client.http.data[:persistent]).to eq true
14
+ end
15
+
16
+ describe 'index_prefix' do
17
+ after do
18
+ EsClient.index_prefix = nil
19
+ end
20
+
21
+ it 'set index name prefix' do
22
+ EsClient.index_prefix = 'prefix'
23
+ expect(EsClient::Index.new('test').name).to eq 'prefix_test'
24
+ end
25
+ end
26
+
27
+ describe '#with_log_level' do
28
+ it 'execute block with integer log level' do
29
+ EsClient.with_log_level 2 do
30
+ expect(EsClient.logger.level).to eq 2
31
+ end
32
+ end
33
+
34
+ it 'execute block with symbol log level' do
35
+ EsClient.with_log_level :error do
36
+ expect(EsClient.logger.level).to eq 3
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,156 @@
1
+ require 'spec_helper'
2
+
3
+ describe EsClient::Index do
4
+ describe 'exists' do
5
+ it 'index not exists' do
6
+ index = EsClient::Index.new('test_index')
7
+ index.delete
8
+ expect(index.exists?).to eq false
9
+ end
10
+
11
+ it 'index not exists' do
12
+ index = EsClient::Index.new('test_index')
13
+ index.create
14
+ expect(index.exists?).to eq true
15
+ end
16
+ end
17
+
18
+ describe 'create' do
19
+ it 'create index' do
20
+ index = EsClient::Index.new('test_index')
21
+ index.delete
22
+ expect(index.create.success?).to eq true
23
+ end
24
+
25
+ it 'create index with mapping and settings' do
26
+ index = EsClient::Index.new('test_index', mappings: {product: {properties: {sku: {type: 'string'}}}}, settings: {number_of_shards: 1})
27
+ index.delete
28
+ expect(index.create.success?).to eq true
29
+ expect(index.get_mapping).to eq({'product' => {'properties' => {'sku' => {'type' => 'string'}}}})
30
+ expect(index.get_settings['index']['number_of_shards']).to eq '1'
31
+ end
32
+
33
+ it 'create index error' do
34
+ index = EsClient::Index.new('test_index')
35
+ index.create
36
+ expect(index.create.success?).to eq false
37
+ end
38
+ end
39
+
40
+ describe 'delete' do
41
+ it 'delete index' do
42
+ index = EsClient::Index.new('test_index')
43
+ index.create
44
+ expect(index.delete.success?).to eq true
45
+ end
46
+
47
+ it 'delete index error' do
48
+ index = EsClient::Index.new('test_index')
49
+ index.delete
50
+ expect(index.delete.success?).to eq false
51
+ end
52
+ end
53
+
54
+ describe 'mapping' do
55
+ it 'update mapping' do
56
+ index = EsClient::Index.new('test_index')
57
+ index.recreate
58
+ expect(index.put_mapping('product', {properties: {sku: {type: 'string'}}}).success?).to eq true
59
+ expect(index.get_mapping).to eq({'product' => {'properties' => {'sku' => {'type' => 'string'}}}})
60
+ end
61
+ end
62
+
63
+ describe 'settings' do
64
+ it 'update settings' do
65
+ index = EsClient::Index.new('test_index')
66
+ index.recreate
67
+ expect(index.put_settings({refresh_interval: '2s'}).success?).to eq true
68
+ expect(index.get_settings['index']['refresh_interval']).to eq '2s'
69
+ end
70
+ end
71
+
72
+ describe 'save document' do
73
+ it 'save document' do
74
+ index = EsClient::Index.new('test_index')
75
+ index.recreate
76
+ expect(index.save_document('test', nil, {}).success?).to eq true
77
+ end
78
+ end
79
+
80
+ describe 'update document' do
81
+ it 'update document' do
82
+ index = EsClient::Index.new('test_index')
83
+ index.recreate
84
+ index.save_document('test', 1, {id: 1, name: 'test', description: 'text'})
85
+ index.update_document('test', 1, {name: 'test1'})
86
+ expect(index.find('test', 1)['name']).to eq 'test1'
87
+ expect(index.find('test', 1)['description']).to eq 'text'
88
+ end
89
+ end
90
+
91
+ describe 'destroy document' do
92
+ it 'destroy document' do
93
+ index = EsClient::Index.new('test_index')
94
+ index.recreate
95
+ index.save_document('test', 1, {id: 1, name: 'test'})
96
+ expect(index.destroy_document('test', 1).success?).to eq true
97
+ end
98
+ end
99
+
100
+ describe 'find' do
101
+ it 'find document' do
102
+ index = EsClient::Index.new('test_index')
103
+ index.recreate
104
+ index.save_document('test', 1, {id: 1, name: 'test'})
105
+ expect(index.find('test', 1)['name']).to eq 'test'
106
+ end
107
+ end
108
+
109
+ describe 'bulk' do
110
+ it 'perform bulk indexing' do
111
+ index = EsClient::Index.new('test_index')
112
+ index.recreate
113
+ index.bulk(:index, 'test', [{id: 1, name: 'test'}])
114
+ expect(index.find('test', 1)['name']).to eq 'test'
115
+ end
116
+
117
+ it 'perform bulk update' do
118
+ index = EsClient::Index.new('test_index')
119
+ index.recreate
120
+ index.save_document('test', 1, {id: 1, name: 'test'})
121
+ index.bulk(:update, 'test', [{id: 1, name: 'updated name'}])
122
+ expect(index.find('test', 1)['name']).to eq 'updated name'
123
+ end
124
+
125
+ it 'perform bulk update with options' do
126
+ index = EsClient::Index.new('test_index')
127
+ index.recreate
128
+ index.bulk(:update, 'test', [{id: 1, name: 'updated name', bulk_options: {doc_as_upsert: true}}])
129
+ expect(index.find('test', 1)['name']).to eq 'updated name'
130
+ end
131
+
132
+ it 'perform bulk delete' do
133
+ index = EsClient::Index.new('test_index')
134
+ index.recreate
135
+ index.save_document('test', 1, {id: 1, name: 'test'})
136
+ index.bulk(:delete, 'test', [{id: 1}])
137
+ expect(index.find('test', 1)).to be_nil
138
+ end
139
+ end
140
+
141
+ it 'refresh index' do
142
+ index = EsClient::Index.new('test_index')
143
+ index.recreate
144
+ expect(index.refresh.success?).to eq true
145
+ end
146
+
147
+ describe 'search' do
148
+ it 'perform query' do
149
+ index = EsClient::Index.new('test_index')
150
+ index.recreate
151
+ index.save_document('test', 1, {id: 1, name: 'test'})
152
+ index.refresh
153
+ expect(index.search({query: {ids: {values: [1]}}}, type: 'test').decoded['hits']['hits'].length).to eq 1
154
+ end
155
+ end
156
+ end
@@ -0,0 +1,113 @@
1
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
+ require 'es_client'
3
+ require 'byebug'
4
+ require 'active_model'
5
+ require 'ruby-progressbar'
6
+
7
+ RSpec.configure do |c|
8
+ c.order = :rand
9
+ end
10
+
11
+ EsClient.setup do |config|
12
+ config.log_path = File.expand_path('../../log/elasticsearch.log', __FILE__)
13
+ config.host = 'http://localhost:9201'
14
+ end
15
+
16
+ class RspecActiveRecordBase
17
+ include ActiveModel::AttributeMethods
18
+ include ActiveModel::Serialization
19
+ include ActiveModel::Serializers::JSON
20
+ include ActiveModel::Naming
21
+
22
+ extend ActiveModel::Callbacks
23
+ define_model_callbacks :save, :destroy
24
+
25
+ attr_reader :attributes
26
+
27
+ def initialize(attributes = {})
28
+ @attributes = attributes
29
+ end
30
+
31
+ def id
32
+ @attributes[:id]
33
+ end
34
+
35
+ def to_indexed_json
36
+ @attributes.to_json
37
+ end
38
+
39
+ def method_missing(id, *args, &block)
40
+ attributes[id.to_sym] || attributes[id.to_s] || super
41
+ end
42
+
43
+ def new_record?
44
+ false
45
+ end
46
+
47
+ def persisted?
48
+ !new_record?
49
+ end
50
+
51
+ def save
52
+ run_callbacks(:save) {}
53
+ end
54
+
55
+ def destroy
56
+ run_callbacks(:destroy) { @destroyed = true }
57
+ end
58
+
59
+ def destroyed?
60
+ !!@destroyed
61
+ end
62
+
63
+ def self.find_in_batches(options={})
64
+ i = 0
65
+ 2.times do
66
+ yield [new(id: i += 1), new(id: i += 1)]
67
+ end
68
+ end
69
+
70
+ def self.count
71
+ 4
72
+ end
73
+ end
74
+
75
+ class RspecUser < RspecActiveRecordBase
76
+ include ::EsClient::ActiveRecord::Glue
77
+ include ::EsClient::ActiveRecord::Shortcuts
78
+
79
+ def self.setup_index
80
+ es_client.index.recreate
81
+ populate
82
+ es_client.index.refresh
83
+ end
84
+
85
+ def self.test_data
86
+ [
87
+ {
88
+ id: 1,
89
+ name: 'alex',
90
+ created_at: 3.day.ago
91
+ },
92
+ {
93
+ id: 2,
94
+ name: 'bob',
95
+ created_at: 2.day.ago
96
+ },
97
+ {
98
+ id: 3,
99
+ name: 'john',
100
+ created_at: 1.day.ago
101
+ }
102
+ ]
103
+ end
104
+
105
+ def self.populate
106
+ test_data.each do |attrs|
107
+ u = new(attrs)
108
+ u.id = attrs[:id]
109
+ u.save
110
+ end
111
+ end
112
+
113
+ end