chewy 7.6.0 → 8.0.0.pre.beta

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/.github/CODEOWNERS +1 -1
  3. data/.github/workflows/ruby.yml +5 -5
  4. data/CHANGELOG.md +12 -0
  5. data/README.md +33 -1
  6. data/chewy.gemspec +3 -2
  7. data/docker-compose.yml +15 -0
  8. data/gemfiles/base.gemfile +1 -1
  9. data/lib/chewy/config.rb +2 -2
  10. data/lib/chewy/errors.rb +3 -0
  11. data/lib/chewy/fields/root.rb +1 -1
  12. data/lib/chewy/index/actions.rb +5 -5
  13. data/lib/chewy/index/aliases.rb +1 -1
  14. data/lib/chewy/index/syncer.rb +1 -1
  15. data/lib/chewy/minitest/helpers.rb +1 -1
  16. data/lib/chewy/search/request.rb +4 -4
  17. data/lib/chewy/search/response.rb +7 -0
  18. data/lib/chewy/search/scrolling.rb +2 -1
  19. data/lib/chewy/version.rb +1 -1
  20. data/lib/chewy.rb +4 -0
  21. data/spec/chewy/config_spec.rb +2 -2
  22. data/spec/chewy/elastic_client_spec.rb +1 -1
  23. data/spec/chewy/fields/base_spec.rb +2 -2
  24. data/spec/chewy/fields/time_fields_spec.rb +1 -1
  25. data/spec/chewy/index/actions_spec.rb +9 -9
  26. data/spec/chewy/index/aliases_spec.rb +1 -1
  27. data/spec/chewy/index/import/bulk_builder_spec.rb +2 -2
  28. data/spec/chewy/index/import/bulk_request_spec.rb +1 -1
  29. data/spec/chewy/index/import/routine_spec.rb +1 -1
  30. data/spec/chewy/index/import_spec.rb +15 -15
  31. data/spec/chewy/index/observe/callback_spec.rb +1 -1
  32. data/spec/chewy/index/specification_spec.rb +1 -4
  33. data/spec/chewy/index/syncer_spec.rb +1 -1
  34. data/spec/chewy/index_spec.rb +1 -1
  35. data/spec/chewy/journal_spec.rb +2 -2
  36. data/spec/chewy/minitest/helpers_spec.rb +1 -1
  37. data/spec/chewy/multi_search_spec.rb +1 -1
  38. data/spec/chewy/rake_helper_spec.rb +1 -1
  39. data/spec/chewy/rspec/update_index_spec.rb +1 -1
  40. data/spec/chewy/runtime_spec.rb +2 -2
  41. data/spec/chewy/search/loader_spec.rb +1 -1
  42. data/spec/chewy/search/pagination/kaminari_examples.rb +1 -1
  43. data/spec/chewy/search/request_spec.rb +1 -1
  44. data/spec/chewy/search/response_spec.rb +2 -2
  45. data/spec/chewy/search/scrolling_spec.rb +1 -1
  46. data/spec/chewy/search_spec.rb +1 -1
  47. data/spec/chewy/stash_spec.rb +1 -1
  48. data/spec/chewy/strategy/delayed_sidekiq_spec.rb +1 -1
  49. data/spec/chewy/strategy_spec.rb +1 -1
  50. data/spec/chewy_spec.rb +6 -5
  51. data/spec/spec_helper.rb +26 -0
  52. metadata +13 -12
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a15165f889275fecc6a0d590c3339ce0ac9b7944f916306fd6883e7c2be67747
4
- data.tar.gz: 8efc6201add68bf1c378f598934b6c52c74bd9a62056e7aafdd357358d5cd2b0
3
+ metadata.gz: fe6459bb964c9d44912601a2a5abc6ea93ea7ac7be94c384673ade2ce68fb9e6
4
+ data.tar.gz: 397d2104f889f9e9232ed673b3fe5dc50fe4c13f1330b4ce9b1b1e45f9a11e16
5
5
  SHA512:
6
- metadata.gz: cfc7f1297fc72fcbdfdbedbcd82c6afe12dd9e15583b4e3467a8a77da89cd1aa8f20b9d0c0a8dd1841275e2916715030e28e9ed10cf510d6985904be9574890e
7
- data.tar.gz: 6917027945ce94dab50d2f6d679570be58e4bb86472f1d591805d915ca425ecbd24e4cc13e30a459fe2dae4d572002735b69cef138a5c6038c52803a251b8a54
6
+ metadata.gz: ebe662c3e11aaebd6fb8de8058ed9199d94b7eb80e7f4b6347c0fe98481c37cdb6be51e72d13645e627ae7d653d43c4bcd6a9a1f81b4eafdbb7371c814f2e847
7
+ data.tar.gz: 0e3b1d9b5eb0724fb1b2453d75e7980d9d7c1a3b341dca3934c366c7ba6ec5242bd9e647538486c9be6203d1ca9a5c6f18bcefcfc7ea64cdf8a31b7893af9f72
data/.github/CODEOWNERS CHANGED
@@ -1 +1 @@
1
- .github/workflows @toptal/platform-sre
1
+ .github/workflows @toptal/sre
@@ -41,11 +41,11 @@ jobs:
41
41
  with:
42
42
  ruby-version: ${{ matrix.ruby }}
43
43
  bundler-cache: true
44
- - name: Run Elasticsearch
45
- uses: elastic/elastic-github-actions/elasticsearch@9de0f78f306e4ebc0838f057e6b754364685e759
46
- with:
47
- stack-version: 7.10.1
48
- port: 9250
44
+ - name: Start containers
45
+ run: |
46
+ docker compose up elasticsearch_test -d
47
+ sleep 15
48
+
49
49
  - name: Tests
50
50
  run: bundle exec rspec
51
51
 
data/CHANGELOG.md CHANGED
@@ -8,6 +8,18 @@
8
8
 
9
9
  ### Bugs Fixed
10
10
 
11
+ ## 8.0.0-beta (2024-08-27)
12
+
13
+ ### New Features
14
+
15
+ * [#962](https://github.com/toptal/chewy/pull/962): ElasticSearch v.8 support added
16
+
17
+ * `delete_all_enabled` setting introduced to align Chewy.massacre with wildcard indices deletion disabled in ES 8 by default
18
+
19
+ ### Changes
20
+
21
+ ### Bugs Fixed
22
+
11
23
  ## 7.6.0 (2024-05-03)
12
24
 
13
25
  ### Changes
data/README.md CHANGED
@@ -51,6 +51,7 @@ Chewy is compatible with MRI 3.0-3.2¹.
51
51
 
52
52
  | Chewy version | Elasticsearch version |
53
53
  | ------------- | ---------------------------------- |
54
+ | 8.0.0 | 8.x |
54
55
  | 7.2.x | 7.x |
55
56
  | 7.1.x | 7.x |
56
57
  | 7.0.x | 6.8, 7.x |
@@ -97,7 +98,36 @@ development:
97
98
  Make sure you have Elasticsearch up and running. You can [install](https://www.elastic.co/guide/en/elasticsearch/reference/current/install-elasticsearch.html) it locally, but the easiest way is to use [Docker](https://www.docker.com/get-started):
98
99
 
99
100
  ```shell
100
- $ docker run --rm --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.11.1
101
+ $ docker run --rm --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e "xpack.security.enabled=false" elasticsearch:8.15.0
102
+ ```
103
+
104
+ ### Security
105
+
106
+ Please note that starting from version 8 ElasticSearch has security features enabled by default.
107
+ Docker command above has it disabled for local testing convenience. If you want to enable it, omit
108
+ `"xpack.security.enabled=false"` part from Docker command, and run these command after starting container (container name `es8` assumed):
109
+
110
+ Reset password for `elastic` user:
111
+ ```
112
+ docker container exec es8 '/usr/share/elasticsearch/bin/elasticsearch-reset-password' -u elastic
113
+ ```
114
+
115
+ Extract CA certificate generated by ElasticSearch on first run:
116
+ ```
117
+ docker container cp es8:/usr/share/elasticsearch/config/certs/http_ca.crt tmp/
118
+ ```
119
+
120
+ And then add them to settings:
121
+
122
+ ```yaml
123
+ # config/chewy.yml
124
+ development:
125
+ host: 'localhost:9200'
126
+ user: 'elastic'
127
+ password: 'SomeLongPassword'
128
+ transport_options:
129
+ ssl:
130
+ ca_file: './tmp/http_ca.crt'
101
131
  ```
102
132
 
103
133
  ### Index
@@ -941,6 +971,8 @@ Controller actions are wrapped with the configurable value of `Chewy.request_str
941
971
 
942
972
  It is also a good idea to set up the `:bypass` strategy inside your test suite and import objects manually only when needed, and use `Chewy.massacre` when needed to flush test ES indices before every example. This will allow you to minimize unnecessary ES requests and reduce overhead.
943
973
 
974
+ Deprecation note: since version 8 wildcard removing of indices is disabled by default. You can enable it for a cluster with setting `action.destructive_requires_name` to false.
975
+
944
976
  ```ruby
945
977
  RSpec.configure do |config|
946
978
  config.before(:suite) do
data/chewy.gemspec CHANGED
@@ -11,13 +11,14 @@ Gem::Specification.new do |spec|
11
11
  spec.description = 'Chewy provides functionality for Elasticsearch index handling, documents import mappings and chainable query DSL'
12
12
  spec.homepage = 'https://github.com/toptal/chewy'
13
13
  spec.license = 'MIT'
14
+ spec.required_ruby_version = '~> 3.0'
14
15
 
15
16
  spec.files = `git ls-files`.split($RS)
16
17
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
18
  spec.require_paths = ['lib']
18
19
 
19
- spec.add_dependency 'activesupport', '>= 5.2' # Remove with major version bump, 8.x
20
- spec.add_dependency 'elasticsearch', '>= 7.14.0', '< 8'
20
+ spec.add_dependency 'activesupport', '>= 6.1'
21
+ spec.add_dependency 'elasticsearch', '>= 8.14', '< 9.0'
21
22
  spec.add_dependency 'elasticsearch-dsl'
22
23
  spec.metadata['rubygems_mfa_required'] = 'true'
23
24
  end
@@ -0,0 +1,15 @@
1
+ version: "3.4"
2
+ services:
3
+ elasticsearch_test:
4
+ image: "elasticsearch:8.15.0"
5
+ environment:
6
+ - bootstrap.memory_lock=${ES_MEMORY_LOCK:-false}
7
+ - "ES_JAVA_OPTS=-Xms${TEST_ES_HEAP_SIZE:-500m} -Xmx${TEST_ES_HEAP_SIZE:-500m}"
8
+ - discovery.type=single-node
9
+ - xpack.security.enabled=false
10
+ ports:
11
+ - "127.0.0.1:9250:9200"
12
+ ulimits:
13
+ nofile:
14
+ soft: 65536
15
+ hard: 65536
@@ -6,7 +6,7 @@ gem 'redis', require: false
6
6
  gem 'rspec', '>= 3.7.0'
7
7
  gem 'rspec-collection_matchers'
8
8
  gem 'rspec-its'
9
- gem 'rubocop', '1.63.4'
9
+ gem 'rubocop', '1.65.1'
10
10
  gem 'sqlite3', '~> 1.4'
11
11
  gem 'timecop'
12
12
  gem 'unparser'
data/lib/chewy/config.rb CHANGED
@@ -70,12 +70,12 @@ module Chewy
70
70
  end
71
71
 
72
72
  def transport_logger=(logger)
73
- Chewy.client.transport.transport.logger = logger
73
+ Chewy.client.transport.logger = logger
74
74
  @transport_logger = logger
75
75
  end
76
76
 
77
77
  def transport_tracer=(tracer)
78
- Chewy.client.transport.transport.tracer = tracer
78
+ Chewy.client.transport.tracer = tracer
79
79
  @transport_tracer = tracer
80
80
  end
81
81
 
data/lib/chewy/errors.rb CHANGED
@@ -39,4 +39,7 @@ module Chewy
39
39
 
40
40
  class ImportScopeCleanupError < Error
41
41
  end
42
+
43
+ class FeatureDisabled < Error
44
+ end
42
45
  end
@@ -4,7 +4,7 @@ module Chewy
4
4
  attr_reader :dynamic_templates, :id
5
5
 
6
6
  def initialize(name, **options)
7
- super(name, **options)
7
+ super
8
8
 
9
9
  @value ||= -> { self }
10
10
  @dynamic_templates = []
@@ -32,7 +32,7 @@ module Chewy
32
32
  #
33
33
  def create(*args, **kwargs)
34
34
  create!(*args, **kwargs)
35
- rescue Elasticsearch::Transport::Transport::Errors::BadRequest
35
+ rescue Elastic::Transport::Transport::Errors::BadRequest
36
36
  false
37
37
  end
38
38
 
@@ -83,9 +83,9 @@ module Chewy
83
83
  result = client.indices.delete index: index_names.join(',')
84
84
  Chewy.wait_for_status if result
85
85
  result
86
- # es-ruby >= 1.0.10 handles Elasticsearch::Transport::Transport::Errors::NotFound
86
+ # es-ruby >= 1.0.10 handles Elastic::Transport::Transport::Errors::NotFound
87
87
  # by itself, rescue is for previous versions
88
- rescue Elasticsearch::Transport::Transport::Errors::NotFound
88
+ rescue Elastic::Transport::Transport::Errors::NotFound
89
89
  false
90
90
  end
91
91
 
@@ -99,9 +99,9 @@ module Chewy
99
99
  # UsersIndex.delete '01-2014' # deletes `users_01-2014` index
100
100
  #
101
101
  def delete!(suffix = nil)
102
- # es-ruby >= 1.0.10 handles Elasticsearch::Transport::Transport::Errors::NotFound
102
+ # es-ruby >= 1.0.10 handles Elastic::Transport::Transport::Errors::NotFound
103
103
  # by itself, so it is raised here
104
- delete(suffix) or raise Elasticsearch::Transport::Transport::Errors::NotFound
104
+ delete(suffix) or raise Elastic::Transport::Transport::Errors::NotFound
105
105
  end
106
106
 
107
107
  # Deletes and recreates index. Supports suffixes.
@@ -22,7 +22,7 @@ module Chewy
22
22
 
23
23
  def empty_if_not_found
24
24
  yield
25
- rescue Elasticsearch::Transport::Transport::Errors::NotFound
25
+ rescue Elastic::Transport::Transport::Errors::NotFound
26
26
  []
27
27
  end
28
28
  end
@@ -213,7 +213,7 @@ module Chewy
213
213
  @outdated_sync_field_type = mappings
214
214
  .fetch('properties', {})
215
215
  .fetch(@index.outdated_sync_field.to_s, {})['type']
216
- rescue Elasticsearch::Transport::Transport::Errors::NotFound
216
+ rescue Elastic::Transport::Transport::Errors::NotFound
217
217
  nil
218
218
  end
219
219
  end
@@ -142,7 +142,7 @@ module Chewy
142
142
  teardown do
143
143
  # always destroy indexes between tests
144
144
  # Prevent croll pollution of test cases due to indexing
145
- Chewy.massacre
145
+ drop_indices
146
146
  end
147
147
  end
148
148
  end
@@ -46,7 +46,7 @@ module Chewy
46
46
 
47
47
  delegate :hits, :wrappers, :objects, :records, :documents,
48
48
  :object_hash, :record_hash, :document_hash,
49
- :total, :max_score, :took, :timed_out?, to: :response
49
+ :total, :max_score, :took, :timed_out?, :terminated_early?, to: :response
50
50
  delegate :each, :size, :to_a, :[], to: :wrappers
51
51
  alias_method :to_ary, :to_a
52
52
  alias_method :total_count, :total
@@ -854,7 +854,7 @@ module Chewy
854
854
  else
855
855
  Chewy.client.count(only(WHERE_STORAGES).render)['count']
856
856
  end
857
- rescue Elasticsearch::Transport::Transport::Errors::NotFound
857
+ rescue Elastic::Transport::Transport::Errors::NotFound
858
858
  0
859
859
  end
860
860
 
@@ -891,7 +891,7 @@ module Chewy
891
891
  def first(limit = UNDEFINED)
892
892
  request_limit = limit == UNDEFINED ? 1 : limit
893
893
 
894
- if performed? && (request_limit <= size || size == total)
894
+ if performed? && (terminated_early? || request_limit <= size || size == total)
895
895
  limit == UNDEFINED ? wrappers.first : wrappers.first(limit)
896
896
  else
897
897
  result = except(EXTRA_STORAGES).limit(request_limit).to_a
@@ -1035,7 +1035,7 @@ module Chewy
1035
1035
  request_body = render.merge(additional)
1036
1036
  ActiveSupport::Notifications.instrument 'search_query.chewy', notification_payload(request: request_body) do
1037
1037
  Chewy.client.search(request_body)
1038
- rescue Elasticsearch::Transport::Transport::Errors::NotFound
1038
+ rescue Elastic::Transport::Transport::Errors::NotFound
1039
1039
  {}
1040
1040
  end
1041
1041
  end
@@ -47,6 +47,13 @@ module Chewy
47
47
  @timed_out ||= @body['timed_out']
48
48
  end
49
49
 
50
+ # Has the request been terminated early?
51
+ #
52
+ # @return [true, false]
53
+ def terminated_early?
54
+ @terminated_early ||= @body['terminated_early']
55
+ end
56
+
50
57
  # The `suggest` response part. Returns empty hash if suggests
51
58
  # were not requested.
52
59
  #
@@ -39,7 +39,8 @@ module Chewy
39
39
  hits = hits.first(last_batch_size) if last_batch_size != 0 && fetched >= total
40
40
  yield(hits) if hits.present?
41
41
  scroll_id = result['_scroll_id']
42
- break if fetched >= total
42
+
43
+ break if result['terminated_early'] || fetched >= total
43
44
 
44
45
  result = perform_scroll(scroll: scroll, scroll_id: scroll_id)
45
46
  end
data/lib/chewy/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Chewy
2
- VERSION = '7.6.0'.freeze
2
+ VERSION = '8.0.0-beta'.freeze
3
3
  end
data/lib/chewy.rb CHANGED
@@ -116,6 +116,10 @@ module Chewy
116
116
  # Be careful, if current prefix is blank, this will destroy all the indexes.
117
117
  #
118
118
  def massacre
119
+ unless Chewy.settings[:delete_all_enabled]
120
+ raise FeatureDisabled, 'Feature disabled by default in ES 8. You can enable it in the cluster and set `delete_all_enabled` option in settings'
121
+ end
122
+
119
123
  Chewy.client.indices.delete(index: [Chewy.configuration[:prefix], '*'].reject(&:blank?).join('_'))
120
124
  Chewy.wait_for_status
121
125
  end
@@ -22,7 +22,7 @@ describe Chewy::Config do
22
22
 
23
23
  specify do
24
24
  expect { subject.transport_logger = logger }
25
- .to change { Chewy.client.transport.transport.logger }.to(logger)
25
+ .to change { Chewy.client.transport.logger }.to(logger)
26
26
  end
27
27
  specify do
28
28
  expect { subject.transport_logger = logger }
@@ -40,7 +40,7 @@ describe Chewy::Config do
40
40
 
41
41
  specify do
42
42
  expect { subject.transport_tracer = tracer }
43
- .to change { Chewy.client.transport.transport.tracer }.to(tracer)
43
+ .to change { Chewy.client.transport.tracer }.to(tracer)
44
44
  end
45
45
  specify do
46
46
  expect { subject.transport_tracer = tracer }
@@ -6,7 +6,7 @@ describe Chewy::ElasticClient do
6
6
  let!(:filter_previous_value) { Chewy.before_es_request_filter }
7
7
 
8
8
  before do
9
- Chewy.massacre
9
+ drop_indices
10
10
  stub_index(:products) do
11
11
  field :id, type: :integer
12
12
  end
@@ -5,7 +5,7 @@ describe Chewy::Fields::Base do
5
5
  specify { expect(described_class.new('name', type: 'integer').options[:type]).to eq('integer') }
6
6
 
7
7
  describe '#compose' do
8
- let(:field) { described_class.new(:name, value: ->(o) { o.value }) }
8
+ let(:field) { described_class.new(:name, value: lambda(&:value)) }
9
9
 
10
10
  specify { expect(field.compose(double(value: 'hello'))).to eq(name: 'hello') }
11
11
  specify { expect(field.compose(double(value: %w[hello world]))).to eq(name: %w[hello world]) }
@@ -23,7 +23,7 @@ describe Chewy::Fields::Base do
23
23
 
24
24
  context 'nested fields' do
25
25
  before do
26
- field.children.push(described_class.new(:subname1, value: ->(o) { o.subvalue1 }))
26
+ field.children.push(described_class.new(:subname1, value: lambda(&:subvalue1)))
27
27
  field.children.push(described_class.new(:subname2, value: -> { subvalue2 }))
28
28
  field.children.push(described_class.new(:subname3))
29
29
  end
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe 'Time fields' do
4
- before { Chewy.massacre }
4
+ before { drop_indices }
5
5
 
6
6
  before do
7
7
  stub_index(:posts) do
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Chewy::Index::Actions do
4
- before { Chewy.massacre }
4
+ before { drop_indices }
5
5
 
6
6
  before do
7
7
  stub_index :dummies
@@ -78,12 +78,12 @@ describe Chewy::Index::Actions do
78
78
  specify do
79
79
  expect do
80
80
  DummiesIndex.create!
81
- end.to raise_error(Elasticsearch::Transport::Transport::Errors::BadRequest).with_message(/already exists.*dummies/)
81
+ end.to raise_error(Elastic::Transport::Transport::Errors::BadRequest).with_message(/already exists.*dummies/)
82
82
  end
83
83
  specify do
84
84
  expect do
85
85
  DummiesIndex.create!('2013')
86
- end.to raise_error(Elasticsearch::Transport::Transport::Errors::BadRequest).with_message(/Invalid alias name \[dummies\]/)
86
+ end.to raise_error(Elastic::Transport::Transport::Errors::BadRequest).with_message(/Invalid alias name \[dummies\]/)
87
87
  end
88
88
  end
89
89
 
@@ -100,7 +100,7 @@ describe Chewy::Index::Actions do
100
100
  specify do
101
101
  expect do
102
102
  DummiesIndex.create!('2013')
103
- end.to raise_error(Elasticsearch::Transport::Transport::Errors::BadRequest).with_message(/already exists.*dummies_2013/)
103
+ end.to raise_error(Elastic::Transport::Transport::Errors::BadRequest).with_message(/already exists.*dummies_2013/)
104
104
  end
105
105
  specify { expect(DummiesIndex.create!('2014')['acknowledged']).to eq(true) }
106
106
 
@@ -190,11 +190,11 @@ describe Chewy::Index::Actions do
190
190
  end
191
191
 
192
192
  describe '.delete!' do
193
- specify { expect { DummiesIndex.delete! }.to raise_error(Elasticsearch::Transport::Transport::Errors::NotFound) }
193
+ specify { expect { DummiesIndex.delete! }.to raise_error(Elastic::Transport::Transport::Errors::NotFound) }
194
194
  specify do
195
195
  expect do
196
196
  DummiesIndex.delete!('2013')
197
- end.to raise_error(Elasticsearch::Transport::Transport::Errors::NotFound)
197
+ end.to raise_error(Elastic::Transport::Transport::Errors::NotFound)
198
198
  end
199
199
 
200
200
  context do
@@ -768,7 +768,7 @@ describe Chewy::Index::Actions do
768
768
  .to receive(:clear_cache)
769
769
  .and_call_original
770
770
  expect { CitiesIndex.clear_cache({index: unexisted_index_name}) }
771
- .to raise_error Elasticsearch::Transport::Transport::Errors::NotFound
771
+ .to raise_error Elastic::Transport::Transport::Errors::NotFound
772
772
  end
773
773
  end
774
774
 
@@ -820,7 +820,7 @@ describe Chewy::Index::Actions do
820
820
  .to receive(:reindex)
821
821
  .and_call_original
822
822
  expect { CitiesIndex.reindex(source: unexisting_index, dest: dest_index_with_prefix) }
823
- .to raise_error Elasticsearch::Transport::Transport::Errors::NotFound
823
+ .to raise_error Elastic::Transport::Transport::Errors::NotFound
824
824
  end
825
825
  end
826
826
 
@@ -883,7 +883,7 @@ describe Chewy::Index::Actions do
883
883
  context 'index name' do
884
884
  specify do
885
885
  expect { CitiesIndex.update_mapping(unexisting_index, body_hash) }
886
- .to raise_error Elasticsearch::Transport::Transport::Errors::NotFound
886
+ .to raise_error Elastic::Transport::Transport::Errors::NotFound
887
887
  end
888
888
  end
889
889
 
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Chewy::Index::Aliases do
4
- before { Chewy.massacre }
4
+ before { drop_indices }
5
5
 
6
6
  before { stub_index :dummies }
7
7
 
@@ -17,7 +17,7 @@ SimpleComment = Class.new do
17
17
  end
18
18
 
19
19
  describe Chewy::Index::Import::BulkBuilder do
20
- before { Chewy.massacre }
20
+ before { drop_indices }
21
21
 
22
22
  subject { described_class.new(index, to_index: to_index, delete: delete, fields: fields) }
23
23
  let(:index) { CitiesIndex }
@@ -216,7 +216,7 @@ describe Chewy::Index::Import::BulkBuilder do
216
216
  end
217
217
 
218
218
  def do_raw_index_comment(options:, data:)
219
- CommentsIndex.client.index(options.merge(index: 'comments', type: '_doc', refresh: true, body: data))
219
+ CommentsIndex.client.index(options.merge(index: 'comments', refresh: true, body: data))
220
220
  end
221
221
 
222
222
  def raw_index_comment(comment)
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Chewy::Index::Import::BulkRequest do
4
- before { Chewy.massacre }
4
+ before { drop_indices }
5
5
 
6
6
  subject { described_class.new(index, suffix: suffix, bulk_size: bulk_size, **bulk_options) }
7
7
  let(:suffix) {}
@@ -2,7 +2,7 @@ require 'spec_helper'
2
2
 
3
3
  # TODO: add more specs here later
4
4
  describe Chewy::Index::Import::Routine do
5
- before { Chewy.massacre }
5
+ before { drop_indices }
6
6
  before do
7
7
  stub_index(:cities) do
8
8
  field :name
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Chewy::Index::Import do
4
- before { Chewy.massacre }
4
+ before { drop_indices }
5
5
 
6
6
  before do
7
7
  stub_model(:city)
@@ -204,10 +204,10 @@ describe Chewy::Index::Import do
204
204
  end
205
205
  end
206
206
 
207
- let(:mapper_parsing_exception) do
207
+ let(:document_parsing_exception) do
208
208
  {
209
- 'type' => 'mapper_parsing_exception',
210
- 'reason' => 'object mapping for [name] tried to parse field [name] as object, but found a concrete value'
209
+ 'type' => 'document_parsing_exception',
210
+ 'reason' => '[1:9] object mapping for [name] tried to parse field [name] as object, but found a concrete value'
211
211
  }
212
212
  end
213
213
 
@@ -215,7 +215,7 @@ describe Chewy::Index::Import do
215
215
  payload = subscribe_notification
216
216
  import dummy_cities, batch_size: 2
217
217
  expect(payload).to eq(index: CitiesIndex,
218
- errors: {index: {mapper_parsing_exception => %w[1 2 3]}},
218
+ errors: {index: {document_parsing_exception => %w[1 2 3]}},
219
219
  import: {index: 3})
220
220
  end
221
221
  end
@@ -270,8 +270,8 @@ describe Chewy::Index::Import do
270
270
  expect(payload).to eq(
271
271
  errors: {
272
272
  index: {{
273
- 'type' => 'mapper_parsing_exception',
274
- 'reason' => 'object mapping for [object] tried to parse field [object] as object, but found a concrete value'
273
+ 'type' => 'document_parsing_exception',
274
+ 'reason' => '[1:27] object mapping for [object] tried to parse field [object] as object, but found a concrete value'
275
275
  } => %w[2 4]}
276
276
  },
277
277
  import: {index: 6},
@@ -293,8 +293,8 @@ describe Chewy::Index::Import do
293
293
  expect(payload).to eq(
294
294
  errors: {
295
295
  index: {{
296
- 'type' => 'mapper_parsing_exception',
297
- 'reason' => 'object mapping for [object] tried to parse field [object] as object, but found a concrete value'
296
+ 'type' => 'document_parsing_exception',
297
+ 'reason' => '[1:27] object mapping for [object] tried to parse field [object] as object, but found a concrete value'
298
298
  } => %w[2 4]}
299
299
  },
300
300
  import: {index: 6},
@@ -319,8 +319,8 @@ describe Chewy::Index::Import do
319
319
  expect(payload).to eq(
320
320
  errors: {
321
321
  index: {{
322
- 'type' => 'mapper_parsing_exception',
323
- 'reason' => 'object mapping for [object] tried to parse field [object] as object, but found a concrete value'
322
+ 'type' => 'document_parsing_exception',
323
+ 'reason' => '[1:27] object mapping for [object] tried to parse field [object] as object, but found a concrete value'
324
324
  } => %w[2 4]}
325
325
  },
326
326
  import: {index: 6},
@@ -383,8 +383,8 @@ describe Chewy::Index::Import do
383
383
 
384
384
  # Full match doesn't work here.
385
385
  expect(payload[:errors][:update].keys).to match([
386
- hash_including('type' => 'document_missing_exception', 'reason' => '[_doc][1]: document missing'),
387
- hash_including('type' => 'document_missing_exception', 'reason' => '[_doc][3]: document missing')
386
+ hash_including('type' => 'document_missing_exception', 'reason' => '[1]: document missing'),
387
+ hash_including('type' => 'document_missing_exception', 'reason' => '[3]: document missing')
388
388
  ])
389
389
  expect(payload[:errors][:update].values).to eq([['1'], ['3']])
390
390
  expect(imported_cities).to match_array([
@@ -431,8 +431,8 @@ describe Chewy::Index::Import do
431
431
  expect(payload).to eq(
432
432
  errors: {
433
433
  update: {{
434
- 'type' => 'mapper_parsing_exception',
435
- 'reason' => 'object mapping for [object] tried to parse field [object] as object, but found a concrete value'
434
+ 'type' => 'document_parsing_exception',
435
+ 'reason' => '[1:26] object mapping for [object] tried to parse field [object] as object, but found a concrete value'
436
436
  } => %w[2 4]}
437
437
  },
438
438
  import: {index: 6},
@@ -21,7 +21,7 @@ describe Chewy::Index::Observe::Callback do
21
21
  end
22
22
 
23
23
  context 'when executable is has arity 1' do
24
- let(:executable) { ->(record) { record.population } }
24
+ let(:executable) { lambda(&:population) }
25
25
 
26
26
  it 'calls exectuable within context' do
27
27
  expect(callback.call(city)).to eq(city.population)
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Chewy::Index::Specification do
4
- before { Chewy.massacre }
4
+ before { drop_indices }
5
5
 
6
6
  let(:index1) do
7
7
  stub_index(:places) do
@@ -46,7 +46,6 @@ describe Chewy::Index::Specification do
46
46
  specify do
47
47
  expect { specification1.lock! }.to change { Chewy::Stash::Specification.all.hits }.from([]).to([{
48
48
  '_index' => 'chewy_specifications',
49
- '_type' => '_doc',
50
49
  '_id' => 'places',
51
50
  '_score' => 1.0,
52
51
  '_source' => {'specification' => Base64.encode64({
@@ -62,7 +61,6 @@ describe Chewy::Index::Specification do
62
61
  specify do
63
62
  expect { specification5.lock! }.to change { Chewy::Stash::Specification.all.hits }.to([{
64
63
  '_index' => 'chewy_specifications',
65
- '_type' => '_doc',
66
64
  '_id' => 'places',
67
65
  '_score' => 1.0,
68
66
  '_source' => {'specification' => Base64.encode64({
@@ -71,7 +69,6 @@ describe Chewy::Index::Specification do
71
69
  }.to_json)}
72
70
  }, {
73
71
  '_index' => 'chewy_specifications',
74
- '_type' => '_doc',
75
72
  '_id' => 'namespace/cities',
76
73
  '_score' => 1.0,
77
74
  '_source' => {'specification' => Base64.encode64({
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Chewy::Index::Syncer, :orm do
4
- before { Chewy.massacre }
4
+ before { drop_indices }
5
5
  before do
6
6
  stub_model(:city)
7
7
  stub_index(:cities) do
@@ -177,7 +177,7 @@ describe Chewy::Index do
177
177
 
178
178
  context do
179
179
  before do
180
- Chewy.massacre
180
+ drop_indices
181
181
  PlacesIndex.import!(
182
182
  double(colors: ['red']),
183
183
  double(colors: %w[red green]),
@@ -21,7 +21,7 @@ describe Chewy::Journal do
21
21
  default_import_options journal: true
22
22
  end
23
23
 
24
- Chewy.massacre
24
+ drop_indices
25
25
  Chewy.settings[:prefix] = 'some_prefix'
26
26
  Timecop.freeze(time)
27
27
  end
@@ -145,7 +145,7 @@ describe Chewy::Journal do
145
145
  end
146
146
 
147
147
  context do
148
- before { Chewy.massacre }
148
+ before { drop_indices }
149
149
  before do
150
150
  stub_model(:city) do
151
151
  update_index 'cities', :self
@@ -17,7 +17,7 @@ describe :minitest_helper do
17
17
  end
18
18
 
19
19
  before do
20
- Chewy.massacre
20
+ drop_indices
21
21
  end
22
22
 
23
23
  before do
@@ -2,7 +2,7 @@ require 'spec_helper'
2
2
  require 'chewy/multi_search'
3
3
 
4
4
  describe Chewy::MultiSearch do
5
- before { Chewy.massacre }
5
+ before { drop_indices }
6
6
 
7
7
  before do
8
8
  stub_model(:city)
@@ -2,7 +2,7 @@ require 'spec_helper'
2
2
  require 'rake'
3
3
 
4
4
  describe Chewy::RakeHelper, :orm do
5
- before { Chewy.massacre }
5
+ before { drop_indices }
6
6
 
7
7
  before do
8
8
  described_class.instance_variable_set(:@journal_exists, journal_exists)
@@ -9,7 +9,7 @@ describe :update_index do
9
9
  end
10
10
 
11
11
  before do
12
- Chewy.massacre
12
+ drop_indices
13
13
  DummiesIndex.create!
14
14
  end
15
15
 
@@ -3,7 +3,7 @@ require 'spec_helper'
3
3
  describe Chewy::Runtime do
4
4
  describe '.version' do
5
5
  specify { expect(described_class.version).to be_a(described_class::Version) }
6
- specify { expect(described_class.version).to be >= '7.0' }
7
- specify { expect(described_class.version).to be < '8.0' }
6
+ specify { expect(described_class.version).to be >= '8.0' }
7
+ specify { expect(described_class.version).to be < '9.0' }
8
8
  end
9
9
  end
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Chewy::Search::Loader do
4
- before { Chewy.massacre }
4
+ before { drop_indices }
5
5
 
6
6
  before do
7
7
  stub_model(:city)
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  shared_examples :kaminari do |request_base_class|
4
- before { Chewy.massacre }
4
+ before { drop_indices }
5
5
 
6
6
  before do
7
7
  stub_index(:products) do
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Chewy::Search::Request do
4
- before { Chewy.massacre }
4
+ before { drop_indices }
5
5
 
6
6
  before do
7
7
  stub_index(:products) do
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Chewy::Search::Response, :orm do
4
- before { Chewy.massacre }
4
+ before { drop_indices }
5
5
 
6
6
  before do
7
7
  stub_model(:city)
@@ -39,7 +39,7 @@ describe Chewy::Search::Response, :orm do
39
39
  specify { expect(subject.hits).to all be_a(Hash) }
40
40
  specify do
41
41
  expect(subject.hits.flat_map(&:keys).uniq)
42
- .to match_array(%w[_id _index _type _score _source sort])
42
+ .to match_array(%w[_id _index _score _source sort])
43
43
  end
44
44
 
45
45
  context do
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Chewy::Search::Scrolling, :orm do
4
- before { Chewy.massacre }
4
+ before { drop_indices }
5
5
 
6
6
  before do
7
7
  stub_model(:city)
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Chewy::Search do
4
- before { Chewy.massacre }
4
+ before { drop_indices }
5
5
 
6
6
  before do
7
7
  stub_index(:products)
@@ -5,7 +5,7 @@ describe Chewy::Stash::Journal, :orm do
5
5
  response['deleted'] || response['_indices']['_all']['deleted']
6
6
  end
7
7
 
8
- before { Chewy.massacre }
8
+ before { drop_indices }
9
9
 
10
10
  before do
11
11
  stub_model(:city)
@@ -134,7 +134,7 @@ if defined?(Sidekiq)
134
134
  context 'both calls with different update fields' do
135
135
  it 'deos reindex with union of fields' do
136
136
  Timecop.freeze do
137
- expect(CitiesIndex).to receive(:import!).with(match_array([city.id, other_city.id]), update_fields: %w[name description]).once
137
+ expect(CitiesIndex).to receive(:import!).with(match_array([city.id, other_city.id]), update_fields: match_array(%w[name description])).once
138
138
  scheduler = Chewy::Strategy::DelayedSidekiq::Scheduler.new(CitiesIndex, [city.id], update_fields: ['name'])
139
139
  scheduler.postpone
140
140
  scheduler = Chewy::Strategy::DelayedSidekiq::Scheduler.new(CitiesIndex, [other_city.id], update_fields: ['description'])
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Chewy::Strategy do
4
- before { Chewy.massacre }
4
+ before { drop_indices }
5
5
  subject(:strategy) { Chewy::Strategy.new }
6
6
 
7
7
  describe '#current' do
data/spec/chewy_spec.rb CHANGED
@@ -31,8 +31,8 @@ describe Chewy do
31
31
  end
32
32
  end
33
33
 
34
- describe '.massacre' do
35
- before { Chewy.massacre }
34
+ xdescribe '.massacre' do
35
+ before { drop_indices }
36
36
 
37
37
  before do
38
38
  allow(Chewy).to receive_messages(configuration: Chewy.configuration.merge(prefix: 'prefix1'))
@@ -40,7 +40,7 @@ describe Chewy do
40
40
  allow(Chewy).to receive_messages(configuration: Chewy.configuration.merge(prefix: 'prefix2'))
41
41
  stub_index(:developers).create!
42
42
 
43
- Chewy.massacre
43
+ drop_indices
44
44
 
45
45
  allow(Chewy).to receive_messages(configuration: Chewy.configuration.merge(prefix: 'prefix1'))
46
46
  end
@@ -84,7 +84,8 @@ describe Chewy do
84
84
  # To avoid flaky issues when previous specs were run
85
85
  allow(Chewy::Index).to receive(:descendants).and_return([CitiesIndex, PlacesIndex])
86
86
 
87
- Chewy.massacre
87
+ CitiesIndex.delete
88
+ PlacesIndex.delete
88
89
  end
89
90
 
90
91
  specify do
@@ -111,7 +112,7 @@ describe Chewy do
111
112
  expect(CitiesIndex.exists?).to eq true
112
113
  expect(PlacesIndex.exists?).to eq true
113
114
 
114
- expect { Chewy.create_indices! }.to raise_error(Elasticsearch::Transport::Transport::Errors::BadRequest)
115
+ expect { Chewy.create_indices! }.to raise_error(Elastic::Transport::Transport::Errors::BadRequest)
115
116
  end
116
117
  end
117
118
  end
data/spec/spec_helper.rb CHANGED
@@ -28,6 +28,32 @@ Chewy.settings = {
28
28
  }
29
29
  }
30
30
 
31
+ # To work with security enabled:
32
+ #
33
+ # user = ENV['ES_USER'] || 'elastic'
34
+ # password = ENV['ES_PASSWORD'] || ''
35
+ # ca_cert = ENV['ES_CA_CERT'] || './tmp/http_ca.crt'
36
+ #
37
+ # Chewy.settings.merge!(
38
+ # user: user,
39
+ # password: password,
40
+ # transport_options: {
41
+ # ssl: {
42
+ # ca_file: ca_cert
43
+ # }
44
+ # }
45
+ # )
46
+
47
+ # Low-level substitute for now-obsolete drop_indices
48
+ def drop_indices
49
+ response = Chewy.client.cat.indices
50
+ indices = response.body.lines.map { |line| line.split[2] }
51
+ return if indices.blank?
52
+
53
+ Chewy.client.indices.delete(index: indices)
54
+ Chewy.wait_for_status
55
+ end
56
+
31
57
  # Chewy.transport_logger = Logger.new(STDERR)
32
58
 
33
59
  RSpec.configure do |config|
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chewy
3
3
  version: !ruby/object:Gem::Version
4
- version: 7.6.0
4
+ version: 8.0.0.pre.beta
5
5
  platform: ruby
6
6
  authors:
7
7
  - Toptal, LLC
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2024-05-06 00:00:00.000000000 Z
12
+ date: 2024-09-04 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
@@ -17,34 +17,34 @@ dependencies:
17
17
  requirements:
18
18
  - - ">="
19
19
  - !ruby/object:Gem::Version
20
- version: '5.2'
20
+ version: '6.1'
21
21
  type: :runtime
22
22
  prerelease: false
23
23
  version_requirements: !ruby/object:Gem::Requirement
24
24
  requirements:
25
25
  - - ">="
26
26
  - !ruby/object:Gem::Version
27
- version: '5.2'
27
+ version: '6.1'
28
28
  - !ruby/object:Gem::Dependency
29
29
  name: elasticsearch
30
30
  requirement: !ruby/object:Gem::Requirement
31
31
  requirements:
32
32
  - - ">="
33
33
  - !ruby/object:Gem::Version
34
- version: 7.14.0
34
+ version: '8.14'
35
35
  - - "<"
36
36
  - !ruby/object:Gem::Version
37
- version: '8'
37
+ version: '9.0'
38
38
  type: :runtime
39
39
  prerelease: false
40
40
  version_requirements: !ruby/object:Gem::Requirement
41
41
  requirements:
42
42
  - - ">="
43
43
  - !ruby/object:Gem::Version
44
- version: 7.14.0
44
+ version: '8.14'
45
45
  - - "<"
46
46
  - !ruby/object:Gem::Version
47
- version: '8'
47
+ version: '9.0'
48
48
  - !ruby/object:Gem::Dependency
49
49
  name: elasticsearch-dsl
50
50
  requirement: !ruby/object:Gem::Requirement
@@ -88,6 +88,7 @@ files:
88
88
  - README.md
89
89
  - Rakefile
90
90
  - chewy.gemspec
91
+ - docker-compose.yml
91
92
  - filters
92
93
  - gemfiles/base.gemfile
93
94
  - gemfiles/rails.6.1.activerecord.gemfile
@@ -311,14 +312,14 @@ require_paths:
311
312
  - lib
312
313
  required_ruby_version: !ruby/object:Gem::Requirement
313
314
  requirements:
314
- - - ">="
315
+ - - "~>"
315
316
  - !ruby/object:Gem::Version
316
- version: '0'
317
+ version: '3.0'
317
318
  required_rubygems_version: !ruby/object:Gem::Requirement
318
319
  requirements:
319
- - - ">="
320
+ - - ">"
320
321
  - !ruby/object:Gem::Version
321
- version: '0'
322
+ version: 1.3.1
322
323
  requirements: []
323
324
  rubygems_version: 3.4.10
324
325
  signing_key: