Watcher: Replace integration tests with unit and REST tests (elastic/x-pack-elasticsearch#2322)

A bunch of integration tests should have been built as unit tests
or already have unit test equivalents.

This commit removes integration tests as well as adding REST equivalents
or creating unit tests instead of extending from AbstractWatcherIntegrationTestCase

Original commit: elastic/x-pack-elasticsearch@a97b99467d
This commit is contained in:
Alexander Reelsen 2017-08-30 11:46:28 +02:00 committed by GitHub
parent 17de601e21
commit 4ac13fa9c5
14 changed files with 396 additions and 678 deletions

View File

@ -22,7 +22,7 @@ public class ExecutableLoggingAction extends ExecutableAction<LoggingAction> {
private final Logger textLogger;
private final TextTemplateEngine templateEngine;
ExecutableLoggingAction(LoggingAction action, Logger logger, Settings settings, TextTemplateEngine templateEngine) {
public ExecutableLoggingAction(LoggingAction action, Logger logger, Settings settings, TextTemplateEngine templateEngine) {
super(action, logger);
this.textLogger = action.category != null ? Loggers.getLogger(action.category, settings) : logger;
this.templateEngine = templateEngine;

View File

@ -28,6 +28,5 @@ public class LoggingActionFactory extends ActionFactory {
public ExecutableLoggingAction parseExecutable(String watchId, String actionId, XContentParser parser) throws IOException {
LoggingAction action = LoggingAction.parse(watchId, actionId, parser);
return new ExecutableLoggingAction(action, actionLogger, settings, templateEngine);
}
}

View File

@ -1,118 +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.watcher.condition;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.ShardSearchFailure;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.xcontent.support.XContentMapValues;
import org.elasticsearch.index.Index;
import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.script.MockScriptPlugin;
import org.elasticsearch.script.ScriptService;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.SearchShardTarget;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.BucketOrder;
import org.elasticsearch.search.aggregations.bucket.histogram.DateHistogramInterval;
import org.elasticsearch.search.internal.InternalSearchResponse;
import org.elasticsearch.xpack.watcher.execution.WatchExecutionContext;
import org.elasticsearch.xpack.watcher.test.AbstractWatcherIntegrationTestCase;
import org.elasticsearch.xpack.watcher.watch.Payload;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import static org.elasticsearch.xpack.watcher.test.WatcherTestUtils.mockExecutionContext;
import static org.hamcrest.Matchers.is;
import static org.mockito.Mockito.when;
public class ScriptConditionSearchTests extends AbstractWatcherIntegrationTestCase {
@Override
protected List<Class<? extends Plugin>> pluginTypes() {
List<Class<? extends Plugin>> types = super.pluginTypes();
types.add(CustomScriptPlugin.class);
return types;
}
public static class CustomScriptPlugin extends MockScriptPlugin {
@Override
@SuppressWarnings("unchecked")
protected Map<String, Function<Map<String, Object>, Object>> pluginScripts() {
Map<String, Function<Map<String, Object>, Object>> scripts = new HashMap<>();
scripts.put("ctx.payload.aggregations.rate.buckets[0]?.doc_count >= 5", vars -> {
List<?> buckets = (List<?>) XContentMapValues.extractValue("ctx.payload.aggregations.rate.buckets", vars);
int docCount = (int) XContentMapValues.extractValue("doc_count", (Map<String, Object>) buckets.get(0));
return docCount >= 5;
});
scripts.put("ctx.payload.hits?.hits[0]?._score == 1.0", vars -> {
List<Map<String, Object>> searchHits = (List<Map<String, Object>>) XContentMapValues.extractValue("ctx.payload.hits.hits",
vars);
double score = (double) XContentMapValues.extractValue("_score", searchHits.get(0));
return score == 1.0;
});
return scripts;
}
}
public void testExecuteWithAggs() throws Exception {
client().prepareIndex("my-index", "my-type").setSource("@timestamp", "2005-01-01T00:00").get();
client().prepareIndex("my-index", "my-type").setSource("@timestamp", "2005-01-01T00:10").get();
client().prepareIndex("my-index", "my-type").setSource("@timestamp", "2005-01-01T00:20").get();
client().prepareIndex("my-index", "my-type").setSource("@timestamp", "2005-01-01T00:30").get();
refresh();
SearchResponse response = client().prepareSearch("my-index")
.addAggregation(AggregationBuilders.dateHistogram("rate").field("@timestamp")
.dateHistogramInterval(DateHistogramInterval.HOUR).order(BucketOrder.count(false)))
.get();
ScriptService scriptService = internalCluster().getInstance(ScriptService.class);
ScriptCondition condition = new ScriptCondition(
mockScript("ctx.payload.aggregations.rate.buckets[0]?.doc_count >= 5"),
scriptService);
WatchExecutionContext ctx = mockExecutionContext("_name", new Payload.XContent(response));
assertFalse(condition.execute(ctx).met());
client().prepareIndex("my-index", "my-type").setSource("@timestamp", "2005-01-01T00:40").get();
refresh();
response = client().prepareSearch("my-index").addAggregation(AggregationBuilders.dateHistogram("rate").field("@timestamp")
.dateHistogramInterval(DateHistogramInterval.HOUR).order(BucketOrder.count(false)))
.get();
ctx = mockExecutionContext("_name", new Payload.XContent(response));
assertThat(condition.execute(ctx).met(), is(true));
}
public void testExecuteAccessHits() throws Exception {
ScriptService scriptService = internalCluster().getInstance(ScriptService.class);
ScriptCondition condition = new ScriptCondition(
mockScript("ctx.payload.hits?.hits[0]?._score == 1.0"), scriptService);
SearchHit hit = new SearchHit(0, "1", new Text("type"), null);
hit.score(1f);
hit.shard(new SearchShardTarget("a", new Index("a", "testUUID"), 0, null));
InternalSearchResponse internalSearchResponse = new InternalSearchResponse(new SearchHits(
new SearchHit[]{hit}, 1L, 1f), null, null, null, false, false, 1);
SearchResponse response = new SearchResponse(internalSearchResponse, "", 3, 3, 0, 500L, new ShardSearchFailure[0]);
WatchExecutionContext ctx = mockExecutionContext("_watch_name", new Payload.XContent(response));
assertThat(condition.execute(ctx).met(), is(true));
hit.score(2f);
when(ctx.payload()).thenReturn(new Payload.XContent(response));
assertThat(condition.execute(ctx).met(), is(false));
}
}

View File

@ -72,6 +72,7 @@ import static java.util.Arrays.asList;
import static java.util.Collections.singletonMap;
import static org.elasticsearch.common.unit.TimeValue.timeValueSeconds;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.is;
@ -202,7 +203,7 @@ public class ExecutionServiceTests extends ESTestCase {
when(watch.input()).thenReturn(input);
when(watch.condition()).thenReturn(condition);
when(watch.transform()).thenReturn(watchTransform);
when(watch.actions()).thenReturn(Arrays.asList(actionWrapper));
when(watch.actions()).thenReturn(Collections.singletonList(actionWrapper));
when(watch.status()).thenReturn(watchStatus);
WatchRecord watchRecord = executionService.execute(context);
@ -221,6 +222,10 @@ public class ExecutionServiceTests extends ESTestCase {
verify(watchTransform, times(1)).execute(context, payload);
verify(action, times(1)).execute("_action", context, payload);
// test execution duration
assertThat(watchRecord.result().executionDurationMs(), is(greaterThan(0L)));
assertThat(watchRecord.result().executionTime(), is(notNullValue()));
// test stats
XContentSource source = new XContentSource(jsonBuilder().map(executionService.usageStats()));
assertThat(source.getValue("execution.actions._all.total_time_in_ms"), is(notNullValue()));

View File

@ -1,314 +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.watcher.execution;
import org.elasticsearch.action.ActionRequestValidationException;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.support.XContentMapValues;
import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.script.MockScriptPlugin;
import org.elasticsearch.script.Script;
import org.elasticsearch.script.ScriptType;
import org.elasticsearch.xpack.watcher.actions.ActionStatus;
import org.elasticsearch.xpack.watcher.client.WatchSourceBuilder;
import org.elasticsearch.xpack.watcher.condition.AlwaysCondition;
import org.elasticsearch.xpack.watcher.condition.NeverCondition;
import org.elasticsearch.xpack.watcher.condition.ScriptCondition;
import org.elasticsearch.xpack.watcher.history.HistoryStore;
import org.elasticsearch.xpack.watcher.support.xcontent.ObjectPath;
import org.elasticsearch.xpack.watcher.test.AbstractWatcherIntegrationTestCase;
import org.elasticsearch.xpack.watcher.transport.actions.execute.ExecuteWatchRequest;
import org.elasticsearch.xpack.watcher.transport.actions.execute.ExecuteWatchRequestBuilder;
import org.elasticsearch.xpack.watcher.transport.actions.execute.ExecuteWatchResponse;
import org.elasticsearch.xpack.watcher.transport.actions.get.GetWatchRequest;
import org.elasticsearch.xpack.watcher.transport.actions.get.GetWatchResponse;
import org.elasticsearch.xpack.watcher.transport.actions.put.PutWatchRequest;
import org.elasticsearch.xpack.watcher.trigger.TriggerEvent;
import org.elasticsearch.xpack.watcher.trigger.schedule.ScheduleTriggerEvent;
import org.elasticsearch.xpack.watcher.watch.Watch;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import java.time.Clock;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.function.Function;
import static java.util.Collections.singletonMap;
import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
import static org.elasticsearch.xpack.watcher.actions.ActionBuilders.loggingAction;
import static org.elasticsearch.xpack.watcher.client.WatchSourceBuilders.watchBuilder;
import static org.elasticsearch.xpack.watcher.input.InputBuilders.simpleInput;
import static org.elasticsearch.xpack.watcher.trigger.TriggerBuilders.schedule;
import static org.elasticsearch.xpack.watcher.trigger.schedule.Schedules.cron;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.startsWith;
public class ManualExecutionTests extends AbstractWatcherIntegrationTestCase {
@Override
protected boolean enableSecurity() {
return false;
}
@Override
protected List<Class<? extends Plugin>> pluginTypes() {
List<Class<? extends Plugin>> types = super.pluginTypes();
types.add(CustomScriptPlugin.class);
return types;
}
public static class CustomScriptPlugin extends MockScriptPlugin {
@Override
@SuppressWarnings("unchecked")
protected Map<String, Function<Map<String, Object>, Object>> pluginScripts() {
Map<String, Function<Map<String, Object>, Object>> scripts = new HashMap<>();
scripts.put("sleep", vars -> {
Number millis = (Number) XContentMapValues.extractValue("millis", vars);
if (millis != null) {
try {
Thread.sleep(millis.longValue());
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
} else {
throw new RuntimeException("Unable to sleep, [millis] parameter is missing!");
}
return true;
});
return scripts;
}
@Override
public String pluginScriptLang() {
return WATCHER_LANG;
}
}
public void testExecuteWatch() throws Exception {
boolean ignoreCondition = randomBoolean();
boolean recordExecution = randomBoolean();
boolean conditionAlwaysTrue = randomBoolean();
String action = randomFrom("_all", "log");
WatchSourceBuilder watchBuilder = watchBuilder()
.trigger(schedule(cron("0 0 0 1 * ? 2099")))
.input(simpleInput("foo", "bar"))
.condition(conditionAlwaysTrue ? AlwaysCondition.INSTANCE : NeverCondition.INSTANCE)
.addAction("log", loggingAction("foobar"));
watcherClient().putWatch(new PutWatchRequest("_id", watchBuilder)).actionGet();
ExecuteWatchRequestBuilder executeWatchRequestBuilder = watcherClient().prepareExecuteWatch("_id");
executeWatchRequestBuilder.setIgnoreCondition(ignoreCondition);
executeWatchRequestBuilder.setRecordExecution(recordExecution);
executeWatchRequestBuilder.setActionMode(action, ActionExecutionMode.SIMULATE);
refresh();
long oldRecordCount = docCount(HistoryStore.INDEX_PREFIX_WITH_TEMPLATE + "*", HistoryStore.DOC_TYPE, matchAllQuery());
ExecuteWatchResponse executeWatchResponse = executeWatchRequestBuilder.get();
Map<String, Object> responseMap = executeWatchResponse.getRecordSource().getAsMap();
refresh();
long newRecordCount = docCount(HistoryStore.INDEX_PREFIX_WITH_TEMPLATE + "*", HistoryStore.DOC_TYPE, matchAllQuery());
long expectedCount = oldRecordCount + (recordExecution ? 1 : 0);
assertThat("the expected count of history records should be [" + expectedCount + "]", newRecordCount, equalTo(expectedCount));
List<Map<String, Object>> actions = ObjectPath.eval("result.actions", responseMap);
if (ignoreCondition) {
assertThat("The action should have run", actions.size(), equalTo(1));
} else if (!conditionAlwaysTrue) {
assertThat("The action should not have run", actions.size(), equalTo(0));
}
if (ignoreCondition || conditionAlwaysTrue) {
assertThat("The action should have run simulated", actions.get(0).get("status"), is("simulated"));
}
if (recordExecution) {
GetWatchResponse response = watcherClient().getWatch(new GetWatchRequest("_id")).actionGet();
if (ignoreCondition || conditionAlwaysTrue) {
assertThat(response.getStatus().actionStatus("log").ackStatus().state(), is(ActionStatus.AckStatus.State.ACKABLE));
} else {
assertThat(response.getStatus().actionStatus("log").ackStatus().state(),
is(ActionStatus.AckStatus.State.AWAITS_SUCCESSFUL_EXECUTION));
}
} else {
String ackState = executeWatchResponse.getRecordSource().getValue("status.actions.log.ack.state");
if (ignoreCondition || conditionAlwaysTrue) {
assertThat(ackState, is(ActionStatus.AckStatus.State.ACKABLE.toString().toLowerCase(Locale.ROOT)));
} else {
assertThat(ackState, is(ActionStatus.AckStatus.State.AWAITS_SUCCESSFUL_EXECUTION.toString().toLowerCase(Locale.ROOT)));
}
}
}
public void testExecutionWithInlineWatch() throws Exception {
WatchSourceBuilder watchBuilder = watchBuilder()
.trigger(schedule(cron("0 0 0 1 * ? 2099")))
.input(simpleInput("foo", "bar"))
.condition(AlwaysCondition.INSTANCE)
.addAction("log", loggingAction("foobar"));
ExecuteWatchRequestBuilder builder = watcherClient().prepareExecuteWatch()
.setWatchSource(watchBuilder);
if (randomBoolean()) {
builder.setRecordExecution(false);
}
if (randomBoolean()) {
DateTime now = new DateTime(DateTimeZone.UTC);
builder.setTriggerEvent(new ScheduleTriggerEvent(now, now));
}
ExecuteWatchResponse executeWatchResponse = builder.get();
assertThat(executeWatchResponse.getRecordId(), startsWith(ExecuteWatchRequest.INLINE_WATCH_ID));
assertThat(executeWatchResponse.getRecordSource().getValue("watch_id").toString(), equalTo(ExecuteWatchRequest.INLINE_WATCH_ID));
assertThat(executeWatchResponse.getRecordSource().getValue("state").toString(), equalTo("executed"));
assertThat(executeWatchResponse.getRecordSource().getValue("trigger_event.type").toString(), equalTo("manual"));
}
public void testExecutionWithInlineWatchWithRecordExecutionEnabled() throws Exception {
WatchSourceBuilder watchBuilder = watchBuilder()
.trigger(schedule(cron("0 0 0 1 * ? 2099")))
.input(simpleInput("foo", "bar"))
.condition(AlwaysCondition.INSTANCE)
.addAction("log", loggingAction("foobar"));
ActionRequestValidationException e = expectThrows(ActionRequestValidationException.class, () ->
watcherClient().prepareExecuteWatch()
.setWatchSource(watchBuilder)
.setRecordExecution(true)
.setTriggerEvent(new ScheduleTriggerEvent(new DateTime(DateTimeZone.UTC), new DateTime(DateTimeZone.UTC)))
.get());
assertThat(e.getMessage(), containsString("the execution of an inline watch cannot be recorded"));
}
public void testExecutionWithInlineWatch_withWatchId() throws Exception {
WatchSourceBuilder watchBuilder = watchBuilder()
.trigger(schedule(cron("0 0 0 1 * ? 2099")))
.input(simpleInput("foo", "bar"))
.condition(AlwaysCondition.INSTANCE)
.addAction("log", loggingAction("foobar"));
try {
watcherClient().prepareExecuteWatch()
.setId("_id")
.setWatchSource(watchBuilder)
.setRecordExecution(false)
.setTriggerEvent(new ScheduleTriggerEvent(new DateTime(DateTimeZone.UTC), new DateTime(DateTimeZone.UTC)))
.get();
fail();
} catch (ActionRequestValidationException e) {
assertThat(e.getMessage(),
containsString("a watch execution request must either have a watch id or an inline watch source but not both"));
}
}
public void testDifferentAlternativeInputs() throws Exception {
WatchSourceBuilder watchBuilder = watchBuilder()
.trigger(schedule(cron("0 0 0 1 * ? 2099")))
.addAction("log", loggingAction("foobar"));
watcherClient().putWatch(new PutWatchRequest("_id", watchBuilder)).actionGet();
refresh(Watch.INDEX);
Map<String, Object> map1 = new HashMap<>();
map1.put("foo", "bar");
Map<String, Object> map2 = new HashMap<>();
map2.put("foo", map1);
ExecuteWatchResponse firstResponse = watcherClient().prepareExecuteWatch("_id")
.setActionMode("_all", ActionExecutionMode.SIMULATE)
.setAlternativeInput(map1)
.setRecordExecution(true)
.setTriggerEvent(new ScheduleTriggerEvent(new DateTime(DateTimeZone.UTC), new DateTime(DateTimeZone.UTC)))
.get();
ExecuteWatchResponse secondResponse = watcherClient().prepareExecuteWatch("_id")
.setActionMode("_all", ActionExecutionMode.SIMULATE)
.setAlternativeInput(map2)
.setRecordExecution(true)
.setTriggerEvent(new ScheduleTriggerEvent(new DateTime(DateTimeZone.UTC), new DateTime(DateTimeZone.UTC)))
.get();
String firstPayload = ObjectPath.eval("result.input.payload.foo", firstResponse.getRecordSource().getAsMap());
assertThat(firstPayload, is("bar"));
Map<String, String> secondPayload = ObjectPath.eval("result.input.payload", secondResponse.getRecordSource().getAsMap());
assertThat(secondPayload, instanceOf(Map.class));
}
public void testExecutionRequestDefaults() throws Exception {
WatchSourceBuilder watchBuilder = watchBuilder()
.trigger(schedule(cron("0 0 0 1 * ? 2099")))
.input(simpleInput("foo", "bar"))
.condition(NeverCondition.INSTANCE)
.defaultThrottlePeriod(TimeValue.timeValueHours(1))
.addAction("log", loggingAction("foobar"));
watcherClient().putWatch(new PutWatchRequest("_id", watchBuilder)).actionGet();
DateTime now = new DateTime(Clock.systemUTC().millis());
TriggerEvent triggerEvent = new ScheduleTriggerEvent(now, now);
Map<String, Object> executeWatchResult = watcherClient().prepareExecuteWatch()
.setId("_id")
.setTriggerEvent(triggerEvent)
.get().getRecordSource().getAsMap();
assertThat(ObjectPath.eval("state", executeWatchResult), equalTo(ExecutionState.EXECUTION_NOT_NEEDED.toString()));
assertThat(ObjectPath.eval("result.input.payload.foo", executeWatchResult), equalTo("bar"));
watchBuilder = watchBuilder()
.trigger(schedule(cron("0 0 0 1 * ? 2099")))
.input(simpleInput("foo", "bar"))
.condition(AlwaysCondition.INSTANCE)
.defaultThrottlePeriod(TimeValue.timeValueHours(1))
.addAction("log", loggingAction("foobar"));
watcherClient().putWatch(new PutWatchRequest("_id", watchBuilder)).actionGet();
executeWatchResult = watcherClient().prepareExecuteWatch()
.setId("_id").setTriggerEvent(triggerEvent).setRecordExecution(true)
.get().getRecordSource().getAsMap();
assertThat(ObjectPath.eval("state", executeWatchResult), equalTo(ExecutionState.EXECUTED.toString()));
assertThat(ObjectPath.eval("result.input.payload.foo", executeWatchResult), equalTo("bar"));
assertThat(ObjectPath.eval("result.actions.0.id", executeWatchResult), equalTo("log"));
executeWatchResult = watcherClient().prepareExecuteWatch()
.setId("_id").setTriggerEvent(triggerEvent)
.get().getRecordSource().getAsMap();
assertThat(ObjectPath.eval("state", executeWatchResult), equalTo(ExecutionState.THROTTLED.toString()));
}
public void testWatchExecutionDuration() throws Exception {
Script script = new Script(ScriptType.INLINE, WATCHER_LANG, "sleep", singletonMap("millis", 100L));
WatchSourceBuilder watchBuilder = watchBuilder()
.trigger(schedule(cron("0 0 0 1 * ? 2099")))
.input(simpleInput("foo", "bar"))
.condition(new ScriptCondition(script))
.addAction("log", loggingAction("foobar"));
watcherClient().preparePutWatch("_id").setSource(watchBuilder).get();
refresh(Watch.INDEX);
ScheduleTriggerEvent triggerEvent = new ScheduleTriggerEvent(new DateTime(DateTimeZone.UTC), new DateTime(DateTimeZone.UTC));
ExecuteWatchResponse executeWatchResponse = watcherClient().prepareExecuteWatch("_id").setTriggerEvent(triggerEvent).get();
Integer duration = ObjectPath.eval("result.execution_duration", executeWatchResponse.getRecordSource().getAsMap());
assertThat(duration, greaterThanOrEqualTo(100));
}
}

View File

@ -11,11 +11,9 @@ import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.test.http.MockResponse;
import org.elasticsearch.test.http.MockWebServer;
import org.elasticsearch.xpack.common.http.HttpRequestTemplate;
import org.elasticsearch.xpack.watcher.condition.AlwaysCondition;
import org.elasticsearch.xpack.watcher.history.HistoryStore;
import org.elasticsearch.xpack.watcher.support.xcontent.ObjectPath;
import org.elasticsearch.xpack.watcher.test.AbstractWatcherIntegrationTestCase;
import org.elasticsearch.xpack.watcher.transport.actions.delete.DeleteWatchRequest;
import org.elasticsearch.xpack.watcher.transport.actions.delete.DeleteWatchResponse;
import org.elasticsearch.xpack.watcher.transport.actions.execute.ExecuteWatchResponse;
import org.elasticsearch.xpack.watcher.transport.actions.get.GetWatchResponse;
@ -29,43 +27,14 @@ import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertHitC
import static org.elasticsearch.xpack.watcher.actions.ActionBuilders.loggingAction;
import static org.elasticsearch.xpack.watcher.client.WatchSourceBuilders.watchBuilder;
import static org.elasticsearch.xpack.watcher.input.InputBuilders.httpInput;
import static org.elasticsearch.xpack.watcher.input.InputBuilders.simpleInput;
import static org.elasticsearch.xpack.watcher.trigger.TriggerBuilders.schedule;
import static org.elasticsearch.xpack.watcher.trigger.schedule.Schedules.interval;
import static org.hamcrest.Matchers.hasKey;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.notNullValue;
public class DeleteWatchTests extends AbstractWatcherIntegrationTestCase {
public void testDelete() throws Exception {
ensureWatcherStarted();
PutWatchResponse putResponse = watcherClient().preparePutWatch("_name").setSource(watchBuilder()
.trigger(schedule(interval("5m")))
.input(simpleInput())
.condition(AlwaysCondition.INSTANCE)
.addAction("_action1", loggingAction("anything")))
.get();
assertThat(putResponse, notNullValue());
assertThat(putResponse.isCreated(), is(true));
DeleteWatchResponse deleteResponse = watcherClient().deleteWatch(new DeleteWatchRequest("_name")).get();
assertThat(deleteResponse, notNullValue());
assertThat(deleteResponse.getId(), is("_name"));
assertThat(deleteResponse.getVersion(), is(putResponse.getVersion() + 1));
assertThat(deleteResponse.isFound(), is(true));
}
public void testDeleteNotFound() throws Exception {
DeleteWatchResponse response = watcherClient().deleteWatch(new DeleteWatchRequest("_name")).get();
assertThat(response, notNullValue());
assertThat(response.getId(), is("_name"));
assertThat(response.getVersion(), is(1L));
assertThat(response.isFound(), is(false));
}
// This is a special case, since locking is removed
// Deleting a watch while it is being executed is possible now
// This test ensures that there are no leftovers, like a watch status without a watch in the watch store

View File

@ -9,27 +9,17 @@ import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.xpack.watcher.actions.ActionStatus;
import org.elasticsearch.xpack.watcher.client.WatcherClient;
import org.elasticsearch.xpack.watcher.condition.AlwaysCondition;
import org.elasticsearch.xpack.watcher.condition.NeverCondition;
import org.elasticsearch.xpack.watcher.execution.ActionExecutionMode;
import org.elasticsearch.xpack.watcher.execution.Wid;
import org.elasticsearch.xpack.watcher.support.WatcherDateTimeUtils;
import org.elasticsearch.xpack.watcher.support.xcontent.XContentSource;
import org.elasticsearch.xpack.watcher.test.AbstractWatcherIntegrationTestCase;
import org.elasticsearch.xpack.watcher.transport.actions.ack.AckWatchRequestBuilder;
import org.elasticsearch.xpack.watcher.transport.actions.ack.AckWatchResponse;
import org.elasticsearch.xpack.watcher.transport.actions.execute.ExecuteWatchRequestBuilder;
import org.elasticsearch.xpack.watcher.transport.actions.execute.ExecuteWatchResponse;
import org.elasticsearch.xpack.watcher.transport.actions.get.GetWatchResponse;
import org.elasticsearch.xpack.watcher.transport.actions.put.PutWatchResponse;
import org.elasticsearch.xpack.watcher.trigger.schedule.ScheduleTriggerEvent;
import org.elasticsearch.xpack.watcher.watch.WatchStatus;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import java.util.HashMap;
import java.util.Map;
import static java.util.Collections.singletonMap;
import static org.elasticsearch.xpack.watcher.actions.ActionBuilders.loggingAction;
import static org.elasticsearch.xpack.watcher.client.WatchSourceBuilders.watchBuilder;
import static org.elasticsearch.xpack.watcher.input.InputBuilders.simpleInput;
@ -84,149 +74,6 @@ public class ExecuteWatchTests extends AbstractWatcherIntegrationTestCase {
assertValue(record, "status.actions.log.ack.state", is("ackable"));
}
public void testExecuteCustomTriggerData() throws Exception {
WatcherClient watcherClient = watcherClient();
PutWatchResponse putWatchResponse = watcherClient.preparePutWatch()
.setId("_id")
.setSource(watchBuilder()
.trigger(schedule(cron("0/5 * * * * ? 2099")))
.input(simpleInput("foo", "bar"))
.condition(AlwaysCondition.INSTANCE)
.addAction("log", loggingAction("_text")))
.get();
assertThat(putWatchResponse.isCreated(), is(true));
DateTime triggeredTime = DateTime.now(DateTimeZone.UTC);
DateTime scheduledTime = randomBoolean() ? triggeredTime.minusDays(1) : triggeredTime;
ExecuteWatchRequestBuilder requestBuilder = watcherClient.prepareExecuteWatch("_id");
if (randomBoolean()) {
Map<String, Object> data = new HashMap<>();
data.put("triggered_time", WatcherDateTimeUtils.formatDate(triggeredTime));
if (scheduledTime != triggeredTime) {
data.put("scheduled_time", WatcherDateTimeUtils.formatDate(scheduledTime));
}
requestBuilder.setTriggerData(data);
} else {
ScheduleTriggerEvent event = new ScheduleTriggerEvent(triggeredTime, scheduledTime);
requestBuilder.setTriggerEvent(event);
}
ExecuteWatchResponse response = requestBuilder.get();
assertThat(response, notNullValue());
assertThat(response.getRecordId(), notNullValue());
Wid wid = new Wid(response.getRecordId());
assertThat(wid.watchId(), is("_id"));
XContentSource record = response.getRecordSource();
assertValue(record, "watch_id", is("_id"));
assertValue(record, "trigger_event.type", is("manual"));
assertValue(record, "trigger_event.triggered_time", is(WatcherDateTimeUtils.formatDate(triggeredTime)));
assertValue(record, "trigger_event.manual.schedule.scheduled_time", is(WatcherDateTimeUtils.formatDate(scheduledTime)));
assertValue(record, "state", is("executed"));
assertValue(record, "input.simple.foo", is("bar"));
assertValue(record, "condition.always", notNullValue());
assertValue(record, "result.execution_time", notNullValue());
assertValue(record, "result.execution_duration", notNullValue());
assertValue(record, "result.input.type", is("simple"));
assertValue(record, "result.input.payload.foo", is("bar"));
assertValue(record, "result.condition.type", is("always"));
assertValue(record, "result.condition.met", is(true));
assertValue(record, "result.actions.0.id", is("log"));
assertValue(record, "result.actions.0.type", is("logging"));
assertValue(record, "result.actions.0.status", is("success"));
assertValue(record, "result.actions.0.logging.logged_text", is("_text"));
}
public void testExecuteAlternativeInput() throws Exception {
WatcherClient watcherClient = watcherClient();
PutWatchResponse putWatchResponse = watcherClient.preparePutWatch()
.setId("_id")
.setSource(watchBuilder()
.trigger(schedule(cron("0/5 * * * * ? 2099")))
.input(simpleInput("foo", "bar"))
.condition(AlwaysCondition.INSTANCE)
.addAction("log", loggingAction("_text")))
.get();
assertThat(putWatchResponse.isCreated(), is(true));
ExecuteWatchResponse response = watcherClient.prepareExecuteWatch("_id")
.setAlternativeInput(singletonMap("foo1", "bar1"))
.get();
assertThat(response, notNullValue());
assertThat(response.getRecordId(), notNullValue());
Wid wid = new Wid(response.getRecordId());
assertThat(wid.watchId(), is("_id"));
XContentSource record = response.getRecordSource();
assertValue(record, "watch_id", is("_id"));
assertValue(record, "trigger_event.type", is("manual"));
assertValue(record, "trigger_event.triggered_time", notNullValue());
String triggeredTime = record.getValue("trigger_event.triggered_time");
assertValue(record, "trigger_event.manual.schedule.scheduled_time", is(triggeredTime));
assertValue(record, "state", is("executed"));
assertValue(record, "input.simple.foo", is("bar")); // this is the original input
assertValue(record, "condition.always", notNullValue());
assertValue(record, "result.execution_time", notNullValue());
assertValue(record, "result.execution_duration", notNullValue());
assertValue(record, "result.input.type", is("simple"));
assertValue(record, "result.input.payload.foo1", is("bar1")); // this is the alternative one
assertValue(record, "result.condition.type", is("always"));
assertValue(record, "result.condition.met", is(true));
assertValue(record, "result.actions.0.id", is("log"));
assertValue(record, "result.actions.0.type", is("logging"));
assertValue(record, "result.actions.0.status", is("success"));
assertValue(record, "result.actions.0.logging.logged_text", is("_text"));
}
public void testExecuteIgnoreCondition() throws Exception {
WatcherClient watcherClient = watcherClient();
PutWatchResponse putWatchResponse = watcherClient.preparePutWatch()
.setId("_id")
.setSource(watchBuilder()
.trigger(schedule(cron("0/5 * * * * ? 2099")))
.input(simpleInput("foo", "bar"))
.condition(NeverCondition.INSTANCE)
.addAction("log", loggingAction("_text")))
.get();
assertThat(putWatchResponse.isCreated(), is(true));
ExecuteWatchResponse response = watcherClient.prepareExecuteWatch("_id")
.setIgnoreCondition(true)
.get();
assertThat(response, notNullValue());
assertThat(response.getRecordId(), notNullValue());
Wid wid = new Wid(response.getRecordId());
assertThat(wid.watchId(), is("_id"));
XContentSource record = response.getRecordSource();
assertValue(record, "watch_id", is("_id"));
assertValue(record, "trigger_event.type", is("manual"));
assertValue(record, "trigger_event.triggered_time", notNullValue());
String triggeredTime = record.getValue("trigger_event.triggered_time");
assertValue(record, "trigger_event.manual.schedule.scheduled_time", is(triggeredTime));
assertValue(record, "state", is("executed"));
assertValue(record, "input.simple.foo", is("bar"));
assertValue(record, "condition.never", notNullValue()); // the original condition
assertValue(record, "result.execution_time", notNullValue());
assertValue(record, "result.execution_duration", notNullValue());
assertValue(record, "result.input.type", is("simple"));
assertValue(record, "result.input.payload.foo", is("bar"));
assertValue(record, "result.condition.type", is("always")); // when ignored, the condition is replaced with "always"
assertValue(record, "result.condition.met", is(true));
assertValue(record, "result.actions.0.id", is("log"));
assertValue(record, "result.actions.0.type", is("logging"));
assertValue(record, "result.actions.0.status", is("success"));
assertValue(record, "result.actions.0.logging.logged_text", is("_text"));
}
public void testExecuteActionMode() throws Exception {
final WatcherClient watcherClient = watcherClient();

View File

@ -1,54 +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.watcher.transport.action.put;
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.xpack.watcher.client.WatchSourceBuilder;
import org.elasticsearch.xpack.watcher.condition.AlwaysCondition;
import org.elasticsearch.xpack.watcher.test.AbstractWatcherIntegrationTestCase;
import org.elasticsearch.xpack.watcher.transport.actions.put.PutWatchResponse;
import static org.elasticsearch.xpack.watcher.actions.ActionBuilders.loggingAction;
import static org.elasticsearch.xpack.watcher.client.WatchSourceBuilders.watchBuilder;
import static org.elasticsearch.xpack.watcher.input.InputBuilders.simpleInput;
import static org.elasticsearch.xpack.watcher.trigger.TriggerBuilders.schedule;
import static org.elasticsearch.xpack.watcher.trigger.schedule.Schedules.interval;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
public class PutWatchTests extends AbstractWatcherIntegrationTestCase {
public void testPut() throws Exception {
WatchSourceBuilder source = watchBuilder()
.trigger(schedule(interval("5m")));
if (randomBoolean()) {
source.input(simpleInput());
}
if (randomBoolean()) {
source.condition(AlwaysCondition.INSTANCE);
}
if (randomBoolean()) {
source.addAction("_action1", loggingAction("{{ctx.watch_id}}"));
}
PutWatchResponse response = watcherClient().preparePutWatch("_name").setSource(source).get();
assertThat(response, notNullValue());
assertThat(response.isCreated(), is(true));
assertThat(response.getVersion(), is(1L));
}
public void testPutNoTrigger() throws Exception {
ElasticsearchException exception = expectThrows(ElasticsearchException.class,
() -> watcherClient().preparePutWatch("_name").setSource(watchBuilder()
.input(simpleInput())
.condition(AlwaysCondition.INSTANCE)
.addAction("_action1", loggingAction("{{ctx.watch_id}}")))
.get());
assertEquals("Failed to build ToXContent", exception.getMessage());
}
}

View File

@ -50,6 +50,9 @@ import org.elasticsearch.xpack.watcher.actions.email.ExecutableEmailAction;
import org.elasticsearch.xpack.watcher.actions.index.ExecutableIndexAction;
import org.elasticsearch.xpack.watcher.actions.index.IndexAction;
import org.elasticsearch.xpack.watcher.actions.index.IndexActionFactory;
import org.elasticsearch.xpack.watcher.actions.logging.ExecutableLoggingAction;
import org.elasticsearch.xpack.watcher.actions.logging.LoggingAction;
import org.elasticsearch.xpack.watcher.actions.logging.LoggingActionFactory;
import org.elasticsearch.xpack.watcher.actions.throttler.ActionThrottler;
import org.elasticsearch.xpack.watcher.actions.webhook.ExecutableWebhookAction;
import org.elasticsearch.xpack.watcher.actions.webhook.WebhookAction;
@ -68,6 +71,7 @@ import org.elasticsearch.xpack.watcher.input.InputBuilders;
import org.elasticsearch.xpack.watcher.input.InputFactory;
import org.elasticsearch.xpack.watcher.input.InputRegistry;
import org.elasticsearch.xpack.watcher.input.none.ExecutableNoneInput;
import org.elasticsearch.xpack.watcher.input.none.NoneInput;
import org.elasticsearch.xpack.watcher.input.search.ExecutableSearchInput;
import org.elasticsearch.xpack.watcher.input.search.SearchInput;
import org.elasticsearch.xpack.watcher.input.search.SearchInputFactory;
@ -76,6 +80,7 @@ import org.elasticsearch.xpack.watcher.input.simple.SimpleInput;
import org.elasticsearch.xpack.watcher.input.simple.SimpleInputFactory;
import org.elasticsearch.xpack.watcher.support.search.WatcherSearchTemplateRequest;
import org.elasticsearch.xpack.watcher.support.search.WatcherSearchTemplateService;
import org.elasticsearch.xpack.watcher.test.MockTextTemplateEngine;
import org.elasticsearch.xpack.watcher.test.WatcherTestUtils;
import org.elasticsearch.xpack.watcher.transform.ExecutableTransform;
import org.elasticsearch.xpack.watcher.transform.TransformFactory;
@ -132,7 +137,9 @@ import static org.elasticsearch.search.builder.SearchSourceBuilder.searchSource;
import static org.elasticsearch.xpack.watcher.input.InputBuilders.searchInput;
import static org.elasticsearch.xpack.watcher.test.WatcherTestUtils.templateRequest;
import static org.elasticsearch.xpack.watcher.trigger.TriggerBuilders.schedule;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
@ -375,6 +382,76 @@ public class WatchTests extends ESTestCase {
assertThat(((ScriptQueryBuilder) searchRequest.source().query()).script().getLang(), equalTo(Script.DEFAULT_SCRIPT_LANG));
}
public void testParseWatchWithoutInput() throws Exception {
try (XContentBuilder builder = jsonBuilder()) {
builder.startObject();
builder.startObject("trigger").startObject("schedule").field("interval", "99w").endObject().endObject();
builder.startObject("condition").startObject("always").endObject().endObject();
builder.startObject("actions").startObject("logme")
.startObject("logging").field("text", "foo").endObject()
.endObject().endObject();
builder.endObject();
Watch.Parser parser = createWatchparser();
Watch watch = parser.parse("_id", false, builder.bytes(), XContentType.JSON);
assertThat(watch, is(notNullValue()));
assertThat(watch.input().type(), is(NoneInput.TYPE));
}
}
public void testParseWatchWithoutAction() throws Exception {
try (XContentBuilder builder = jsonBuilder()) {
builder.startObject();
builder.startObject("trigger").startObject("schedule").field("interval", "99w").endObject().endObject();
builder.startObject("input").startObject("simple").endObject().endObject();
builder.startObject("condition").startObject("always").endObject().endObject();
builder.endObject();
Watch.Parser parser = createWatchparser();
Watch watch = parser.parse("_id", false, builder.bytes(), XContentType.JSON);
assertThat(watch, is(notNullValue()));
assertThat(watch.actions(), hasSize(0));
}
}
public void testParseWatchWithoutTriggerDoesNotWork() throws Exception {
try (XContentBuilder builder = jsonBuilder()) {
builder.startObject();
builder.startObject("input").startObject("simple").endObject().endObject();
builder.startObject("condition").startObject("always").endObject().endObject();
builder.startObject("actions").startObject("logme")
.startObject("logging").field("text", "foo").endObject()
.endObject().endObject();
builder.endObject();
Watch.Parser parser = createWatchparser();
ElasticsearchParseException e = expectThrows(ElasticsearchParseException.class,
() -> parser.parse("_id", false, builder.bytes(), XContentType.JSON));
assertThat(e.getMessage(), is("could not parse watch [_id]. missing required field [trigger]"));
}
}
private Watch.Parser createWatchparser() throws Exception {
LoggingAction loggingAction = new LoggingAction(new TextTemplate("foo"), null, null);
List<ActionWrapper> actions = Collections.singletonList(new ActionWrapper("_logging_", randomThrottler(), null, null,
new ExecutableLoggingAction(loggingAction, logger, settings, new MockTextTemplateEngine())));
ScheduleRegistry scheduleRegistry = registry(new IntervalSchedule(new IntervalSchedule.Interval(1,
IntervalSchedule.Interval.Unit.SECONDS)));
TriggerEngine triggerEngine = new ParseOnlyScheduleTriggerEngine(Settings.EMPTY, scheduleRegistry, Clock.systemUTC());
TriggerService triggerService = new TriggerService(Settings.EMPTY, singleton(triggerEngine));
ConditionRegistry conditionRegistry = conditionRegistry();
InputRegistry inputRegistry = registry(SimpleInput.TYPE);
TransformRegistry transformRegistry = transformRegistry();
ActionRegistry actionRegistry = registry(actions, conditionRegistry, transformRegistry);
return new Watch.Parser(settings, triggerService, actionRegistry, inputRegistry, null, Clock.systemUTC());
}
private static Schedule randomSchedule() {
String type = randomFrom(CronSchedule.TYPE, HourlySchedule.TYPE, DailySchedule.TYPE, WeeklySchedule.TYPE, MonthlySchedule.TYPE,
YearlySchedule.TYPE, IntervalSchedule.TYPE);
@ -541,6 +618,9 @@ public class WatchTests extends ESTestCase {
parsers.put(WebhookAction.TYPE, new WebhookActionFactory(settings, httpClient,
new HttpRequestTemplate.Parser(authRegistry), templateEngine));
break;
case LoggingAction.TYPE:
parsers.put(LoggingAction.TYPE, new LoggingActionFactory(settings, new MockTextTemplateEngine()));
break;
}
}
return new ActionRegistry(unmodifiableMap(parsers), conditionRegistry, transformRegistry, Clock.systemUTC(), licenseState);

View File

@ -1,9 +1,18 @@
---
"Test delete watch api":
setup:
- do:
cluster.health:
wait_for_status: yellow
---
teardown:
- do:
xpack.watcher.delete_watch:
id: "my_watch"
ignore: 404
---
"Test delete watch api":
- do:
xpack.watcher.put_watch:
id: "my_watch"
@ -37,6 +46,7 @@
}
}
- match: { _id: "my_watch" }
- match: { created: true }
- do:
xpack.watcher.delete_watch:
@ -51,10 +61,6 @@
---
"Non existent watch returns 404":
- do:
cluster.health:
wait_for_status: yellow
- do:
xpack.watcher.delete_watch:
id: "non-existent-watch"

View File

@ -106,3 +106,49 @@ teardown:
xpack.watcher.execute_watch:
id: "non-existent-watch"
catch: missing
---
"Test execute watch with alternative input":
- do:
xpack.watcher.put_watch:
id: "test_watch"
body: >
{
"trigger": {
"schedule" : { "cron" : "0 0 0 1 * ? 2099" }
},
"input": {
"simple": {
"foo": "bar"
}
},
"actions": {
"indexme" : {
"index" : {
"index" : "my-index",
"doc_type" : "my-type",
"doc_id": "my-id"
}
}
}
}
- match: { _id: "test_watch" }
- match: { created: true }
- do:
xpack.watcher.execute_watch:
id: "test_watch"
body: >
{
"alternative_input" : {
"spam" : "eggs"
}
}
- match: { watch_record.watch_id: "test_watch" }
- match: { watch_record.state: "executed" }
- match: { watch_record.status.state.active: true }
- is_true: watch_record.node
- is_false: watch_record.result.input.payload.foo
- is_true: watch_record.result.input.payload.spam

View File

@ -0,0 +1,118 @@
---
setup:
- do:
cluster.health:
wait_for_status: yellow
---
teardown:
- do:
xpack.watcher.delete_watch:
id: "test_watch"
ignore: 404
---
"Test execute watch api works with throttling":
- do:
xpack.watcher.put_watch:
id: "test_watch"
body: >
{
"trigger": {
"schedule" : { "cron" : "0 0 0 1 * ? 2099" }
},
"input": {
"simple": {
"foo": "bar"
}
},
"condition": {
"never": {}
},
"actions": {
"logging" : {
"logging" : {
"text" : "logging text from test: execute_watch/30_throttled.yml"
}
}
}
}
- match: { _id: "test_watch" }
- match: { created: true }
- do:
xpack.watcher.execute_watch:
id: "test_watch"
body: >
{
"trigger_data" : {
"triggered_time" : "2012-12-12T12:12:12.120Z",
"scheduled_time" : "2000-12-12T12:12:12.120Z"
}
}
- match: { watch_record.watch_id: "test_watch" }
- match: { watch_record.trigger_event.type: "manual" }
- match: { watch_record.trigger_event.triggered_time: "2012-12-12T12:12:12.120Z" }
- match: { watch_record.trigger_event.manual.schedule.scheduled_time: "2000-12-12T12:12:12.120Z" }
- match: { watch_record.state: "execution_not_needed" }
- match: { watch_record.status.state.active: true }
- do:
xpack.watcher.put_watch:
id: "test_watch"
body: >
{
"trigger": {
"schedule" : { "cron" : "0 0 0 1 * ? 2099" }
},
"input": {
"simple": {
"foo": "bar"
}
},
"condition": {
"always": {}
},
"throttle_period" : "1h",
"actions": {
"logging" : {
"logging" : {
"text" : "logging text from test: execute_watch/30_throttled.yml"
}
}
}
}
- match: { _id: "test_watch" }
- do:
xpack.watcher.execute_watch:
id: "test_watch"
body: >
{
"trigger_data" : {
"triggered_time" : "2012-12-12T12:12:12.120Z",
"scheduled_time" : "2000-12-12T12:12:12.120Z"
},
"record_execution": true
}
- match: { watch_record.watch_id: "test_watch" }
- match: { watch_record.state: "executed" }
- do:
xpack.watcher.execute_watch:
id: "test_watch"
body: >
{
"trigger_data" : {
"triggered_time" : "2012-12-12T12:12:12.120Z",
"scheduled_time" : "2000-12-12T12:12:12.120Z"
},
"record_execution": true
}
- match: { watch_record.watch_id: "test_watch" }
- match: { watch_record.state: "throttled" }

View File

@ -0,0 +1,63 @@
---
setup:
- do:
cluster.health:
wait_for_status: yellow
---
teardown:
- do:
xpack.watcher.delete_watch:
id: "test_watch"
ignore: 404
---
"Test execute watch api can ignore conditions":
- do:
xpack.watcher.put_watch:
id: "test_watch"
body: >
{
"trigger": {
"schedule" : { "cron" : "0 0 0 1 * ? 2099" }
},
"input": {
"simple": {
"foo": "bar"
}
},
"condition": {
"never": {}
},
"actions": {
"logging" : {
"logging" : {
"text" : "logging text from test: execute_watch/30_throttled.yml"
}
}
}
}
- match: { _id: "test_watch" }
- match: { created: true }
- do:
xpack.watcher.execute_watch:
id: "test_watch"
body: >
{
"ignore_condition" : true
}
- match: { watch_record.watch_id: "test_watch" }
- match: { watch_record.input.simple.foo: "bar" }
- match: { watch_record.trigger_event.type: "manual" }
- match: { watch_record.state: "executed" }
- match: { watch_record.status.state.active: true }
- match: { watch_record.status.actions.logging.ack.state: "ackable" }
- is_true: watch_record.condition.never
- is_true: watch_record.result.execution_time
- is_true: watch_record.result.execution_duration
- match: { watch_record.result.input.type: "simple" }
- match: { watch_record.result.input.payload.foo: "bar" }
- match: { watch_record.result.condition.type: "always" }
- match: { watch_record.result.condition.met: true }

View File

@ -0,0 +1,71 @@
---
setup:
- do:
cluster.health:
wait_for_status: yellow
---
teardown:
- do:
xpack.watcher.delete_watch:
id: "test_watch"
ignore: 404
---
"Test execute watch api supports action modes":
- do:
xpack.watcher.put_watch:
id: "test_watch"
body: >
{
"trigger": {
"schedule" : { "cron" : "0 0 0 1 * ? 2099" }
},
"input": {
"simple": {
"foo": "bar"
}
},
"actions": {
"logging" : {
"logging" : {
"text" : "logging text from test: execute_watch/30_throttled.yml"
}
}
}
}
- match: { _id: "test_watch" }
- match: { created: true }
- do:
xpack.watcher.execute_watch:
id: "test_watch"
body: >
{
"action_modes" : {
"logging" : "simulate"
}
}
- match: { watch_record.watch_id: "test_watch" }
- match: { watch_record.trigger_event.type: "manual" }
- match: { watch_record.state: "executed" }
- match: { watch_record.result.actions.0.id: "logging" }
- match: { watch_record.result.actions.0.status: "simulated" }
- do:
xpack.watcher.execute_watch:
id: "test_watch"
body: >
{
"action_modes" : {
"_all" : "simulate"
}
}
- match: { watch_record.watch_id: "test_watch" }
- match: { watch_record.trigger_event.type: "manual" }
- match: { watch_record.state: "executed" }
- match: { watch_record.result.actions.0.id: "logging" }
- match: { watch_record.result.actions.0.status: "simulated" }