chewy 6.0.0 → 7.5.1
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.
- checksums.yaml +4 -4
- data/.github/CODEOWNERS +1 -0
- data/.github/ISSUE_TEMPLATE/bug_report.md +39 -0
- data/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
- data/.github/PULL_REQUEST_TEMPLATE.md +16 -0
- data/.github/dependabot.yml +42 -0
- data/.github/workflows/ruby.yml +48 -0
- data/.rubocop.yml +16 -8
- data/.rubocop_todo.yml +110 -22
- data/CHANGELOG.md +385 -105
- data/CODE_OF_CONDUCT.md +14 -0
- data/CONTRIBUTING.md +63 -0
- data/Gemfile +4 -10
- data/Guardfile +3 -1
- data/README.md +494 -275
- data/chewy.gemspec +5 -20
- data/gemfiles/base.gemfile +12 -0
- data/gemfiles/rails.6.1.activerecord.gemfile +10 -15
- data/gemfiles/rails.7.0.activerecord.gemfile +14 -0
- data/gemfiles/rails.7.1.activerecord.gemfile +14 -0
- data/lib/chewy/config.rb +58 -50
- data/lib/chewy/elastic_client.rb +31 -0
- data/lib/chewy/errors.rb +7 -10
- data/lib/chewy/fields/base.rb +79 -13
- data/lib/chewy/fields/root.rb +4 -14
- data/lib/chewy/index/actions.rb +54 -37
- data/lib/chewy/{type → index}/adapter/active_record.rb +30 -6
- data/lib/chewy/{type → index}/adapter/base.rb +2 -3
- data/lib/chewy/{type → index}/adapter/object.rb +27 -31
- data/lib/chewy/{type → index}/adapter/orm.rb +17 -18
- data/lib/chewy/index/aliases.rb +14 -5
- data/lib/chewy/index/crutch.rb +40 -0
- data/lib/chewy/index/import/bulk_builder.rb +311 -0
- data/lib/chewy/{type → index}/import/bulk_request.rb +6 -7
- data/lib/chewy/{type → index}/import/journal_builder.rb +11 -12
- data/lib/chewy/{type → index}/import/routine.rb +18 -17
- data/lib/chewy/{type → index}/import.rb +76 -32
- data/lib/chewy/{type → index}/mapping.rb +29 -34
- data/lib/chewy/index/observe/active_record_methods.rb +87 -0
- data/lib/chewy/index/observe/callback.rb +34 -0
- data/lib/chewy/index/observe.rb +17 -0
- data/lib/chewy/index/specification.rb +1 -0
- data/lib/chewy/{type → index}/syncer.rb +59 -59
- data/lib/chewy/{type → index}/witchcraft.rb +11 -7
- data/lib/chewy/{type → index}/wrapper.rb +2 -2
- data/lib/chewy/index.rb +67 -94
- data/lib/chewy/journal.rb +25 -14
- data/lib/chewy/log_subscriber.rb +5 -1
- data/lib/chewy/minitest/helpers.rb +86 -13
- data/lib/chewy/minitest/search_index_receiver.rb +24 -26
- data/lib/chewy/railtie.rb +6 -20
- data/lib/chewy/rake_helper.rb +169 -113
- data/lib/chewy/rspec/build_query.rb +12 -0
- data/lib/chewy/rspec/helpers.rb +55 -0
- data/lib/chewy/rspec/update_index.rb +55 -44
- data/lib/chewy/rspec.rb +2 -0
- data/lib/chewy/runtime/version.rb +1 -1
- data/lib/chewy/runtime.rb +1 -1
- data/lib/chewy/search/loader.rb +19 -41
- data/lib/chewy/search/parameters/collapse.rb +16 -0
- data/lib/chewy/search/parameters/concerns/query_storage.rb +2 -2
- data/lib/chewy/search/parameters/ignore_unavailable.rb +27 -0
- data/lib/chewy/search/parameters/indices.rb +13 -58
- data/lib/chewy/search/parameters/knn.rb +16 -0
- data/lib/chewy/search/parameters/order.rb +6 -19
- data/lib/chewy/search/parameters/source.rb +5 -1
- data/lib/chewy/search/parameters/storage.rb +1 -1
- data/lib/chewy/search/parameters/track_total_hits.rb +16 -0
- data/lib/chewy/search/parameters.rb +6 -4
- data/lib/chewy/search/query_proxy.rb +9 -2
- data/lib/chewy/search/request.rb +169 -134
- data/lib/chewy/search/response.rb +5 -5
- data/lib/chewy/search/scoping.rb +7 -8
- data/lib/chewy/search/scrolling.rb +13 -13
- data/lib/chewy/search.rb +9 -19
- data/lib/chewy/stash.rb +19 -30
- data/lib/chewy/strategy/active_job.rb +1 -1
- data/lib/chewy/strategy/atomic_no_refresh.rb +18 -0
- data/lib/chewy/strategy/base.rb +10 -0
- data/lib/chewy/strategy/delayed_sidekiq/scheduler.rb +151 -0
- data/lib/chewy/strategy/delayed_sidekiq/worker.rb +52 -0
- data/lib/chewy/strategy/delayed_sidekiq.rb +30 -0
- data/lib/chewy/strategy/lazy_sidekiq.rb +64 -0
- data/lib/chewy/strategy/sidekiq.rb +2 -1
- data/lib/chewy/strategy.rb +6 -19
- data/lib/chewy/version.rb +1 -1
- data/lib/chewy.rb +39 -86
- data/lib/generators/chewy/install_generator.rb +1 -1
- data/lib/tasks/chewy.rake +36 -32
- data/migration_guide.md +46 -8
- data/spec/chewy/config_spec.rb +14 -39
- data/spec/chewy/elastic_client_spec.rb +26 -0
- data/spec/chewy/fields/base_spec.rb +432 -147
- data/spec/chewy/fields/root_spec.rb +20 -28
- data/spec/chewy/fields/time_fields_spec.rb +5 -5
- data/spec/chewy/index/actions_spec.rb +368 -59
- data/spec/chewy/{type → index}/adapter/active_record_spec.rb +156 -40
- data/spec/chewy/{type → index}/adapter/object_spec.rb +21 -6
- data/spec/chewy/index/aliases_spec.rb +3 -3
- data/spec/chewy/index/import/bulk_builder_spec.rb +494 -0
- data/spec/chewy/{type → index}/import/bulk_request_spec.rb +5 -12
- data/spec/chewy/{type → index}/import/journal_builder_spec.rb +9 -19
- data/spec/chewy/{type → index}/import/routine_spec.rb +19 -19
- data/spec/chewy/{type → index}/import_spec.rb +164 -98
- data/spec/chewy/index/mapping_spec.rb +135 -0
- data/spec/chewy/index/observe/active_record_methods_spec.rb +68 -0
- data/spec/chewy/index/observe/callback_spec.rb +139 -0
- data/spec/chewy/index/observe_spec.rb +143 -0
- data/spec/chewy/index/settings_spec.rb +3 -1
- data/spec/chewy/index/specification_spec.rb +20 -30
- data/spec/chewy/{type → index}/syncer_spec.rb +14 -19
- data/spec/chewy/{type → index}/witchcraft_spec.rb +20 -22
- data/spec/chewy/index/wrapper_spec.rb +100 -0
- data/spec/chewy/index_spec.rb +60 -105
- data/spec/chewy/journal_spec.rb +25 -74
- data/spec/chewy/minitest/helpers_spec.rb +123 -15
- data/spec/chewy/minitest/search_index_receiver_spec.rb +28 -30
- data/spec/chewy/multi_search_spec.rb +4 -5
- data/spec/chewy/rake_helper_spec.rb +315 -55
- data/spec/chewy/rspec/build_query_spec.rb +34 -0
- data/spec/chewy/rspec/helpers_spec.rb +61 -0
- data/spec/chewy/rspec/update_index_spec.rb +74 -71
- data/spec/chewy/runtime_spec.rb +2 -2
- data/spec/chewy/search/loader_spec.rb +19 -53
- data/spec/chewy/search/pagination/kaminari_examples.rb +4 -6
- data/spec/chewy/search/pagination/kaminari_spec.rb +2 -2
- data/spec/chewy/search/parameters/collapse_spec.rb +5 -0
- data/spec/chewy/search/parameters/ignore_unavailable_spec.rb +67 -0
- data/spec/chewy/search/parameters/indices_spec.rb +26 -117
- data/spec/chewy/search/parameters/knn_spec.rb +5 -0
- data/spec/chewy/search/parameters/order_spec.rb +18 -11
- data/spec/chewy/search/parameters/query_storage_examples.rb +67 -21
- data/spec/chewy/search/parameters/search_after_spec.rb +4 -1
- data/spec/chewy/search/parameters/source_spec.rb +8 -2
- data/spec/chewy/search/parameters/track_total_hits_spec.rb +5 -0
- data/spec/chewy/search/parameters_spec.rb +18 -4
- data/spec/chewy/search/query_proxy_spec.rb +68 -17
- data/spec/chewy/search/request_spec.rb +292 -110
- data/spec/chewy/search/response_spec.rb +12 -12
- data/spec/chewy/search/scrolling_spec.rb +10 -17
- data/spec/chewy/search_spec.rb +40 -34
- data/spec/chewy/stash_spec.rb +9 -21
- data/spec/chewy/strategy/active_job_spec.rb +16 -16
- data/spec/chewy/strategy/atomic_no_refresh_spec.rb +60 -0
- data/spec/chewy/strategy/atomic_spec.rb +9 -10
- data/spec/chewy/strategy/delayed_sidekiq_spec.rb +202 -0
- data/spec/chewy/strategy/lazy_sidekiq_spec.rb +214 -0
- data/spec/chewy/strategy/sidekiq_spec.rb +12 -12
- data/spec/chewy/strategy_spec.rb +19 -15
- data/spec/chewy_spec.rb +24 -107
- data/spec/spec_helper.rb +3 -22
- data/spec/support/active_record.rb +25 -7
- metadata +78 -339
- data/.circleci/config.yml +0 -240
- data/Appraisals +0 -81
- data/gemfiles/rails.5.2.activerecord.gemfile +0 -17
- data/gemfiles/rails.5.2.mongoid.6.4.gemfile +0 -17
- data/gemfiles/rails.6.0.activerecord.gemfile +0 -17
- data/gemfiles/sequel.4.45.gemfile +0 -11
- data/lib/chewy/backports/deep_dup.rb +0 -46
- data/lib/chewy/backports/duplicable.rb +0 -91
- data/lib/chewy/search/pagination/will_paginate.rb +0 -43
- data/lib/chewy/search/parameters/types.rb +0 -20
- data/lib/chewy/strategy/resque.rb +0 -27
- data/lib/chewy/strategy/shoryuken.rb +0 -40
- data/lib/chewy/type/actions.rb +0 -43
- data/lib/chewy/type/adapter/mongoid.rb +0 -67
- data/lib/chewy/type/adapter/sequel.rb +0 -93
- data/lib/chewy/type/crutch.rb +0 -32
- data/lib/chewy/type/import/bulk_builder.rb +0 -122
- data/lib/chewy/type/observe.rb +0 -82
- data/lib/chewy/type.rb +0 -120
- data/lib/sequel/plugins/chewy_observe.rb +0 -63
- data/spec/chewy/search/pagination/will_paginate_examples.rb +0 -63
- data/spec/chewy/search/pagination/will_paginate_spec.rb +0 -23
- data/spec/chewy/search/parameters/types_spec.rb +0 -5
- data/spec/chewy/strategy/resque_spec.rb +0 -46
- data/spec/chewy/strategy/shoryuken_spec.rb +0 -70
- data/spec/chewy/type/actions_spec.rb +0 -50
- data/spec/chewy/type/adapter/mongoid_spec.rb +0 -372
- data/spec/chewy/type/adapter/sequel_spec.rb +0 -472
- data/spec/chewy/type/import/bulk_builder_spec.rb +0 -194
- data/spec/chewy/type/mapping_spec.rb +0 -175
- data/spec/chewy/type/observe_spec.rb +0 -137
- data/spec/chewy/type/wrapper_spec.rb +0 -100
- data/spec/chewy/type_spec.rb +0 -55
- data/spec/support/mongoid.rb +0 -93
- data/spec/support/sequel.rb +0 -80
@@ -1,26 +1,29 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
+
require 'rake'
|
2
3
|
|
3
4
|
describe Chewy::RakeHelper, :orm do
|
4
5
|
before { Chewy.massacre }
|
5
6
|
|
6
7
|
before do
|
8
|
+
described_class.instance_variable_set(:@journal_exists, journal_exists)
|
9
|
+
|
7
10
|
stub_model(:city)
|
8
11
|
stub_model(:country)
|
9
12
|
|
10
13
|
stub_index(:cities) do
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
end
|
14
|
+
index_scope City
|
15
|
+
field :name
|
16
|
+
field :updated_at, type: 'date'
|
15
17
|
end
|
16
18
|
stub_index(:countries) do
|
17
|
-
|
19
|
+
index_scope Country
|
18
20
|
end
|
19
21
|
stub_index(:users)
|
20
22
|
|
21
23
|
allow(described_class).to receive(:all_indexes) { [CitiesIndex, CountriesIndex, UsersIndex] }
|
22
24
|
end
|
23
25
|
|
26
|
+
let(:journal_exists) { true }
|
24
27
|
let!(:cities) { Array.new(3) { |i| City.create!(name: "Name#{i + 1}") } }
|
25
28
|
let!(:countries) { Array.new(2) { |i| Country.create!(name: "Name#{i + 1}") } }
|
26
29
|
let(:journal) do
|
@@ -52,17 +55,18 @@ describe Chewy::RakeHelper, :orm do
|
|
52
55
|
.to update_index(CitiesIndex)
|
53
56
|
expect(output.string).to match(Regexp.new(<<-OUTPUT, Regexp::MULTILINE))
|
54
57
|
\\AResetting CitiesIndex
|
55
|
-
Imported CitiesIndex
|
56
|
-
Applying journal to \\[CitiesIndex
|
57
|
-
Imported CitiesIndex
|
58
|
-
Imported Chewy::Stash::Specification
|
58
|
+
Imported CitiesIndex in \\d+s, stats: index 3
|
59
|
+
Applying journal to \\[CitiesIndex\\], 2 entries, stage 1
|
60
|
+
Imported CitiesIndex in \\d+s, stats: index 2
|
61
|
+
Imported Chewy::Stash::Specification in \\d+s, stats: index 1
|
59
62
|
Resetting CountriesIndex
|
60
|
-
Imported CountriesIndex
|
61
|
-
Applying journal to \\[CountriesIndex
|
62
|
-
Imported CountriesIndex
|
63
|
-
Imported Chewy::Stash::Specification
|
63
|
+
Imported CountriesIndex in \\d+s, stats: index 2
|
64
|
+
Applying journal to \\[CountriesIndex\\], 1 entries, stage 1
|
65
|
+
Imported CountriesIndex in \\d+s, stats: index 1
|
66
|
+
Imported Chewy::Stash::Specification in \\d+s, stats: index 1
|
64
67
|
Resetting UsersIndex
|
65
|
-
Imported
|
68
|
+
Imported UsersIndex in 1s, stats:\s
|
69
|
+
Imported Chewy::Stash::Specification in \\d+s, stats: index 1
|
66
70
|
Total: \\d+s\\Z
|
67
71
|
OUTPUT
|
68
72
|
end
|
@@ -73,10 +77,10 @@ Total: \\d+s\\Z
|
|
73
77
|
.to update_index(CitiesIndex)
|
74
78
|
expect(output.string).to match(Regexp.new(<<-OUTPUT, Regexp::MULTILINE))
|
75
79
|
\\AResetting CitiesIndex
|
76
|
-
Imported CitiesIndex
|
77
|
-
Applying journal to \\[CitiesIndex
|
78
|
-
Imported CitiesIndex
|
79
|
-
Imported Chewy::Stash::Specification
|
80
|
+
Imported CitiesIndex in \\d+s, stats: index 3
|
81
|
+
Applying journal to \\[CitiesIndex\\], 2 entries, stage 1
|
82
|
+
Imported CitiesIndex in \\d+s, stats: index 2
|
83
|
+
Imported Chewy::Stash::Specification in \\d+s, stats: index 1
|
80
84
|
Total: \\d+s\\Z
|
81
85
|
OUTPUT
|
82
86
|
end
|
@@ -87,10 +91,27 @@ Total: \\d+s\\Z
|
|
87
91
|
.not_to update_index(CitiesIndex)
|
88
92
|
expect(output.string).to match(Regexp.new(<<-OUTPUT, Regexp::MULTILINE))
|
89
93
|
\\AResetting UsersIndex
|
90
|
-
Imported
|
94
|
+
Imported UsersIndex in 1s, stats:\s
|
95
|
+
Imported Chewy::Stash::Specification in \\d+s, stats: index 1
|
91
96
|
Total: \\d+s\\Z
|
92
97
|
OUTPUT
|
93
98
|
end
|
99
|
+
|
100
|
+
context 'when journal is missing' do
|
101
|
+
let(:journal_exists) { false }
|
102
|
+
|
103
|
+
specify do
|
104
|
+
output = StringIO.new
|
105
|
+
expect { described_class.reset(only: [CitiesIndex], output: output) }
|
106
|
+
.to update_index(CitiesIndex)
|
107
|
+
expect(output.string).to include(
|
108
|
+
"############################################################\n" \
|
109
|
+
"WARN: You are risking to lose some changes during the reset.\n " \
|
110
|
+
"Please consider enabling journaling.\n " \
|
111
|
+
'See https://github.com/toptal/chewy#journaling'
|
112
|
+
)
|
113
|
+
end
|
114
|
+
end
|
94
115
|
end
|
95
116
|
|
96
117
|
describe '.upgrade' do
|
@@ -100,13 +121,14 @@ Total: \\d+s\\Z
|
|
100
121
|
.to update_index(CitiesIndex)
|
101
122
|
expect(output.string).to match(Regexp.new(<<-OUTPUT, Regexp::MULTILINE))
|
102
123
|
\\AResetting CitiesIndex
|
103
|
-
Imported CitiesIndex
|
104
|
-
Imported Chewy::Stash::Specification
|
124
|
+
Imported CitiesIndex in \\d+s, stats: index 3
|
125
|
+
Imported Chewy::Stash::Specification in \\d+s, stats: index 1
|
105
126
|
Resetting CountriesIndex
|
106
|
-
Imported CountriesIndex
|
107
|
-
Imported Chewy::Stash::Specification
|
127
|
+
Imported CountriesIndex in \\d+s, stats: index 2
|
128
|
+
Imported Chewy::Stash::Specification in \\d+s, stats: index 1
|
108
129
|
Resetting UsersIndex
|
109
|
-
Imported
|
130
|
+
Imported UsersIndex in 1s, stats:\s
|
131
|
+
Imported Chewy::Stash::Specification in \\d+s, stats: index 1
|
110
132
|
Total: \\d+s\\Z
|
111
133
|
OUTPUT
|
112
134
|
end
|
@@ -125,7 +147,8 @@ Total: \\d+s\\Z
|
|
125
147
|
\\ASkipping CitiesIndex, the specification didn't change
|
126
148
|
Skipping CountriesIndex, the specification didn't change
|
127
149
|
Resetting UsersIndex
|
128
|
-
Imported
|
150
|
+
Imported UsersIndex in 1s, stats:\s
|
151
|
+
Imported Chewy::Stash::Specification in \\d+s, stats: index 1
|
129
152
|
Total: \\d+s\\Z
|
130
153
|
OUTPUT
|
131
154
|
end
|
@@ -136,7 +159,8 @@ Total: \\d+s\\Z
|
|
136
159
|
.not_to update_index(CitiesIndex)
|
137
160
|
expect(output.string).to match(Regexp.new(<<-OUTPUT, Regexp::MULTILINE))
|
138
161
|
\\AResetting UsersIndex
|
139
|
-
Imported
|
162
|
+
Imported UsersIndex in 1s, stats:\s
|
163
|
+
Imported Chewy::Stash::Specification in \\d+s, stats: index 1
|
140
164
|
Total: \\d+s\\Z
|
141
165
|
OUTPUT
|
142
166
|
end
|
@@ -165,6 +189,7 @@ Total: \\d+s\\Z
|
|
165
189
|
expect(output.string).to match(Regexp.new(<<-OUTPUT, Regexp::MULTILINE))
|
166
190
|
\\ASkipping CitiesIndex, it does not exists \\(use rake chewy:reset\\[cities\\] to create and update it\\)
|
167
191
|
Skipping CountriesIndex, it does not exists \\(use rake chewy:reset\\[countries\\] to create and update it\\)
|
192
|
+
Skipping UsersIndex, it does not exists \\(use rake chewy:reset\\[users\\] to create and update it\\)
|
168
193
|
Total: \\d+s\\Z
|
169
194
|
OUTPUT
|
170
195
|
end
|
@@ -181,9 +206,10 @@ Total: \\d+s\\Z
|
|
181
206
|
.to update_index(CitiesIndex)
|
182
207
|
expect(output.string).to match(Regexp.new(<<-OUTPUT, Regexp::MULTILINE))
|
183
208
|
\\AUpdating CitiesIndex
|
184
|
-
Imported CitiesIndex
|
209
|
+
Imported CitiesIndex in \\d+s, stats: index 3
|
185
210
|
Updating CountriesIndex
|
186
|
-
Imported CountriesIndex
|
211
|
+
Imported CountriesIndex in \\d+s, stats: index 2
|
212
|
+
Skipping UsersIndex, it does not exists \\(use rake chewy:reset\\[users\\] to create and update it\\)
|
187
213
|
Total: \\d+s\\Z
|
188
214
|
OUTPUT
|
189
215
|
end
|
@@ -194,7 +220,7 @@ Total: \\d+s\\Z
|
|
194
220
|
.not_to update_index(CitiesIndex)
|
195
221
|
expect(output.string).to match(Regexp.new(<<-OUTPUT, Regexp::MULTILINE))
|
196
222
|
\\AUpdating CountriesIndex
|
197
|
-
Imported CountriesIndex
|
223
|
+
Imported CountriesIndex in \\d+s, stats: index 2
|
198
224
|
Total: \\d+s\\Z
|
199
225
|
OUTPUT
|
200
226
|
end
|
@@ -205,7 +231,8 @@ Total: \\d+s\\Z
|
|
205
231
|
.to update_index(CitiesIndex)
|
206
232
|
expect(output.string).to match(Regexp.new(<<-OUTPUT, Regexp::MULTILINE))
|
207
233
|
\\AUpdating CitiesIndex
|
208
|
-
Imported CitiesIndex
|
234
|
+
Imported CitiesIndex in \\d+s, stats: index 3
|
235
|
+
Skipping UsersIndex, it does not exists \\(use rake chewy:reset\\[users\\] to create and update it\\)
|
209
236
|
Total: \\d+s\\Z
|
210
237
|
OUTPUT
|
211
238
|
end
|
@@ -218,15 +245,19 @@ Total: \\d+s\\Z
|
|
218
245
|
expect { described_class.sync(output: output) }
|
219
246
|
.to update_index(CitiesIndex)
|
220
247
|
expect(output.string).to match(Regexp.new(<<-OUTPUT, Regexp::MULTILINE))
|
221
|
-
\\ASynchronizing CitiesIndex
|
222
|
-
Imported CitiesIndex
|
248
|
+
\\ASynchronizing CitiesIndex
|
249
|
+
Imported CitiesIndex in \\d+s, stats: index 3
|
223
250
|
Missing documents: \\[[^\\]]+\\]
|
224
251
|
Took \\d+s
|
225
|
-
Synchronizing CountriesIndex
|
226
|
-
CountriesIndex
|
227
|
-
Imported CountriesIndex
|
252
|
+
Synchronizing CountriesIndex
|
253
|
+
CountriesIndex doesn't support outdated synchronization
|
254
|
+
Imported CountriesIndex in \\d+s, stats: index 2
|
228
255
|
Missing documents: \\[[^\\]]+\\]
|
229
256
|
Took \\d+s
|
257
|
+
Synchronizing UsersIndex
|
258
|
+
UsersIndex doesn't support outdated synchronization
|
259
|
+
Skipping UsersIndex, up to date
|
260
|
+
Took \\d+s
|
230
261
|
Total: \\d+s\\Z
|
231
262
|
OUTPUT
|
232
263
|
end
|
@@ -236,7 +267,6 @@ Total: \\d+s\\Z
|
|
236
267
|
CitiesIndex.import(cities.first(2))
|
237
268
|
CountriesIndex.import
|
238
269
|
|
239
|
-
sleep(1) if ActiveSupport::VERSION::STRING < '4.1.0'
|
240
270
|
cities.first.update(name: 'Name5')
|
241
271
|
end
|
242
272
|
|
@@ -245,14 +275,18 @@ Total: \\d+s\\Z
|
|
245
275
|
expect { described_class.sync(output: output) }
|
246
276
|
.to update_index(CitiesIndex)
|
247
277
|
expect(output.string).to match(Regexp.new(<<-OUTPUT, Regexp::MULTILINE))
|
248
|
-
\\ASynchronizing CitiesIndex
|
249
|
-
Imported CitiesIndex
|
278
|
+
\\ASynchronizing CitiesIndex
|
279
|
+
Imported CitiesIndex in \\d+s, stats: index 2
|
250
280
|
Missing documents: \\["#{cities.last.id}"\\]
|
251
281
|
Outdated documents: \\["#{cities.first.id}"\\]
|
252
282
|
Took \\d+s
|
253
|
-
Synchronizing CountriesIndex
|
254
|
-
CountriesIndex
|
255
|
-
Skipping CountriesIndex
|
283
|
+
Synchronizing CountriesIndex
|
284
|
+
CountriesIndex doesn't support outdated synchronization
|
285
|
+
Skipping CountriesIndex, up to date
|
286
|
+
Took \\d+s
|
287
|
+
Synchronizing UsersIndex
|
288
|
+
UsersIndex doesn't support outdated synchronization
|
289
|
+
Skipping UsersIndex, up to date
|
256
290
|
Took \\d+s
|
257
291
|
Total: \\d+s\\Z
|
258
292
|
OUTPUT
|
@@ -263,8 +297,8 @@ Total: \\d+s\\Z
|
|
263
297
|
expect { described_class.sync(only: CitiesIndex, output: output) }
|
264
298
|
.to update_index(CitiesIndex)
|
265
299
|
expect(output.string).to match(Regexp.new(<<-OUTPUT, Regexp::MULTILINE))
|
266
|
-
\\ASynchronizing CitiesIndex
|
267
|
-
Imported CitiesIndex
|
300
|
+
\\ASynchronizing CitiesIndex
|
301
|
+
Imported CitiesIndex in \\d+s, stats: index 2
|
268
302
|
Missing documents: \\["#{cities.last.id}"\\]
|
269
303
|
Outdated documents: \\["#{cities.first.id}"\\]
|
270
304
|
Took \\d+s
|
@@ -277,9 +311,13 @@ Total: \\d+s\\Z
|
|
277
311
|
expect { described_class.sync(except: ['cities'], output: output) }
|
278
312
|
.not_to update_index(CitiesIndex)
|
279
313
|
expect(output.string).to match(Regexp.new(<<-OUTPUT, Regexp::MULTILINE))
|
280
|
-
\\ASynchronizing CountriesIndex
|
281
|
-
CountriesIndex
|
282
|
-
Skipping CountriesIndex
|
314
|
+
\\ASynchronizing CountriesIndex
|
315
|
+
CountriesIndex doesn't support outdated synchronization
|
316
|
+
Skipping CountriesIndex, up to date
|
317
|
+
Took \\d+s
|
318
|
+
Synchronizing UsersIndex
|
319
|
+
UsersIndex doesn't support outdated synchronization
|
320
|
+
Skipping UsersIndex, up to date
|
283
321
|
Took \\d+s
|
284
322
|
Total: \\d+s\\Z
|
285
323
|
OUTPUT
|
@@ -308,9 +346,9 @@ Total: \\d+s\\Z
|
|
308
346
|
.to update_index(CitiesIndex)
|
309
347
|
expect(output.string).to match(Regexp.new(<<-OUTPUT, Regexp::MULTILINE))
|
310
348
|
\\AApplying journal entries created after [+-:\\d\\s]+
|
311
|
-
Applying journal to \\[CitiesIndex
|
312
|
-
Imported CitiesIndex
|
313
|
-
Imported CountriesIndex
|
349
|
+
Applying journal to \\[CitiesIndex, CountriesIndex\\], 3 entries, stage 1
|
350
|
+
Imported CitiesIndex in \\d+s, stats: index 2
|
351
|
+
Imported CountriesIndex in \\d+s, stats: index 1
|
314
352
|
Total: \\d+s\\Z
|
315
353
|
OUTPUT
|
316
354
|
end
|
@@ -321,8 +359,8 @@ Total: \\d+s\\Z
|
|
321
359
|
.not_to update_index(CitiesIndex)
|
322
360
|
expect(output.string).to match(Regexp.new(<<-OUTPUT, Regexp::MULTILINE))
|
323
361
|
\\AApplying journal entries created after [+-:\\d\\s]+
|
324
|
-
Applying journal to \\[CountriesIndex
|
325
|
-
Imported CountriesIndex
|
362
|
+
Applying journal to \\[CountriesIndex\\], 1 entries, stage 1
|
363
|
+
Imported CountriesIndex in \\d+s, stats: index 1
|
326
364
|
Total: \\d+s\\Z
|
327
365
|
OUTPUT
|
328
366
|
end
|
@@ -333,8 +371,8 @@ Total: \\d+s\\Z
|
|
333
371
|
.to update_index(CitiesIndex)
|
334
372
|
expect(output.string).to match(Regexp.new(<<-OUTPUT, Regexp::MULTILINE))
|
335
373
|
\\AApplying journal entries created after [+-:\\d\\s]+
|
336
|
-
Applying journal to \\[CitiesIndex
|
337
|
-
Imported CitiesIndex
|
374
|
+
Applying journal to \\[CitiesIndex\\], 2 entries, stage 1
|
375
|
+
Imported CitiesIndex in \\d+s, stats: index 2
|
338
376
|
Total: \\d+s\\Z
|
339
377
|
OUTPUT
|
340
378
|
end
|
@@ -345,8 +383,8 @@ Total: \\d+s\\Z
|
|
345
383
|
.not_to update_index(CitiesIndex)
|
346
384
|
expect(output.string).to match(Regexp.new(<<-OUTPUT, Regexp::MULTILINE))
|
347
385
|
\\AApplying journal entries created after [+-:\\d\\s]+
|
348
|
-
Applying journal to \\[CountriesIndex
|
349
|
-
Imported CountriesIndex
|
386
|
+
Applying journal to \\[CountriesIndex\\], 1 entries, stage 1
|
387
|
+
Imported CountriesIndex in \\d+s, stats: index 1
|
350
388
|
Total: \\d+s\\Z
|
351
389
|
OUTPUT
|
352
390
|
end
|
@@ -392,5 +430,227 @@ Total: \\d+s\\Z
|
|
392
430
|
Total: \\d+s\\Z
|
393
431
|
OUTPUT
|
394
432
|
end
|
433
|
+
|
434
|
+
it 'executes asynchronously' do
|
435
|
+
output = StringIO.new
|
436
|
+
expect(Chewy.client).to receive(:delete_by_query).with(
|
437
|
+
{
|
438
|
+
body: {query: {match_all: {}}},
|
439
|
+
index: ['chewy_journal'],
|
440
|
+
refresh: false,
|
441
|
+
requests_per_second: 10.0,
|
442
|
+
scroll_size: 200,
|
443
|
+
wait_for_completion: false
|
444
|
+
}
|
445
|
+
).and_call_original
|
446
|
+
described_class.journal_clean(
|
447
|
+
output: output,
|
448
|
+
delete_by_query_options: {
|
449
|
+
wait_for_completion: false,
|
450
|
+
requests_per_second: 10.0,
|
451
|
+
scroll_size: 200
|
452
|
+
}
|
453
|
+
)
|
454
|
+
|
455
|
+
expect(output.string).to match(Regexp.new(<<-OUTPUT, Regexp::MULTILINE))
|
456
|
+
\\ATask to cleanup the journal has been created, [^\\n]*
|
457
|
+
Total: \\d+s\\Z
|
458
|
+
OUTPUT
|
459
|
+
end
|
460
|
+
|
461
|
+
context 'execute "chewy:journal:clean" rake task' do
|
462
|
+
subject(:task) { Rake.application['chewy:journal:clean'] }
|
463
|
+
before do
|
464
|
+
Rake::DefaultLoader.new.load('lib/tasks/chewy.rake')
|
465
|
+
Rake::Task.define_task(:environment)
|
466
|
+
end
|
467
|
+
it 'does not raise error' do
|
468
|
+
expect { task.invoke }.to_not raise_error
|
469
|
+
end
|
470
|
+
end
|
471
|
+
end
|
472
|
+
|
473
|
+
describe '.create_missing_indexes!' do
|
474
|
+
before do
|
475
|
+
[CountriesIndex, Chewy::Stash::Specification].map(&:create!)
|
476
|
+
|
477
|
+
# To avoid flaky issues when previous specs were run
|
478
|
+
expect(Chewy::Index).to receive(:descendants).and_return(
|
479
|
+
[
|
480
|
+
UsersIndex,
|
481
|
+
CountriesIndex,
|
482
|
+
CitiesIndex,
|
483
|
+
Chewy::Stash::Specification,
|
484
|
+
Chewy::Stash::Journal
|
485
|
+
]
|
486
|
+
)
|
487
|
+
end
|
488
|
+
|
489
|
+
specify do
|
490
|
+
output = StringIO.new
|
491
|
+
described_class.create_missing_indexes!(output: output)
|
492
|
+
expect(CitiesIndex.exists?).to be_truthy
|
493
|
+
expect(UsersIndex.exists?).to be_truthy
|
494
|
+
expect(Chewy::Stash::Journal.exists?).to be_falsey
|
495
|
+
expect(output.string).to match(Regexp.new(<<-OUTPUT, Regexp::MULTILINE))
|
496
|
+
UsersIndex index successfully created
|
497
|
+
CitiesIndex index successfully created
|
498
|
+
Total: \\d+s\\Z
|
499
|
+
OUTPUT
|
500
|
+
end
|
501
|
+
|
502
|
+
context 'when verbose' do
|
503
|
+
specify do
|
504
|
+
output = StringIO.new
|
505
|
+
described_class.create_missing_indexes!(output: output, env: {'VERBOSE' => '1'})
|
506
|
+
expect(output.string).to match(Regexp.new(<<-OUTPUT, Regexp::MULTILINE))
|
507
|
+
UsersIndex index successfully created
|
508
|
+
CountriesIndex already exists, skipping
|
509
|
+
CitiesIndex index successfully created
|
510
|
+
Chewy::Stash::Specification already exists, skipping
|
511
|
+
Total: \\d+s\\Z
|
512
|
+
OUTPUT
|
513
|
+
end
|
514
|
+
end
|
515
|
+
|
516
|
+
context 'when journaling is enabled' do
|
517
|
+
before { Chewy.config.settings[:journal] = true }
|
518
|
+
after { Chewy.config.settings.delete(:journal) }
|
519
|
+
specify do
|
520
|
+
described_class.create_missing_indexes!(output: StringIO.new)
|
521
|
+
expect(Chewy::Stash::Journal.exists?).to be_truthy
|
522
|
+
end
|
523
|
+
end
|
524
|
+
end
|
525
|
+
|
526
|
+
describe '.journal_create' do
|
527
|
+
specify do
|
528
|
+
output = StringIO.new
|
529
|
+
described_class.journal_create(output: output)
|
530
|
+
expect(Chewy::Stash::Journal.exists?).to be_truthy
|
531
|
+
expect(output.string).to match(Regexp.new(<<-OUTPUT, Regexp::MULTILINE))
|
532
|
+
Total: \\d+s\\Z
|
533
|
+
OUTPUT
|
534
|
+
end
|
535
|
+
end
|
536
|
+
|
537
|
+
describe '.reindex' do
|
538
|
+
before do
|
539
|
+
journal
|
540
|
+
CitiesIndex.create!
|
541
|
+
CountriesIndex.create!
|
542
|
+
end
|
543
|
+
|
544
|
+
let(:source_index) { 'cities' }
|
545
|
+
let(:dest_index) { 'countries' }
|
546
|
+
|
547
|
+
context 'with correct arguments' do
|
548
|
+
specify do
|
549
|
+
output = StringIO.new
|
550
|
+
described_class.reindex(source: source_index, dest: dest_index, output: output)
|
551
|
+
expect(output.string).to match(Regexp.new(<<-OUTPUT, Regexp::MULTILINE))
|
552
|
+
\\Source index is cities
|
553
|
+
\\Destination index is countries
|
554
|
+
cities index successfully reindexed with countries index data
|
555
|
+
Total: \\d+s\\Z
|
556
|
+
OUTPUT
|
557
|
+
end
|
558
|
+
end
|
559
|
+
|
560
|
+
context 'with missing indexes' do
|
561
|
+
context 'without dest index' do
|
562
|
+
specify do
|
563
|
+
output = StringIO.new
|
564
|
+
expect { described_class.reindex(source: source_index, output: output) }
|
565
|
+
.to raise_error ArgumentError
|
566
|
+
end
|
567
|
+
end
|
568
|
+
|
569
|
+
context 'without source index' do
|
570
|
+
specify do
|
571
|
+
output = StringIO.new
|
572
|
+
expect { described_class.reindex(dest: dest_index, output: output) }
|
573
|
+
.to raise_error ArgumentError
|
574
|
+
end
|
575
|
+
end
|
576
|
+
end
|
577
|
+
end
|
578
|
+
|
579
|
+
describe '.update_mapping' do
|
580
|
+
before do
|
581
|
+
journal
|
582
|
+
CitiesIndex.create!
|
583
|
+
end
|
584
|
+
|
585
|
+
let(:index_name) { CitiesIndex.index_name }
|
586
|
+
let(:nonexistent_index) { 'wrong_index' }
|
587
|
+
|
588
|
+
context 'with existing index' do
|
589
|
+
specify do
|
590
|
+
output = StringIO.new
|
591
|
+
described_class.update_mapping(name: index_name, output: output)
|
592
|
+
expect(output.string).to match(Regexp.new(<<-OUTPUT, Regexp::MULTILINE))
|
593
|
+
\\Index name is cities
|
594
|
+
cities index successfully updated
|
595
|
+
Total: \\d+s\\Z
|
596
|
+
OUTPUT
|
597
|
+
end
|
598
|
+
end
|
599
|
+
|
600
|
+
context 'with non-existent index name' do
|
601
|
+
specify do
|
602
|
+
output = StringIO.new
|
603
|
+
expect { described_class.update_mapping(name: nonexistent_index, output: output) }
|
604
|
+
.to raise_error NameError
|
605
|
+
end
|
606
|
+
end
|
607
|
+
end
|
608
|
+
|
609
|
+
describe '.delete_by_query_options_from_env' do
|
610
|
+
subject(:options) { described_class.delete_by_query_options_from_env(env) }
|
611
|
+
let(:env) do
|
612
|
+
{
|
613
|
+
'WAIT_FOR_COMPLETION' => 'false',
|
614
|
+
'REQUESTS_PER_SECOND' => '10',
|
615
|
+
'SCROLL_SIZE' => '5000'
|
616
|
+
}
|
617
|
+
end
|
618
|
+
|
619
|
+
it 'parses the options' do
|
620
|
+
expect(options).to eq(
|
621
|
+
wait_for_completion: false,
|
622
|
+
requests_per_second: 10.0,
|
623
|
+
scroll_size: 5000
|
624
|
+
)
|
625
|
+
end
|
626
|
+
|
627
|
+
context 'with different boolean values' do
|
628
|
+
it 'parses the option correctly' do
|
629
|
+
%w[1 t true TRUE on ON].each do |v|
|
630
|
+
expect(described_class.delete_by_query_options_from_env({'WAIT_FOR_COMPLETION' => v}))
|
631
|
+
.to eq(wait_for_completion: true)
|
632
|
+
end
|
633
|
+
|
634
|
+
%w[0 f false FALSE off OFF].each do |v|
|
635
|
+
expect(described_class.delete_by_query_options_from_env({'WAIT_FOR_COMPLETION' => v}))
|
636
|
+
.to eq(wait_for_completion: false)
|
637
|
+
end
|
638
|
+
end
|
639
|
+
end
|
640
|
+
|
641
|
+
context 'with other env' do
|
642
|
+
let(:env) { {'SOME_ENV' => '123', 'REQUESTS_PER_SECOND' => '15'} }
|
643
|
+
|
644
|
+
it 'parses only the options' do
|
645
|
+
expect(options).to eq(requests_per_second: 15.0)
|
646
|
+
end
|
647
|
+
end
|
648
|
+
end
|
649
|
+
|
650
|
+
describe '.subscribed_task_stats' do
|
651
|
+
specify do
|
652
|
+
block_output = described_class.subscribed_task_stats(StringIO.new) { 'expected output' }
|
653
|
+
expect(block_output).to eq('expected output')
|
654
|
+
end
|
395
655
|
end
|
396
656
|
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe :build_query do
|
4
|
+
before do
|
5
|
+
stub_model(:city)
|
6
|
+
stub_index(:cities) { index_scope City }
|
7
|
+
CitiesIndex.create
|
8
|
+
end
|
9
|
+
|
10
|
+
let(:expected_query) do
|
11
|
+
{
|
12
|
+
index: ['cities'],
|
13
|
+
body: {
|
14
|
+
query: {
|
15
|
+
match: {name: 'name'}
|
16
|
+
}
|
17
|
+
}
|
18
|
+
}
|
19
|
+
end
|
20
|
+
let(:dummy_query) { {match: {name: 'name'}} }
|
21
|
+
let(:unexpected_query) { {match: {name: 'name'}} }
|
22
|
+
|
23
|
+
context 'build expected query' do
|
24
|
+
specify do
|
25
|
+
expect(CitiesIndex.query(dummy_query)).to build_query(expected_query)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'not to build unexpected query' do
|
30
|
+
specify do
|
31
|
+
expect(CitiesIndex.query(dummy_query)).not_to build_query(unexpected_query)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe :rspec_helper do
|
4
|
+
include Chewy::Rspec::Helpers
|
5
|
+
|
6
|
+
before do
|
7
|
+
stub_model(:city)
|
8
|
+
stub_index(:cities) { index_scope City }
|
9
|
+
CitiesIndex.create
|
10
|
+
end
|
11
|
+
|
12
|
+
let(:hits) do
|
13
|
+
[
|
14
|
+
{
|
15
|
+
'_index' => 'cities',
|
16
|
+
'_type' => '_doc',
|
17
|
+
'_id' => '1',
|
18
|
+
'_score' => 3.14,
|
19
|
+
'_source' => source
|
20
|
+
}
|
21
|
+
]
|
22
|
+
end
|
23
|
+
|
24
|
+
let(:source) { {'name' => 'some_name'} }
|
25
|
+
let(:sources) { [source] }
|
26
|
+
|
27
|
+
context :mock_elasticsearch_response do
|
28
|
+
let(:raw_response) do
|
29
|
+
{
|
30
|
+
'took' => 4,
|
31
|
+
'timed_out' => false,
|
32
|
+
'_shards' => {
|
33
|
+
'total' => 1,
|
34
|
+
'successful' => 1,
|
35
|
+
'skipped' => 0,
|
36
|
+
'failed' => 0
|
37
|
+
},
|
38
|
+
'hits' => {
|
39
|
+
'total' => {
|
40
|
+
'value' => 1,
|
41
|
+
'relation' => 'eq'
|
42
|
+
},
|
43
|
+
'max_score' => 1.0,
|
44
|
+
'hits' => hits
|
45
|
+
}
|
46
|
+
}
|
47
|
+
end
|
48
|
+
|
49
|
+
specify do
|
50
|
+
mock_elasticsearch_response(CitiesIndex, raw_response)
|
51
|
+
expect(CitiesIndex.query({}).hits).to eq(hits)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
context :mock_elasticsearch_response_sources do
|
56
|
+
specify do
|
57
|
+
mock_elasticsearch_response_sources(CitiesIndex, sources)
|
58
|
+
expect(CitiesIndex.query({}).hits).to eq(hits)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|