|
| 1 | +# Licensed to Elasticsearch B.V. under one or more contributor |
| 2 | +# license agreements. See the NOTICE file distributed with |
| 3 | +# this work for additional information regarding copyright |
| 4 | +# ownership. Elasticsearch B.V. licenses this file to you under |
| 5 | +# the Apache License, Version 2.0 (the "License"); you may |
| 6 | +# not use this file except in compliance with the License. |
| 7 | +# You may obtain a copy of the License at |
| 8 | +# |
| 9 | +# http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | +# |
| 11 | +# Unless required by applicable law or agreed to in writing, |
| 12 | +# software distributed under the License is distributed on an |
| 13 | +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| 14 | +# KIND, either express or implied. See the License for the |
| 15 | +# specific language governing permissions and limitations |
| 16 | +# under the License. |
| 17 | + |
| 18 | +require 'support/test_file/action' |
| 19 | +require 'support/test_file/test' |
| 20 | +require 'support/test_file/task_group' |
| 21 | + |
| 22 | +module Elasticsearch |
| 23 | + |
| 24 | + module RestAPIYAMLTests |
| 25 | + |
| 26 | + # Class representing a single test file, containing a setup, teardown, and multiple tests. |
| 27 | + # |
| 28 | + # @since 6.2.0 |
| 29 | + class TestFile |
| 30 | + |
| 31 | + attr_reader :features_to_skip |
| 32 | + attr_reader :name |
| 33 | + |
| 34 | + # Initialize a single test file. |
| 35 | + # |
| 36 | + # @example Create a test file object. |
| 37 | + # TestFile.new(file_name) |
| 38 | + # |
| 39 | + # @param [ String ] file_name The name of the test file. |
| 40 | + # @param [ Array<Symbol> ] skip_features The names of features to skip. |
| 41 | + # |
| 42 | + # @since 6.1.0 |
| 43 | + def initialize(file_name, features_to_skip = []) |
| 44 | + @name = file_name |
| 45 | + documents = YAML.load_stream(File.new(file_name)) |
| 46 | + @test_definitions = documents.reject { |doc| doc['setup'] || doc['teardown'] } |
| 47 | + @setup = documents.find { |doc| doc['setup'] } |
| 48 | + @teardown = documents.find { |doc| doc['teardown'] } |
| 49 | + @features_to_skip = REST_API_YAML_SKIP_FEATURES + features_to_skip |
| 50 | + end |
| 51 | + |
| 52 | + # Get a list of tests in the test file. |
| 53 | + # |
| 54 | + # @example Get the list of tests |
| 55 | + # test_file.tests |
| 56 | + # |
| 57 | + # @return [ Array<Test> ] A list of Test objects. |
| 58 | + # |
| 59 | + # @since 6.2.0 |
| 60 | + def tests |
| 61 | + @test_definitions.collect do |test_definition| |
| 62 | + Test.new(self, test_definition) |
| 63 | + end |
| 64 | + end |
| 65 | + |
| 66 | + # Run the setup tasks defined for a single test file. |
| 67 | + # |
| 68 | + # @example Run the setup tasks. |
| 69 | + # test_file.setup(client) |
| 70 | + # |
| 71 | + # @param [ Elasticsearch::Client ] client The client to use to perform the setup tasks. |
| 72 | + # |
| 73 | + # @return [ self ] |
| 74 | + # |
| 75 | + # @since 6.2.0 |
| 76 | + def setup(client) |
| 77 | + return unless @setup |
| 78 | + actions = @setup['setup'].select { |action| action['do'] }.map { |action| Action.new(action['do']) } |
| 79 | + actions.each do |action| |
| 80 | + action.execute(client) |
| 81 | + end |
| 82 | + self |
| 83 | + end |
| 84 | + |
| 85 | + # Run the teardown tasks defined for a single test file. |
| 86 | + # |
| 87 | + # @example Run the teardown tasks. |
| 88 | + # test_file.teardown(client) |
| 89 | + # |
| 90 | + # @param [ Elasticsearch::Client ] client The client to use to perform the teardown tasks. |
| 91 | + # |
| 92 | + # @return [ self ] |
| 93 | + # |
| 94 | + # @since 6.2.0 |
| 95 | + def teardown(client) |
| 96 | + return unless @teardown |
| 97 | + actions = @teardown['teardown'].select { |action| action['do'] }.map { |action| Action.new(action['do']) } |
| 98 | + actions.each { |action| action.execute(client) } |
| 99 | + self |
| 100 | + end |
| 101 | + |
| 102 | + class << self |
| 103 | + |
| 104 | + # Prepare Elasticsearch for a single test file. |
| 105 | + # This method deletes indices, roles, datafeeds, etc. |
| 106 | + # |
| 107 | + # @since 6.2.0 |
| 108 | + def clear_data(client) |
| 109 | + clear_indices(client) |
| 110 | + clear_index_templates(client) |
| 111 | + clear_snapshots_and_repositories(client) |
| 112 | + end |
| 113 | + |
| 114 | + # Prepare Elasticsearch for a single test file. |
| 115 | + # This method deletes indices, roles, datafeeds, etc. |
| 116 | + # |
| 117 | + # @since 6.2.0 |
| 118 | + def prepare(client) |
| 119 | + clear_indices(client) |
| 120 | + clear_roles(client) |
| 121 | + clear_users(client) |
| 122 | + clear_privileges(client) |
| 123 | + clear_datafeeds(client) |
| 124 | + clear_ml_jobs(client) |
| 125 | + clear_rollup_jobs(client) |
| 126 | + clear_tasks(client) |
| 127 | + clear_machine_learning_indices(client) |
| 128 | + create_x_pack_rest_user(client) |
| 129 | + end |
| 130 | + |
| 131 | + private |
| 132 | + |
| 133 | + def create_x_pack_rest_user(client) |
| 134 | + client.xpack.security.put_user(username: 'x_pack_rest_user', |
| 135 | + body: { password: 'x-pack-test-password', roles: ['superuser'] }) |
| 136 | + end |
| 137 | + |
| 138 | + def clear_roles(client) |
| 139 | + client.xpack.security.get_role.each do |role, _| |
| 140 | + begin; client.xpack.security.delete_role(name: role); rescue; end |
| 141 | + end |
| 142 | + end |
| 143 | + |
| 144 | + def clear_users(client) |
| 145 | + client.xpack.security.get_user.each do |user, _| |
| 146 | + begin; client.xpack.security.delete_user(username: user); rescue; end |
| 147 | + end |
| 148 | + end |
| 149 | + |
| 150 | + def clear_privileges(client) |
| 151 | + client.xpack.security.get_privileges.each do |privilege, _| |
| 152 | + begin; client.xpack.security.delete_privileges(name: privilege); rescue; end |
| 153 | + end |
| 154 | + end |
| 155 | + |
| 156 | + def clear_datafeeds(client) |
| 157 | + client.xpack.ml.stop_datafeed(datafeed_id: '_all', force: true) |
| 158 | + client.xpack.ml.get_datafeeds['datafeeds'].each do |d| |
| 159 | + client.xpack.ml.delete_datafeed(datafeed_id: d['datafeed_id']) |
| 160 | + end |
| 161 | + end |
| 162 | + |
| 163 | + def clear_ml_jobs(client) |
| 164 | + client.xpack.ml.close_job(job_id: '_all', force: true) |
| 165 | + client.xpack.ml.get_jobs['jobs'].each do |d| |
| 166 | + client.xpack.ml.delete_job(job_id: d['job_id']) |
| 167 | + end |
| 168 | + end |
| 169 | + |
| 170 | + def clear_rollup_jobs(client) |
| 171 | + client.xpack.rollup.get_jobs(id: '_all')['jobs'].each do |d| |
| 172 | + client.xpack.rollup.stop_job(id: d['config']['id']) |
| 173 | + client.xpack.rollup.delete_job(id: d['config']['id']) |
| 174 | + end |
| 175 | + end |
| 176 | + |
| 177 | + def clear_tasks(client) |
| 178 | + tasks = client.tasks.get['nodes'].values.first['tasks'].values.select do |d| |
| 179 | + d['cancellable'] |
| 180 | + end.map do |d| |
| 181 | + "#{d['node']}:#{d['id']}" |
| 182 | + end |
| 183 | + tasks.each { |t| client.tasks.cancel task_id: t } |
| 184 | + end |
| 185 | + |
| 186 | + def clear_machine_learning_indices(client) |
| 187 | + client.indices.delete(index: '.ml-*', ignore: 404) |
| 188 | + end |
| 189 | + |
| 190 | + def clear_index_templates(client) |
| 191 | + client.indices.delete_template(name: '*') |
| 192 | + end |
| 193 | + |
| 194 | + def clear_snapshots_and_repositories(client) |
| 195 | + client.snapshot.get_repository(repository: '_all').keys.each do |repository| |
| 196 | + client.snapshot.get(repository: repository, snapshot: '_all')['snapshots'].each do |s| |
| 197 | + client.snapshot.delete(repository: repository, snapshot: s['snapshot']) |
| 198 | + end |
| 199 | + client.snapshot.delete_repository(repository: repository) |
| 200 | + end |
| 201 | + end |
| 202 | + |
| 203 | + def clear_indices(client) |
| 204 | + indices = client.indices.get(index: '_all').keys.reject do |i| |
| 205 | + i.start_with?('.security') || i.start_with?('.watches') |
| 206 | + end |
| 207 | + indices.each do |index| |
| 208 | + client.indices.delete_alias(index: index, name: '*', ignore: 404) |
| 209 | + client.indices.delete(index: index, ignore: 404) |
| 210 | + end |
| 211 | + # See cat.aliases/10_basic.yml, test_index is not return in client.indices.get(index: '_all') |
| 212 | + client.indices.delete(index: 'test_index', ignore: 404) |
| 213 | + client.indices.delete(index: 'index1', ignore: 404) |
| 214 | + client.indices.delete(index: 'index_closed', ignore: 404) |
| 215 | + client.indices.delete(index: 'bar', ignore: 404) |
| 216 | + client.indices.delete(index: 'test_close_index', ignore: 404) |
| 217 | + client.indices.delete(index: 'test_index_3', ignore: 404) |
| 218 | + client.indices.delete(index: 'test_index_2', ignore: 404) |
| 219 | + client.indices.delete(index: 'test-xyy', ignore: 404) |
| 220 | + end |
| 221 | + end |
| 222 | + end |
| 223 | + end |
| 224 | +end |
0 commit comments