From 5d307e2b7cc86168b073506f974ba1d7163419ac Mon Sep 17 00:00:00 2001 From: Matteo Mazzola Date: Wed, 21 Jan 2026 14:09:18 +0000 Subject: [PATCH] Migrate third party module tests using legacy test clusters framework (#140991) (cherry picked from commit e5f96379c234fe94059ffc6650f5388d35f4bb39) # Conflicts: # build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/RestrictedBuildApiService.java --- .../internal/RestrictedBuildApiService.java | 3 - x-pack/qa/third-party/build.gradle | 8 ++ x-pack/qa/third-party/jira/build.gradle | 25 ++---- .../smoketest/WatcherJiraYamlTestSuiteIT.java | 75 +++++----------- x-pack/qa/third-party/pagerduty/build.gradle | 23 ++--- .../WatcherPagerDutyYamlTestSuiteIT.java | 66 +++----------- x-pack/qa/third-party/slack/build.gradle | 19 ++-- .../WatcherSlackYamlTestSuiteIT.java | 66 +++----------- ...tractWatcherThirdPartyYamlTestSuiteIT.java | 90 +++++++++++++++++++ 9 files changed, 166 insertions(+), 209 deletions(-) create mode 100644 x-pack/qa/third-party/src/main/java/org/elasticsearch/smoketest/AbstractWatcherThirdPartyYamlTestSuiteIT.java diff --git a/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/RestrictedBuildApiService.java b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/RestrictedBuildApiService.java index 0b856d8e42842..40f9dcf0d27a1 100644 --- a/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/RestrictedBuildApiService.java +++ b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/RestrictedBuildApiService.java @@ -53,9 +53,6 @@ private static ListMultimap, String> createLegacyRestTestBasePluginUsag map.put(LegacyRestTestBasePlugin.class, ":x-pack:qa:multi-cluster-search-security:legacy-with-basic-license"); map.put(LegacyRestTestBasePlugin.class, ":x-pack:qa:multi-cluster-search-security:legacy-with-full-license"); map.put(LegacyRestTestBasePlugin.class, ":x-pack:qa:multi-cluster-search-security:legacy-with-restricted-trust"); - map.put(LegacyRestTestBasePlugin.class, ":x-pack:qa:third-party:jira"); - map.put(LegacyRestTestBasePlugin.class, ":x-pack:qa:third-party:pagerduty"); - map.put(LegacyRestTestBasePlugin.class, ":x-pack:qa:third-party:slack"); map.put(LegacyRestTestBasePlugin.class, ":x-pack:plugin:ent-search:qa:rest"); map.put(LegacyRestTestBasePlugin.class, ":x-pack:plugin:eql:qa:ccs-rolling-upgrade"); map.put(LegacyRestTestBasePlugin.class, ":x-pack:plugin:eql:qa:correctness"); diff --git a/x-pack/qa/third-party/build.gradle b/x-pack/qa/third-party/build.gradle index e69de29bb2d1d..c6337bf162934 100644 --- a/x-pack/qa/third-party/build.gradle +++ b/x-pack/qa/third-party/build.gradle @@ -0,0 +1,8 @@ +apply plugin: 'elasticsearch.java' + +dependencies { + api project(':test:framework') + api project(':test:yaml-rest-runner') + api project(':test:test-clusters') + api project(xpackModule('core')) +} diff --git a/x-pack/qa/third-party/jira/build.gradle b/x-pack/qa/third-party/jira/build.gradle index 7e3d0485545a6..7cbf108e7ae61 100644 --- a/x-pack/qa/third-party/jira/build.gradle +++ b/x-pack/qa/third-party/jira/build.gradle @@ -10,16 +10,18 @@ import groovy.json.JsonSlurper import javax.net.ssl.HttpsURLConnection import java.nio.charset.StandardCharsets -apply plugin: 'elasticsearch.legacy-yaml-rest-test' +apply plugin: 'elasticsearch.internal-yaml-rest-test' dependencies { - yamlRestTestImplementation project(':x-pack:plugin:core') - yamlRestTestImplementation project(path: xpackModule('watcher')) + yamlRestTestImplementation project(':x-pack:qa:third-party') + + clusterModules project(xpackModule('watcher')) + clusterModules project(xpackModule('ilm')) } restResources { restApi { - include 'watcher' + include '_common', 'cluster', 'indices', 'search', 'watcher' } } @@ -44,20 +46,7 @@ tasks.register("cleanJira", DefaultTask) { if (!jiraUrl && !jiraUser && !jiraPassword && !jiraProject) { tasks.named("yamlRestTest").configure { enabled = false } } else { - testClusters.matching { it.name == "yamlRestTest" }.configureEach { - testDistribution = 'DEFAULT' - setting 'xpack.security.enabled', 'false' - setting 'xpack.ml.enabled', 'false' - setting 'xpack.license.self_generated.type', 'trial' - setting 'logger.org.elasticsearch.xpack.watcher', 'DEBUG' - setting 'xpack.notification.jira.account.test.issue_defaults.issuetype.name', 'Bug' - setting 'xpack.notification.jira.account.test.issue_defaults.labels.0', 'integration-tests' - setting 'xpack.notification.jira.account.test.issue_defaults.project.key', jiraProject - keystore 'xpack.notification.jira.account.test.secure_url', jiraUrl - keystore 'xpack.notification.jira.account.test.secure_user', jiraUser - keystore 'xpack.notification.jira.account.test.secure_password', jiraPassword - } - tasks.named("yamlRestTest")configure { finalizedBy "cleanJira" } + tasks.named("yamlRestTest").configure { finalizedBy "cleanJira" } } if (buildParams.inFipsJvm){ diff --git a/x-pack/qa/third-party/jira/src/yamlRestTest/java/org/elasticsearch/smoketest/WatcherJiraYamlTestSuiteIT.java b/x-pack/qa/third-party/jira/src/yamlRestTest/java/org/elasticsearch/smoketest/WatcherJiraYamlTestSuiteIT.java index 250920382719a..b4454408314e3 100644 --- a/x-pack/qa/third-party/jira/src/yamlRestTest/java/org/elasticsearch/smoketest/WatcherJiraYamlTestSuiteIT.java +++ b/x-pack/qa/third-party/jira/src/yamlRestTest/java/org/elasticsearch/smoketest/WatcherJiraYamlTestSuiteIT.java @@ -9,22 +9,29 @@ import com.carrotsearch.randomizedtesting.annotations.Name; import com.carrotsearch.randomizedtesting.annotations.ParametersFactory; +import org.elasticsearch.test.cluster.ElasticsearchCluster; 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.List; -import java.util.Map; -import java.util.concurrent.TimeUnit; - -import static org.hamcrest.Matchers.is; +import org.junit.ClassRule; /** Runs rest tests against external cluster */ -public class WatcherJiraYamlTestSuiteIT extends ESClientYamlSuiteTestCase { +public class WatcherJiraYamlTestSuiteIT extends AbstractWatcherThirdPartyYamlTestSuiteIT { + + @ClassRule + public static ElasticsearchCluster cluster = baseClusterBuilder().setting( + "xpack.notification.jira.account.test.issue_defaults.issuetype.name", + "Bug" + ) + .setting("xpack.notification.jira.account.test.issue_defaults.labels.0", "integration-tests") + .setting("xpack.notification.jira.account.test.issue_defaults.project.key", System.getenv("jira_project")) + .keystore("xpack.notification.jira.account.test.secure_url", System.getenv("jira_url")) + .keystore("xpack.notification.jira.account.test.secure_user", System.getenv("jira_user")) + .keystore("xpack.notification.jira.account.test.secure_password", System.getenv("jira_password")) + .build(); + + @Override + protected ElasticsearchCluster getCluster() { + return cluster; + } public WatcherJiraYamlTestSuiteIT(@Name("yaml") ClientYamlTestCandidate testCandidate) { super(testCandidate); @@ -32,46 +39,6 @@ public WatcherJiraYamlTestSuiteIT(@Name("yaml") ClientYamlTestCandidate testCand @ParametersFactory public static Iterable parameters() throws Exception { - return ESClientYamlSuiteTestCase.createParameters(); - } - - @Before - public void startWatcher() throws Exception { - final List watcherTemplates = List.of(WatcherIndexTemplateRegistryField.TEMPLATE_NAMES_NO_ILM); - assertBusy(() -> { - try { - getAdminExecutionContext().callApi("watcher.start", Map.of(), List.of(), Map.of()); - - for (String template : watcherTemplates) { - ClientYamlTestResponse templateExistsResponse = getAdminExecutionContext().callApi( - "indices.exists_template", - Map.of("name", template), - List.of(), - Map.of() - ); - assertThat(templateExistsResponse.getStatusCode(), is(200)); - } - - ClientYamlTestResponse response = getAdminExecutionContext().callApi("watcher.stats", Map.of(), List.of(), Map.of()); - String state = 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("watcher.stop", Map.of(), List.of(), Map.of()); - ClientYamlTestResponse response = getAdminExecutionContext().callApi("watcher.stats", Map.of(), List.of(), Map.of()); - String state = response.evaluate("stats.0.watcher_state"); - assertThat(state, is("stopped")); - } catch (IOException e) { - throw new AssertionError(e); - } - }, 60, TimeUnit.SECONDS); + return createParameters(); } } diff --git a/x-pack/qa/third-party/pagerduty/build.gradle b/x-pack/qa/third-party/pagerduty/build.gradle index 20f7b9b654b66..0c0884300ecd9 100644 --- a/x-pack/qa/third-party/pagerduty/build.gradle +++ b/x-pack/qa/third-party/pagerduty/build.gradle @@ -5,32 +5,25 @@ * 2.0. */ -apply plugin: 'elasticsearch.legacy-yaml-rest-test' +apply plugin: 'elasticsearch.internal-yaml-rest-test' dependencies { - yamlRestTestImplementation project(':x-pack:plugin:core') - yamlRestTestImplementation project(path: xpackModule('watcher')) -} + yamlRestTestImplementation project(':x-pack:qa:third-party') -String pagerDutyServiceKey = System.getenv('pagerduty_service_api_key') + clusterModules project(xpackModule('watcher')) + clusterModules project(xpackModule('ilm')) +} restResources { restApi { - include 'watcher' + include '_common', 'watcher', 'indices', 'cluster', 'search' } } +String pagerDutyServiceKey = System.getenv('pagerduty_service_api_key') + if (!pagerDutyServiceKey) { tasks.named("yamlRestTest").configure { enabled = false } -} else { - testClusters.matching { it.name == "yamlRestTest" }.configureEach { - testDistribution = 'DEFAULT' - setting 'xpack.security.enabled', 'false' - setting 'xpack.ml.enabled', 'false' - setting 'xpack.license.self_generated.type', 'trial' - setting 'logger.org.elasticsearch.xpack.watcher', 'DEBUG' - keystore 'xpack.notification.pagerduty.account.test_account.secure_service_api_key', pagerDutyServiceKey - } } if (buildParams.inFipsJvm){ diff --git a/x-pack/qa/third-party/pagerduty/src/yamlRestTest/java/org/elasticsearch/smoketest/WatcherPagerDutyYamlTestSuiteIT.java b/x-pack/qa/third-party/pagerduty/src/yamlRestTest/java/org/elasticsearch/smoketest/WatcherPagerDutyYamlTestSuiteIT.java index a8e522f3836fb..9a31f49779cf8 100644 --- a/x-pack/qa/third-party/pagerduty/src/yamlRestTest/java/org/elasticsearch/smoketest/WatcherPagerDutyYamlTestSuiteIT.java +++ b/x-pack/qa/third-party/pagerduty/src/yamlRestTest/java/org/elasticsearch/smoketest/WatcherPagerDutyYamlTestSuiteIT.java @@ -9,22 +9,22 @@ import com.carrotsearch.randomizedtesting.annotations.Name; import com.carrotsearch.randomizedtesting.annotations.ParametersFactory; +import org.elasticsearch.test.cluster.ElasticsearchCluster; 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 org.junit.ClassRule; -import java.io.IOException; -import java.util.List; -import java.util.Map; -import java.util.concurrent.TimeUnit; +public class WatcherPagerDutyYamlTestSuiteIT extends AbstractWatcherThirdPartyYamlTestSuiteIT { -import static org.hamcrest.Matchers.is; + @ClassRule + public static ElasticsearchCluster cluster = baseClusterBuilder().keystore( + "xpack.notification.pagerduty.account.test_account.secure_service_api_key", + System.getenv("pagerduty_service_api_key") + ).build(); -/** Runs rest tests against external cluster */ -public class WatcherPagerDutyYamlTestSuiteIT extends ESClientYamlSuiteTestCase { + @Override + protected ElasticsearchCluster getCluster() { + return cluster; + } public WatcherPagerDutyYamlTestSuiteIT(@Name("yaml") ClientYamlTestCandidate testCandidate) { super(testCandidate); @@ -32,46 +32,6 @@ public WatcherPagerDutyYamlTestSuiteIT(@Name("yaml") ClientYamlTestCandidate tes @ParametersFactory public static Iterable parameters() throws Exception { - return ESClientYamlSuiteTestCase.createParameters(); - } - - @Before - public void startWatcher() throws Exception { - final List watcherTemplates = List.of(WatcherIndexTemplateRegistryField.TEMPLATE_NAMES_NO_ILM); - assertBusy(() -> { - try { - getAdminExecutionContext().callApi("watcher.start", Map.of(), List.of(), Map.of()); - - for (String template : watcherTemplates) { - ClientYamlTestResponse templateExistsResponse = getAdminExecutionContext().callApi( - "indices.exists_template", - Map.of("name", template), - List.of(), - Map.of() - ); - assertThat(templateExistsResponse.getStatusCode(), is(200)); - } - - ClientYamlTestResponse response = getAdminExecutionContext().callApi("watcher.stats", Map.of(), List.of(), Map.of()); - String state = 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("watcher.stop", Map.of(), List.of(), Map.of()); - ClientYamlTestResponse response = getAdminExecutionContext().callApi("watcher.stats", Map.of(), List.of(), Map.of()); - String state = response.evaluate("stats.0.watcher_state"); - assertThat(state, is("stopped")); - } catch (IOException e) { - throw new AssertionError(e); - } - }, 60, TimeUnit.SECONDS); + return createParameters(); } } diff --git a/x-pack/qa/third-party/slack/build.gradle b/x-pack/qa/third-party/slack/build.gradle index 54821a9d2b71a..ec031fe2a9f6c 100644 --- a/x-pack/qa/third-party/slack/build.gradle +++ b/x-pack/qa/third-party/slack/build.gradle @@ -5,16 +5,18 @@ * 2.0. */ -apply plugin: 'elasticsearch.legacy-yaml-rest-test' +apply plugin: 'elasticsearch.internal-yaml-rest-test' dependencies { - yamlRestTestImplementation project(':x-pack:plugin:core') - yamlRestTestImplementation project(path: xpackModule('watcher')) + yamlRestTestImplementation project(':x-pack:qa:third-party') + + clusterModules project(xpackModule('watcher')) + clusterModules project(xpackModule('ilm')) } restResources { restApi { - include 'watcher' + include '_common', 'cluster', 'indices', 'search', 'watcher' } } @@ -22,15 +24,6 @@ String slackUrl = System.getenv('slack_url') if (!slackUrl) { tasks.named("yamlRestTest").configure { enabled = false } -} else { - testClusters.matching { it.name == "yamlRestTest" }.configureEach { - testDistribution = 'DEFAULT' - setting 'xpack.security.enabled', 'false' - setting 'xpack.ml.enabled', 'false' - setting 'xpack.license.self_generated.type', 'trial' - setting 'logger.org.elasticsearch.xpack.watcher', 'DEBUG' - keystore 'xpack.notification.slack.account.test_account.secure_url', slackUrl - } } if (buildParams.inFipsJvm){ diff --git a/x-pack/qa/third-party/slack/src/yamlRestTest/java/org/elasticsearch/smoketest/WatcherSlackYamlTestSuiteIT.java b/x-pack/qa/third-party/slack/src/yamlRestTest/java/org/elasticsearch/smoketest/WatcherSlackYamlTestSuiteIT.java index 9cb64bab89d34..4e82514280b3b 100644 --- a/x-pack/qa/third-party/slack/src/yamlRestTest/java/org/elasticsearch/smoketest/WatcherSlackYamlTestSuiteIT.java +++ b/x-pack/qa/third-party/slack/src/yamlRestTest/java/org/elasticsearch/smoketest/WatcherSlackYamlTestSuiteIT.java @@ -9,22 +9,22 @@ import com.carrotsearch.randomizedtesting.annotations.Name; import com.carrotsearch.randomizedtesting.annotations.ParametersFactory; +import org.elasticsearch.test.cluster.ElasticsearchCluster; 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 org.junit.ClassRule; -import java.io.IOException; -import java.util.List; -import java.util.Map; -import java.util.concurrent.TimeUnit; +public class WatcherSlackYamlTestSuiteIT extends AbstractWatcherThirdPartyYamlTestSuiteIT { -import static org.hamcrest.Matchers.is; + @ClassRule + public static ElasticsearchCluster cluster = baseClusterBuilder().keystore( + "xpack.notification.slack.account.test_account.secure_url", + System.getenv("slack_url") + ).build(); -/** Runs rest tests against external cluster */ -public class WatcherSlackYamlTestSuiteIT extends ESClientYamlSuiteTestCase { + @Override + protected ElasticsearchCluster getCluster() { + return cluster; + } public WatcherSlackYamlTestSuiteIT(@Name("yaml") ClientYamlTestCandidate testCandidate) { super(testCandidate); @@ -32,46 +32,6 @@ public WatcherSlackYamlTestSuiteIT(@Name("yaml") ClientYamlTestCandidate testCan @ParametersFactory public static Iterable parameters() throws Exception { - return ESClientYamlSuiteTestCase.createParameters(); - } - - @Before - public void startWatcher() throws Exception { - final List watcherTemplates = List.of(WatcherIndexTemplateRegistryField.TEMPLATE_NAMES_NO_ILM); - assertBusy(() -> { - try { - getAdminExecutionContext().callApi("watcher.start", Map.of(), List.of(), Map.of()); - - for (String template : watcherTemplates) { - ClientYamlTestResponse templateExistsResponse = getAdminExecutionContext().callApi( - "indices.exists_template", - Map.of("name", template), - List.of(), - Map.of() - ); - assertThat(templateExistsResponse.getStatusCode(), is(200)); - } - - ClientYamlTestResponse response = getAdminExecutionContext().callApi("watcher.stats", Map.of(), List.of(), Map.of()); - String state = 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("watcher.stop", Map.of(), List.of(), Map.of()); - ClientYamlTestResponse response = getAdminExecutionContext().callApi("watcher.stats", Map.of(), List.of(), Map.of()); - String state = response.evaluate("stats.0.watcher_state"); - assertThat(state, is("stopped")); - } catch (IOException e) { - throw new AssertionError(e); - } - }, 60, TimeUnit.SECONDS); + return createParameters(); } } diff --git a/x-pack/qa/third-party/src/main/java/org/elasticsearch/smoketest/AbstractWatcherThirdPartyYamlTestSuiteIT.java b/x-pack/qa/third-party/src/main/java/org/elasticsearch/smoketest/AbstractWatcherThirdPartyYamlTestSuiteIT.java new file mode 100644 index 0000000000000..9384118e1994b --- /dev/null +++ b/x-pack/qa/third-party/src/main/java/org/elasticsearch/smoketest/AbstractWatcherThirdPartyYamlTestSuiteIT.java @@ -0,0 +1,90 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +package org.elasticsearch.smoketest; + +import com.carrotsearch.randomizedtesting.annotations.Name; + +import org.elasticsearch.test.cluster.ElasticsearchCluster; +import org.elasticsearch.test.cluster.local.LocalClusterSpecBuilder; +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.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +import static org.hamcrest.Matchers.is; + +public abstract class AbstractWatcherThirdPartyYamlTestSuiteIT extends ESClientYamlSuiteTestCase { + + private static final Map NO_ERROR_TRACE = Map.of("error_trace", "false"); + + protected static LocalClusterSpecBuilder baseClusterBuilder() { + return ElasticsearchCluster.local() + .module("x-pack-watcher") + .module("x-pack-ilm") + .setting("xpack.security.enabled", "false") + .setting("xpack.license.self_generated.type", "trial") + .setting("logger.org.elasticsearch.xpack.watcher", "DEBUG"); + } + + protected AbstractWatcherThirdPartyYamlTestSuiteIT(@Name("yaml") ClientYamlTestCandidate testCandidate) { + super(testCandidate); + } + + protected abstract ElasticsearchCluster getCluster(); + + @Override + protected String getTestRestCluster() { + return getCluster().getHttpAddresses(); + } + + @Before + public void startWatcher() throws Exception { + final List watcherTemplates = List.of(WatcherIndexTemplateRegistryField.TEMPLATE_NAMES); + assertBusy(() -> { + try { + getAdminExecutionContext().callApi("watcher.start", NO_ERROR_TRACE, List.of(), Map.of()); + + for (String template : watcherTemplates) { + ClientYamlTestResponse templateExistsResponse = getAdminExecutionContext().callApi( + "indices.exists_index_template", + Map.of("name", template, "error_trace", "false"), + List.of(), + Map.of() + ); + assertThat(templateExistsResponse.getStatusCode(), is(200)); + } + + ClientYamlTestResponse response = getAdminExecutionContext().callApi("watcher.stats", NO_ERROR_TRACE, List.of(), Map.of()); + String state = 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("watcher.stop", NO_ERROR_TRACE, List.of(), Map.of()); + ClientYamlTestResponse response = getAdminExecutionContext().callApi("watcher.stats", NO_ERROR_TRACE, List.of(), Map.of()); + String state = response.evaluate("stats.0.watcher_state"); + assertThat(state, is("stopped")); + } catch (IOException e) { + throw new AssertionError(e); + } + }, 60, TimeUnit.SECONDS); + } +}