From ab99b82125960a87d42cb6f58e20cfddf17cb7f4 Mon Sep 17 00:00:00 2001 From: Alexander Reelsen Date: Thu, 15 Mar 2018 14:20:58 -0700 Subject: [PATCH] Tests: Replace YAML test waiting for watch execution (elastic/x-pack-elasticsearch#4008) This is the last YAML test, that waits for a watch execution by specifying some timeout value. This one also gets replaced with a java test that uses `assertBusy()` and thus is much more likely to succeed. relates elastic/x-pack-elasticsearch#1513 Original commit: elastic/x-pack-elasticsearch@c2ab8777f42c00f9606ec2c5414bfdad4453bc26 --- ...SmokeTestWatcherClientYamlTestSuiteIT.java | 75 ------- .../SmokeTestWatcherTestSuiteIT.java | 183 ++++++++++++++++++ .../10_monitor_cluster_health.yml | 130 ------------- .../authc/ldap/PreventFailingTests.java | 17 -- 4 files changed, 183 insertions(+), 222 deletions(-) delete mode 100644 qa/smoke-test-watcher/src/test/java/org/elasticsearch/smoketest/SmokeTestWatcherClientYamlTestSuiteIT.java create mode 100644 qa/smoke-test-watcher/src/test/java/org/elasticsearch/smoketest/SmokeTestWatcherTestSuiteIT.java delete mode 100644 qa/smoke-test-watcher/src/test/resources/rest-api-spec/test/watcher_getting_started/10_monitor_cluster_health.yml delete mode 100644 qa/third-party/active-directory/src/test/java/org/elasticsearch/xpack/security/authc/ldap/PreventFailingTests.java diff --git a/qa/smoke-test-watcher/src/test/java/org/elasticsearch/smoketest/SmokeTestWatcherClientYamlTestSuiteIT.java b/qa/smoke-test-watcher/src/test/java/org/elasticsearch/smoketest/SmokeTestWatcherClientYamlTestSuiteIT.java deleted file mode 100644 index 3ff49260e95..00000000000 --- a/qa/smoke-test-watcher/src/test/java/org/elasticsearch/smoketest/SmokeTestWatcherClientYamlTestSuiteIT.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -package org.elasticsearch.smoketest; - -import com.carrotsearch.randomizedtesting.annotations.Name; -import com.carrotsearch.randomizedtesting.annotations.ParametersFactory; -import org.elasticsearch.test.junit.annotations.TestLogging; -import org.elasticsearch.test.rest.yaml.ClientYamlTestCandidate; -import org.elasticsearch.test.rest.yaml.ClientYamlTestResponse; -import org.elasticsearch.test.rest.yaml.ESClientYamlSuiteTestCase; -import org.elasticsearch.xpack.core.watcher.support.WatcherIndexTemplateRegistryField; -import org.junit.After; -import org.junit.Before; - -import java.io.IOException; -import java.util.Arrays; -import java.util.List; - -import static java.util.Collections.emptyList; -import static java.util.Collections.emptyMap; -import static java.util.Collections.singletonMap; -import static org.hamcrest.Matchers.is; - -public class SmokeTestWatcherClientYamlTestSuiteIT extends ESClientYamlSuiteTestCase { - - public SmokeTestWatcherClientYamlTestSuiteIT(@Name("yaml") ClientYamlTestCandidate testCandidate) { - super(testCandidate); - } - - @ParametersFactory - public static Iterable parameters() throws Exception { - return ESClientYamlSuiteTestCase.createParameters(); - } - - @Before - public void startWatcher() throws Exception { - final List watcherTemplates = Arrays.asList(WatcherIndexTemplateRegistryField.TEMPLATE_NAMES); - assertBusy(() -> { - try { - getAdminExecutionContext().callApi("xpack.watcher.start", emptyMap(), emptyList(), emptyMap()); - - for (String template : watcherTemplates) { - ClientYamlTestResponse templateExistsResponse = getAdminExecutionContext().callApi("indices.exists_template", - singletonMap("name", template), emptyList(), emptyMap()); - assertThat(templateExistsResponse.getStatusCode(), is(200)); - } - - ClientYamlTestResponse response = - getAdminExecutionContext().callApi("xpack.watcher.stats", emptyMap(), emptyList(), emptyMap()); - String state = (String) response.evaluate("stats.0.watcher_state"); - assertThat(state, is("started")); - } catch (IOException e) { - throw new AssertionError(e); - } - }); - } - - @After - public void stopWatcher() throws Exception { - assertBusy(() -> { - try { - getAdminExecutionContext().callApi("xpack.watcher.stop", emptyMap(), emptyList(), emptyMap()); - ClientYamlTestResponse response = - getAdminExecutionContext().callApi("xpack.watcher.stats", emptyMap(), emptyList(), emptyMap()); - String state = (String) response.evaluate("stats.0.watcher_state"); - assertThat(state, is("stopped")); - } catch (IOException e) { - throw new AssertionError(e); - } - }); - } -} diff --git a/qa/smoke-test-watcher/src/test/java/org/elasticsearch/smoketest/SmokeTestWatcherTestSuiteIT.java b/qa/smoke-test-watcher/src/test/java/org/elasticsearch/smoketest/SmokeTestWatcherTestSuiteIT.java new file mode 100644 index 00000000000..6581de8fa26 --- /dev/null +++ b/qa/smoke-test-watcher/src/test/java/org/elasticsearch/smoketest/SmokeTestWatcherTestSuiteIT.java @@ -0,0 +1,183 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +package org.elasticsearch.smoketest; + +import org.apache.http.entity.ContentType; +import org.apache.http.entity.StringEntity; +import org.elasticsearch.client.Response; +import org.elasticsearch.common.Strings; +import org.elasticsearch.common.settings.SecureString; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.util.concurrent.ThreadContext; +import org.elasticsearch.common.xcontent.XContentBuilder; +import org.elasticsearch.test.rest.ESRestTestCase; +import org.elasticsearch.test.rest.yaml.ObjectPath; +import org.elasticsearch.xpack.core.watcher.support.WatcherIndexTemplateRegistryField; +import org.junit.After; +import org.junit.Before; + +import java.io.IOException; +import java.util.Collections; +import java.util.Map; +import java.util.concurrent.atomic.AtomicReference; + +import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder; +import static org.elasticsearch.xpack.core.security.authc.support.UsernamePasswordToken.basicAuthHeaderValue; +import static org.hamcrest.Matchers.greaterThanOrEqualTo; +import static org.hamcrest.Matchers.hasEntry; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; + +public class SmokeTestWatcherTestSuiteIT extends ESRestTestCase { + + private static final String TEST_ADMIN_USERNAME = "test_admin"; + private static final String TEST_ADMIN_PASSWORD = "x-pack-test-password"; + + @Before + public void startWatcher() throws Exception { + assertBusy(() -> { + adminClient().performRequest("POST", "_xpack/watcher/_start"); + + for (String template : WatcherIndexTemplateRegistryField.TEMPLATE_NAMES) { + assertOK(adminClient().performRequest("HEAD", "_template/" + template)); + } + + Response statsResponse = adminClient().performRequest("GET", "_xpack/watcher/stats"); + ObjectPath objectPath = ObjectPath.createFromResponse(statsResponse); + String state = objectPath.evaluate("stats.0.watcher_state"); + assertThat(state, is("started")); + }); + } + + @After + public void stopWatcher() throws Exception { + assertBusy(() -> { + adminClient().performRequest("POST", "_xpack/watcher/_stop", Collections.emptyMap()); + Response statsResponse = adminClient().performRequest("GET", "_xpack/watcher/stats"); + ObjectPath objectPath = ObjectPath.createFromResponse(statsResponse); + String state = objectPath.evaluate("stats.0.watcher_state"); + assertThat(state, is("stopped")); + }); + } + + @Override + protected Settings restClientSettings() { + String token = basicAuthHeaderValue("watcher_manager", new SecureString("x-pack-test-password".toCharArray())); + return Settings.builder().put(ThreadContext.PREFIX + ".Authorization", token).build(); + } + + @Override + protected Settings restAdminSettings() { + String token = basicAuthHeaderValue(TEST_ADMIN_USERNAME, new SecureString(TEST_ADMIN_PASSWORD.toCharArray())); + return Settings.builder().put(ThreadContext.PREFIX + ".Authorization", token).build(); + } + + public void testMonitorClusterHealth() throws Exception { + String watchId = "cluster_health_watch"; + + // get master publish address + Response clusterStateResponse = adminClient().performRequest("GET", "_cluster/state"); + ObjectPath clusterState = ObjectPath.createFromResponse(clusterStateResponse); + String masterNode = clusterState.evaluate("master_node"); + assertThat(masterNode, is(notNullValue())); + + Response statsResponse = adminClient().performRequest("GET", "_nodes"); + ObjectPath stats = ObjectPath.createFromResponse(statsResponse); + String address = stats.evaluate("nodes." + masterNode + ".http.publish_address"); + assertThat(address, is(notNullValue())); + String[] splitAddress = address.split(":", 2); + String host = splitAddress[0]; + int port = Integer.valueOf(splitAddress[1]); + + // put watch + try (XContentBuilder builder = jsonBuilder()) { + builder.startObject(); + // trigger + builder.startObject("trigger").startObject("schedule").field("interval", "1s").endObject().endObject(); + // input + builder.startObject("input").startObject("http").startObject("request").field("host", host).field("port", port) + .field("path", "/_cluster/health") + .field("scheme", "http") + .startObject("auth").startObject("basic") + .field("username", TEST_ADMIN_USERNAME).field("password", TEST_ADMIN_PASSWORD) + .endObject().endObject() + .endObject().endObject().endObject(); + // condition + builder.startObject("condition").startObject("compare").startObject("ctx.payload.number_of_data_nodes").field("lt", 10) + .endObject().endObject().endObject(); + // actions + builder.startObject("actions").startObject("log").startObject("logging").field("text", "executed").endObject().endObject() + .endObject(); + + builder.endObject(); + + indexWatch(watchId, builder); + } + + // check watch count + assertWatchCount(1); + + // check watch history + ObjectPath objectPath = getWatchHistoryEntry(watchId); + boolean conditionMet = objectPath.evaluate("hits.hits.0._source.result.condition.met"); + assertThat(conditionMet, is(true)); + + deleteWatch(watchId); + assertWatchCount(0); + } + + private void indexWatch(String watchId, XContentBuilder builder) throws Exception { + StringEntity entity = new StringEntity(Strings.toString(builder), ContentType.APPLICATION_JSON); + + Response response = client().performRequest("PUT", "_xpack/watcher/watch/" + watchId, Collections.emptyMap(), entity); + assertOK(response); + Map responseMap = entityAsMap(response); + assertThat(responseMap, hasEntry("_id", watchId)); + } + + private void deleteWatch(String watchId) throws IOException { + Response response = client().performRequest("DELETE", "_xpack/watcher/watch/" + watchId); + assertOK(response); + ObjectPath path = ObjectPath.createFromResponse(response); + boolean found = path.evaluate("found"); + assertThat(found, is(true)); + } + + private ObjectPath getWatchHistoryEntry(String watchId) throws Exception { + final AtomicReference objectPathReference = new AtomicReference<>(); + assertBusy(() -> { + client().performRequest("POST", ".watcher-history-*/_refresh"); + + try (XContentBuilder builder = jsonBuilder()) { + builder.startObject(); + builder.startObject("query").startObject("bool").startArray("must"); + builder.startObject().startObject("term").startObject("watch_id").field("value", watchId).endObject().endObject() + .endObject(); + builder.endArray().endObject().endObject(); + builder.startArray("sort").startObject().startObject("trigger_event.triggered_time").field("order", "desc").endObject() + .endObject().endArray(); + builder.endObject(); + + StringEntity entity = new StringEntity(Strings.toString(builder), ContentType.APPLICATION_JSON); + Response response = client().performRequest("POST", ".watcher-history-*/_search", Collections.emptyMap(), entity); + ObjectPath objectPath = ObjectPath.createFromResponse(response); + int totalHits = objectPath.evaluate("hits.total"); + assertThat(totalHits, is(greaterThanOrEqualTo(1))); + String watchid = objectPath.evaluate("hits.hits.0._source.watch_id"); + assertThat(watchid, is(watchId)); + objectPathReference.set(objectPath); + } + }); + return objectPathReference.get(); + } + + private void assertWatchCount(int expectedWatches) throws IOException { + Response watcherStatsResponse = adminClient().performRequest("GET", "_xpack/watcher/stats"); + ObjectPath objectPath = ObjectPath.createFromResponse(watcherStatsResponse); + int watchCount = objectPath.evaluate("stats.0.watch_count"); + assertThat(watchCount, is(expectedWatches)); + } +} diff --git a/qa/smoke-test-watcher/src/test/resources/rest-api-spec/test/watcher_getting_started/10_monitor_cluster_health.yml b/qa/smoke-test-watcher/src/test/resources/rest-api-spec/test/watcher_getting_started/10_monitor_cluster_health.yml deleted file mode 100644 index b2609a9f646..00000000000 --- a/qa/smoke-test-watcher/src/test/resources/rest-api-spec/test/watcher_getting_started/10_monitor_cluster_health.yml +++ /dev/null @@ -1,130 +0,0 @@ ---- -setup: - - do: - cluster.health: - wait_for_status: yellow - ---- -teardown: - - do: - xpack.watcher.delete_watch: - id: "cluster_health_watch" - ignore: 404 - ---- -"Getting started - Monitor cluster health": - - do: - xpack.watcher.stats: {} - - match: { "stats.0.watcher_state": "started" } - - match: { "stats.0.watch_count": 0 } - - # extract http host and port from master node - - do: - cluster.state: {} - - set: { master_node: master } - - - do: - nodes.info: - metric: [ http ] - - is_true: nodes.$master.http.publish_address - - set: { nodes.$master.http.publish_address: host } - - - do: - ingest.simulate: - body: - pipeline: - description: _description - processors: [ grok: { field: host, patterns : ["%{IPORHOST:hostname}:%{NUMBER:port:int}"]} ] - docs: [ { _index: index, _type: type, _id: id, _source: { host: $host } } ] - - set: { docs.0.doc._source.hostname: hostname } - - set: { docs.0.doc._source.port: port } - - - do: - xpack.watcher.put_watch: - id: "cluster_health_watch" - body: - trigger: - schedule: - interval: 1s - input: - http: - request: - host: $hostname - port: $port - path: "/_cluster/health" - auth: - basic: - username: test_admin - password: x-pack-test-password - condition: - compare: - "ctx.payload.number_of_data_nodes": - lt: 10 - actions: - log: - logging: - text: "executed at {{ctx.execution_time}}" - - - match: { _id: "cluster_health_watch" } - - match: { created: true } - - - do: - indices.refresh: - index: .watches - - - do: - xpack.watcher.stats: {} - - match: { "stats.0.watch_count": 1 } - - # Simulate a Thread.sleep() - - do: - catch: request_timeout - cluster.health: - wait_for_nodes: 99 - timeout: 5s - - match: { "timed_out": true } - - - do: - indices.refresh: - index: .watcher-history-* - - - do: - search: - index: .watcher-history-* - body: > - { - "query": { - "bool": { - "must" : [ - { - "term": { - "watch_id": { - "value": "cluster_health_watch" - } - } - }, - { - "term": { - "result.condition.met": { - "value": "true" - } - } - } - ] - } - } - } - - gte: { hits.total: 1 } - - - do: - xpack.watcher.delete_watch: - id: "cluster_health_watch" - - match: { found: true } - - - do: - indices.refresh: - index: .watches - - - do: - xpack.watcher.stats: {} - - match: { "stats.0.watch_count": 0 } diff --git a/qa/third-party/active-directory/src/test/java/org/elasticsearch/xpack/security/authc/ldap/PreventFailingTests.java b/qa/third-party/active-directory/src/test/java/org/elasticsearch/xpack/security/authc/ldap/PreventFailingTests.java deleted file mode 100644 index a0a407a503a..00000000000 --- a/qa/third-party/active-directory/src/test/java/org/elasticsearch/xpack/security/authc/ldap/PreventFailingTests.java +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -package org.elasticsearch.xpack.security.authc.ldap; - -import org.elasticsearch.test.ESTestCase; - -public class PreventFailingTests extends ESTestCase { - - public void testPreventFailingWithNetworkingDisabled() { - // Noop - // This is required because if network tests are not enabled no tests will be run in the entire project and all tests will fail. - } - -}