es_client 0.1.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.
@@ -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