@@ -32,13 +32,15 @@ class SkipTestsException < StandardError
3232 # @since 6.2.0
3333 class TestFile
3434 attr_reader :features_to_skip , :name , :client
35+ LOGGER = Logger . new ( $stdout)
3536
3637 # Initialize a single test file.
3738 #
3839 # @example Create a test file object.
3940 # TestFile.new(file_name)
4041 #
4142 # @param [ String ] file_name The name of the test file.
43+ # @param [ Client] An instance of the client
4244 # @param [ Array<Symbol> ] skip_features The names of features to skip.
4345 #
4446 # @since 6.1.0
@@ -48,9 +50,8 @@ def initialize(file_name, client, features_to_skip = [])
4850 begin
4951 documents = YAML . load_stream ( File . new ( file_name ) )
5052 rescue StandardError => e
51- logger = Logger . new ( $stdout)
52- logger . error e
53- logger . error "Filename : #{ @name } "
53+ LOGGER . error e
54+ LOGGER . error "Filename : #{ @name } "
5455 end
5556 @test_definitions = documents . reject { |doc | doc [ 'setup' ] || doc [ 'teardown' ] }
5657 @setup = documents . find { |doc | doc [ 'setup' ] }
@@ -108,34 +109,50 @@ def tests
108109 # Run the setup tasks defined for a single test file.
109110 #
110111 # @example Run the setup tasks.
111- # test_file.setup(client)
112+ # test_file.setup
112113 #
113114 # @param [ Elasticsearch::Client ] client The client to use to perform the setup tasks.
114115 #
115116 # @return [ self ]
116117 #
117118 # @since 6.2.0
118- def setup ( client )
119+ def setup
119120 return unless @setup
120121
121122 actions = @setup [ 'setup' ] . select { |action | action [ 'do' ] } . map { |action | Action . new ( action [ 'do' ] ) }
122- actions . each do |action |
123- action . execute ( client )
123+ count = 0
124+ loop do
125+ actions . delete_if do |action |
126+ begin
127+ action . execute ( client )
128+ true
129+ rescue Elasticsearch ::Transport ::Transport ::Errors ::ServiceUnavailable => e
130+ # The action sometimes gets the cluster in a recovering state, so we
131+ # retry a few times and then raise an exception if it's still
132+ # happening
133+ count += 1
134+ raise e if count > 9
135+
136+ false
137+ end
138+ end
139+ break if actions . empty?
124140 end
141+
125142 self
126143 end
127144
128145 # Run the teardown tasks defined for a single test file.
129146 #
130147 # @example Run the teardown tasks.
131- # test_file.teardown(client)
148+ # test_file.teardown
132149 #
133150 # @param [ Elasticsearch::Client ] client The client to use to perform the teardown tasks.
134151 #
135152 # @return [ self ]
136153 #
137154 # @since 6.2.0
138- def teardown ( client )
155+ def teardown
139156 return unless @teardown
140157
141158 actions = @teardown [ 'teardown' ] . select { |action | action [ 'do' ] } . map { |action | Action . new ( action [ 'do' ] ) }
@@ -144,35 +161,157 @@ def teardown(client)
144161 end
145162
146163 class << self
147- # Prepare Elasticsearch for a single test file.
148- # This method deletes indices, roles, datafeeds, etc.
149- #
150- # @since 6.2.0
151- def clear_data ( client )
152- clear_indices ( client )
153- clear_index_templates ( client )
164+ PRESERVE_ILM_POLICY_IDS = [
165+ 'ilm-history-ilm-policy' , 'slm-history-ilm-policy' ,
166+ 'watch-history-ilm-policy' , 'ml-size-based-ilm-policy' , 'logs' ,
167+ 'metrics'
168+ ] . freeze
169+
170+ XPACK_TEMPLATES = [
171+ '.watches' , 'logstash-index-template' , '.logstash-management' ,
172+ 'security_audit_log' , '.slm-history' , '.async-search' ,
173+ 'saml-service-provider' , 'ilm-history' , 'logs' , 'logs-settings' ,
174+ 'logs-mappings' , 'metrics' , 'metrics-settings' , 'metrics-mappings' ,
175+ 'synthetics' , 'synthetics-settings' , 'synthetics-mappings' ,
176+ '.snapshot-blob-cache' , '.deprecation-indexing-mappings' , '.deprecation-indexing-settings'
177+ ] . freeze
178+
179+ # Wipe Cluster, based on PHP's implementation of ESRestTestCase.java:wipeCluster()
180+ # https://github.com/elastic/elasticsearch-php/blob/7.10/tests/Elasticsearch/Tests/Utility.php#L97
181+ def wipe_cluster ( client )
182+ if xpack?
183+ clear_rollup_jobs ( client )
184+ clear_sml_policies ( client )
185+ wait_for_pending_tasks ( client )
186+ end
154187 clear_snapshots_and_repositories ( client )
155- end
188+ clear_datastreams ( client ) if xpack?
189+ clear_indices ( client )
190+ if xpack?
191+ clear_templates_xpack ( client )
192+ clear_datafeeds ( client )
193+ clear_ml_jobs ( client )
194+ else
195+ client . indices . delete_template ( name : '*' )
196+ client . indices . delete_index_template ( name : '*' )
197+ client . cluster . delete_component_template ( name : '*' )
198+ end
199+ clear_cluster_settings ( client )
200+ return unless xpack?
156201
157- # Prepare Elasticsearch for a single test file.
158- # This method deletes indices, roles, datafeeds, etc.
159- #
160- # @since 6.2.0
161- def clear_data_xpack ( client )
162- clear_roles ( client )
163- clear_users ( client )
164- clear_privileges ( client )
165- clear_datafeeds ( client )
166- clear_ml_jobs ( client )
167- clear_rollup_jobs ( client )
202+ clear_ml_filters ( client )
203+ clear_ilm_policies ( client )
204+ clear_auto_follow_patterns ( client )
168205 clear_tasks ( client )
169- clear_machine_learning_indices ( client )
170- create_x_pack_rest_user ( client )
171206 clear_transforms ( client )
172- clear_datastreams ( client )
173- clear_indices_xpack ( client )
174- clear_index_templates ( client )
175- clear_snapshots_and_repositories ( client )
207+ wait_for_cluster_tasks ( client )
208+ end
209+
210+ def xpack?
211+ ENV [ 'TEST_SUITE' ] == 'xpack'
212+ end
213+
214+ def wait_for_pending_tasks ( client )
215+ filter = 'xpack/rollup/job'
216+ loop do
217+ results = client . cat . tasks ( detailed : true ) . split ( "\n " )
218+ count = 0
219+
220+ time = Time . now . to_i
221+ results . each do |task |
222+ next if task . empty?
223+
224+ count += 1 if task . include? ( filter )
225+ end
226+ break unless count . positive? && Time . now . to_i < ( time + 30 )
227+ end
228+ end
229+
230+ def wait_for_cluster_tasks ( client )
231+ tasks_filter = [ 'delete-index' , 'remove-data-stream' , 'ilm-history' ]
232+ time = Time . now . to_i
233+ count = 0
234+
235+ loop do
236+ results = client . cluster . pending_tasks
237+ results [ 'tasks' ] . each do |task |
238+ next if task . empty?
239+
240+ LOGGER . info "Pending task: #{ task } "
241+ tasks_filter . map do |filter |
242+ count += 1 if task [ 'source' ] . include? filter
243+ end
244+ end
245+ break unless count . positive? && Time . now . to_i < ( time + 30 )
246+ end
247+ end
248+
249+ def clear_sml_policies ( client )
250+ policies = client . xpack . snapshot_lifecycle_management . get_lifecycle
251+
252+ policies . each do |name , _ |
253+ client . xpack . snapshot_lifecycle_management . delete_lifecycle ( policy_id : name )
254+ end
255+ end
256+
257+ def clear_ilm_policies ( client )
258+ policies = client . xpack . ilm . get_lifecycle
259+ policies . each do |policy |
260+ client . xpack . ilm . delete_lifecycle ( policy : policy [ 0 ] ) unless PRESERVE_ILM_POLICY_IDS . include? policy [ 0 ]
261+ end
262+ end
263+
264+ def clear_cluster_settings ( client )
265+ settings = client . cluster . get_settings
266+ new_settings = [ ]
267+ settings . each do |name , value |
268+ next unless !value . empty? && value . is_a? ( Array )
269+
270+ new_settings [ name ] = [ ] if new_settings [ name ] . empty?
271+ value . each do |key , _v |
272+ new_settings [ name ] [ "#{ key } .*" ] = nil
273+ end
274+ end
275+ client . cluster . put_settings ( body : new_settings ) unless new_settings . empty?
276+ end
277+
278+ def clear_templates_xpack ( client )
279+ templates = client . cat . templates ( h : 'name' ) . split ( "\n " )
280+
281+ templates . each do |template |
282+ next if xpack_template? template
283+
284+ begin
285+ client . indices . delete_template ( name : template )
286+ rescue Elasticsearch ::Transport ::Transport ::Errors ::NotFound => e
287+ if e . message . include? ( "index_template [#{ template } ] missing" )
288+ client . indices . delete_index_template ( name : template , ignore : 404 )
289+ end
290+ end
291+ end
292+ # Delete component template
293+ result = client . cluster . get_component_template
294+
295+ result [ 'component_templates' ] . each do |template |
296+ next if xpack_template? template [ 'name' ]
297+
298+ client . cluster . delete_component_template ( name : template [ 'name' ] , ignore : 404 )
299+ end
300+ end
301+
302+ def xpack_template? ( template )
303+ xpack_prefixes = [ '.monitoring' , '.watch' , '.triggered-watches' , '.data-frame' , '.ml-' , '.transform' ] . freeze
304+ xpack_prefixes . map { |a | return true if a . include? template }
305+
306+ XPACK_TEMPLATES . include? template
307+ end
308+
309+ def clear_auto_follow_patterns ( client )
310+ patterns = client . cross_cluster_replication . get_auto_follow_pattern
311+
312+ patterns [ 'patterns' ] . each do |pattern |
313+ client . cross_cluster_replication . delete_auto_follow_pattern ( name : pattern )
314+ end
176315 end
177316
178317 private
@@ -243,19 +382,19 @@ def clear_index_templates(client)
243382 end
244383
245384 def clear_snapshots_and_repositories ( client )
246- if repositories = client . snapshot . get_repository
247- repositories . keys . each do |repository |
248- responses = client . snapshot . get ( repository : repository , snapshot : '_all' ) [ 'responses' ]
249- next unless responses
250-
251- responses . each do |response |
252- response [ 'snapshots' ] . each do |snapshot |
253- client . snapshot . delete ( repository : repository , snapshot : snapshot [ 'snapshot' ] )
254- end
255- end
385+ return unless ( repositories = client . snapshot . get_repository )
256386
257- client . snapshot . delete_repository ( repository : repository )
387+ repositories . each_key do |repository |
388+ responses = client . snapshot . get ( repository : repository , snapshot : '_all' ) [ 'responses' ]
389+ next unless responses
390+
391+ responses . each do |response |
392+ response [ 'snapshots' ] . each do |snapshot |
393+ client . snapshot . delete ( repository : repository , snapshot : snapshot [ 'snapshot' ] )
394+ end
258395 end
396+
397+ client . snapshot . delete_repository ( repository : repository )
259398 end
260399 end
261400
@@ -266,21 +405,22 @@ def clear_transforms(client)
266405 end
267406
268407 def clear_datastreams ( client )
269- client . indices . delete_data_stream ( name : '*' , expand_wildcards : 'all' )
408+ datastreams = client . xpack . indices . get_data_stream ( name : '*' , expand_wildcards : 'all' )
409+ datastreams [ 'data_streams' ] . each do |datastream |
410+ client . xpack . indices . delete_data_stream ( name : datastream [ 'name' ] , expand_wildcards : 'all' )
411+ end
412+ client . indices . delete_data_stream ( name : '*' )
270413 end
271414
272- def clear_indices ( client )
273- client . indices . delete ( index : '*' , expand_wildcards : 'all' )
415+ def clear_ml_filters ( client )
416+ filters = client . xpack . ml . get_filters [ 'filters' ]
417+ filters . each do |filter |
418+ client . xpack . ml . delete_filter ( filter_id : filter [ 'filter_id' ] )
419+ end
274420 end
275421
276- def clear_indices_xpack ( client )
277- indices = client . indices . get ( index : '_all' , expand_wildcards : 'all' ) . keys . reject do |i |
278- i . start_with? ( '.security' ) || i . start_with? ( '.watches' ) || i . start_with? ( '.ds-' )
279- end
280- indices . each do |index |
281- client . indices . delete_alias ( index : index , name : '*' , ignore : 404 )
282- client . indices . delete ( index : index , ignore : 404 )
283- end
422+ def clear_indices ( client )
423+ client . indices . delete ( index : '*,-.ds-ilm-history-*' , expand_wildcards : 'open,closed,hidden' , ignore : 404 )
284424 end
285425 end
286426 end
0 commit comments