Skip to content

Commit 28a0df2

Browse files
HLRC: Clear ML data after client tests (#33023)
This commit duplicates the `MlRestTestStateCleaner` to make sure all ML data is removed after each test. After implementing the job and datafeed APIs in the HLRC, we shall replace this implementation with one using the HLRC itself. Closes #32993
1 parent 28d12b0 commit 28a0df2

File tree

3 files changed

+124
-2
lines changed

3 files changed

+124
-2
lines changed

client/rest-high-level/src/test/java/org/elasticsearch/client/MachineLearningIT.java

+7-2
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
package org.elasticsearch.client;
2020

2121
import com.carrotsearch.randomizedtesting.generators.CodepointSetGenerator;
22-
import org.apache.lucene.util.LuceneTestCase.AwaitsFix;
2322
import org.elasticsearch.common.unit.TimeValue;
2423
import org.elasticsearch.protocol.xpack.ml.CloseJobRequest;
2524
import org.elasticsearch.protocol.xpack.ml.CloseJobResponse;
@@ -33,15 +32,21 @@
3332
import org.elasticsearch.protocol.xpack.ml.job.config.DataDescription;
3433
import org.elasticsearch.protocol.xpack.ml.job.config.Detector;
3534
import org.elasticsearch.protocol.xpack.ml.job.config.Job;
35+
import org.junit.After;
3636

37+
import java.io.IOException;
3738
import java.util.Arrays;
3839
import java.util.concurrent.TimeUnit;
3940

4041
import static org.hamcrest.Matchers.is;
4142

42-
@AwaitsFix(bugUrl = "https://github.com/elastic/elasticsearch/issues/32993")
4343
public class MachineLearningIT extends ESRestHighLevelClientTestCase {
4444

45+
@After
46+
public void cleanUp() throws IOException {
47+
new MlRestTestStateCleaner(logger, client()).clearMlMetadata();
48+
}
49+
4550
public void testPutJob() throws Exception {
4651
String jobId = randomValidJobId();
4752
Job job = buildJob(jobId);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
/*
2+
* Licensed to Elasticsearch under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.elasticsearch.client;
20+
21+
import org.apache.logging.log4j.Logger;
22+
import org.elasticsearch.common.xcontent.support.XContentMapValues;
23+
import org.elasticsearch.test.rest.ESRestTestCase;
24+
25+
import java.io.IOException;
26+
import java.util.List;
27+
import java.util.Map;
28+
29+
/**
30+
* This is temporarily duplicated from the server side.
31+
* @TODO Replace with an implementation using the HLRC once
32+
* the APIs for managing datafeeds are implemented.
33+
*/
34+
public class MlRestTestStateCleaner {
35+
36+
private final Logger logger;
37+
private final RestClient adminClient;
38+
39+
public MlRestTestStateCleaner(Logger logger, RestClient adminClient) {
40+
this.logger = logger;
41+
this.adminClient = adminClient;
42+
}
43+
44+
public void clearMlMetadata() throws IOException {
45+
deleteAllDatafeeds();
46+
deleteAllJobs();
47+
// indices will be deleted by the ESRestTestCase class
48+
}
49+
50+
@SuppressWarnings("unchecked")
51+
private void deleteAllDatafeeds() throws IOException {
52+
final Request datafeedsRequest = new Request("GET", "/_xpack/ml/datafeeds");
53+
datafeedsRequest.addParameter("filter_path", "datafeeds");
54+
final Response datafeedsResponse = adminClient.performRequest(datafeedsRequest);
55+
final List<Map<String, Object>> datafeeds =
56+
(List<Map<String, Object>>) XContentMapValues.extractValue("datafeeds", ESRestTestCase.entityAsMap(datafeedsResponse));
57+
if (datafeeds == null) {
58+
return;
59+
}
60+
61+
try {
62+
adminClient.performRequest(new Request("POST", "/_xpack/ml/datafeeds/_all/_stop"));
63+
} catch (Exception e1) {
64+
logger.warn("failed to stop all datafeeds. Forcing stop", e1);
65+
try {
66+
adminClient.performRequest(new Request("POST", "/_xpack/ml/datafeeds/_all/_stop?force=true"));
67+
} catch (Exception e2) {
68+
logger.warn("Force-closing all data feeds failed", e2);
69+
}
70+
throw new RuntimeException(
71+
"Had to resort to force-stopping datafeeds, something went wrong?", e1);
72+
}
73+
74+
for (Map<String, Object> datafeed : datafeeds) {
75+
String datafeedId = (String) datafeed.get("datafeed_id");
76+
adminClient.performRequest(new Request("DELETE", "/_xpack/ml/datafeeds/" + datafeedId));
77+
}
78+
}
79+
80+
private void deleteAllJobs() throws IOException {
81+
final Request jobsRequest = new Request("GET", "/_xpack/ml/anomaly_detectors");
82+
jobsRequest.addParameter("filter_path", "jobs");
83+
final Response response = adminClient.performRequest(jobsRequest);
84+
@SuppressWarnings("unchecked")
85+
final List<Map<String, Object>> jobConfigs =
86+
(List<Map<String, Object>>) XContentMapValues.extractValue("jobs", ESRestTestCase.entityAsMap(response));
87+
if (jobConfigs == null) {
88+
return;
89+
}
90+
91+
try {
92+
adminClient.performRequest(new Request("POST", "/_xpack/ml/anomaly_detectors/_all/_close"));
93+
} catch (Exception e1) {
94+
logger.warn("failed to close all jobs. Forcing closed", e1);
95+
try {
96+
adminClient.performRequest(new Request("POST", "/_xpack/ml/anomaly_detectors/_all/_close?force=true"));
97+
} catch (Exception e2) {
98+
logger.warn("Force-closing all jobs failed", e2);
99+
}
100+
throw new RuntimeException("Had to resort to force-closing jobs, something went wrong?",
101+
e1);
102+
}
103+
104+
for (Map<String, Object> jobConfig : jobConfigs) {
105+
String jobId = (String) jobConfig.get("job_id");
106+
adminClient.performRequest(new Request("DELETE", "/_xpack/ml/anomaly_detectors/" + jobId));
107+
}
108+
}
109+
}

client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/MlClientDocumentationIT.java

+8
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import org.elasticsearch.action.LatchedActionListener;
2323
import org.elasticsearch.client.ESRestHighLevelClientTestCase;
2424
import org.elasticsearch.client.MachineLearningIT;
25+
import org.elasticsearch.client.MlRestTestStateCleaner;
2526
import org.elasticsearch.client.RequestOptions;
2627
import org.elasticsearch.client.RestHighLevelClient;
2728
import org.elasticsearch.common.unit.TimeValue;
@@ -37,7 +38,9 @@
3738
import org.elasticsearch.protocol.xpack.ml.job.config.DataDescription;
3839
import org.elasticsearch.protocol.xpack.ml.job.config.Detector;
3940
import org.elasticsearch.protocol.xpack.ml.job.config.Job;
41+
import org.junit.After;
4042

43+
import java.io.IOException;
4144
import java.util.Collections;
4245
import java.util.Date;
4346
import java.util.List;
@@ -48,6 +51,11 @@
4851

4952
public class MlClientDocumentationIT extends ESRestHighLevelClientTestCase {
5053

54+
@After
55+
public void cleanUp() throws IOException {
56+
new MlRestTestStateCleaner(logger, client()).clearMlMetadata();
57+
}
58+
5159
public void testCreateJob() throws Exception {
5260
RestHighLevelClient client = highLevelClient();
5361

0 commit comments

Comments
 (0)