Skip to content

Commit 5db2496

Browse files
committed
add unit test for ExpiredResultsRemoverTests
1 parent 8a28cb0 commit 5db2496

File tree

5 files changed

+78
-45
lines changed

5 files changed

+78
-45
lines changed

x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/job/retention/WritableIndexExpander.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@
1818
import java.util.Objects;
1919
import java.util.stream.Collectors;
2020

21+
/**
22+
* This class is used to expand index patterns and filter out read-only indices.
23+
* It is used in the context of machine learning jobs retention to ensure that only writable indices are considered.
24+
*/
2125
public class WritableIndexExpander {
2226

2327
private final ClusterService clusterService;

x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/job/retention/ExpiredAnnotationsRemoverTests.java

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -212,16 +212,7 @@ private ExpiredAnnotationsRemover createExpiredAnnotationsRemover(Iterator<Job>
212212
return null;
213213
}).when(executor).execute(any());
214214

215-
WritableIndexExpander writableIndexExpander = mock(WritableIndexExpander.class);
216-
if (annotationIndexWritable) {
217-
when(writableIndexExpander.getWritableIndices(AnnotationIndex.READ_ALIAS_NAME)).thenReturn(
218-
new ArrayList<>(Collections.singletonList(AnnotationIndex.READ_ALIAS_NAME))
219-
);
220-
} else {
221-
when(writableIndexExpander.getWritableIndices(AnnotationIndex.READ_ALIAS_NAME)).thenReturn(
222-
new ArrayList<>(Collections.emptyList())
223-
);
224-
}
215+
WritableIndexExpander writableIndexExpander = MockWritableIndexExpander.create(annotationIndexWritable);
225216
return new ExpiredAnnotationsRemover(
226217
originSettingClient,
227218
jobIterator,

x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/job/retention/ExpiredModelSnapshotsRemoverTests.java

Lines changed: 1 addition & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,12 @@
3535
import org.elasticsearch.xpack.ml.test.MockOriginSettingClient;
3636
import org.elasticsearch.xpack.ml.test.SearchHitBuilder;
3737
import org.junit.Before;
38-
import org.mockito.ArgumentMatchers;
3938
import org.mockito.invocation.InvocationOnMock;
4039
import org.mockito.stubbing.Answer;
4140

4241
import java.io.IOException;
4342
import java.util.ArrayList;
4443
import java.util.Arrays;
45-
import java.util.Collection;
4644
import java.util.Collections;
4745
import java.util.Date;
4846
import java.util.HashMap;
@@ -60,7 +58,6 @@
6058
import static org.mockito.ArgumentMatchers.any;
6159
import static org.mockito.ArgumentMatchers.anyBoolean;
6260
import static org.mockito.ArgumentMatchers.anyInt;
63-
import static org.mockito.ArgumentMatchers.anyString;
6461
import static org.mockito.ArgumentMatchers.eq;
6562
import static org.mockito.ArgumentMatchers.same;
6663
import static org.mockito.Mockito.doAnswer;
@@ -330,7 +327,7 @@ private ExpiredModelSnapshotsRemover createExpiredModelSnapshotsRemover(Iterator
330327
return null;
331328
}).when(executor).execute(any());
332329

333-
WritableIndexExpander writableIndexExpander = mockWritableIndexExpander(isStateIndexWritable);
330+
WritableIndexExpander writableIndexExpander = MockWritableIndexExpander.create(isStateIndexWritable);
334331

335332
return new ExpiredModelSnapshotsRemover(
336333
originSettingClient,
@@ -343,30 +340,6 @@ private ExpiredModelSnapshotsRemover createExpiredModelSnapshotsRemover(Iterator
343340
);
344341
}
345342

346-
private static WritableIndexExpander mockWritableIndexExpander(boolean stateIndexWritable) {
347-
WritableIndexExpander writableIndexExpander = mock(WritableIndexExpander.class);
348-
if (stateIndexWritable) {
349-
mockWhenIndicesAreWritable(writableIndexExpander);
350-
} else {
351-
mockWhenIndicesAreNotWritable(writableIndexExpander);
352-
}
353-
return writableIndexExpander;
354-
}
355-
356-
private static void mockWhenIndicesAreNotWritable(WritableIndexExpander writableIndexExpander) {
357-
when(writableIndexExpander.getWritableIndices(anyString()))
358-
.thenReturn(new ArrayList<>());
359-
when(writableIndexExpander.getWritableIndices(ArgumentMatchers.<Collection<String>>any()))
360-
.thenReturn(new ArrayList<>());
361-
}
362-
363-
private static void mockWhenIndicesAreWritable(WritableIndexExpander writableIndexExpander) {
364-
when(writableIndexExpander.getWritableIndices(anyString()))
365-
.thenAnswer(invocation -> List.of(invocation.getArgument(0)));
366-
when(writableIndexExpander.getWritableIndices(ArgumentMatchers.<Collection<String>>any()))
367-
.thenAnswer(invocation -> new ArrayList<>(invocation.getArgument(0)));
368-
}
369-
370343
private static ModelSnapshot createModelSnapshot(String jobId, String snapshotId, Date date) {
371344
return new ModelSnapshot.Builder(jobId).setSnapshotId(snapshotId).setTimestamp(date).build();
372345
}

x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/job/retention/ExpiredResultsRemoverTests.java

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,9 @@
1111
import org.elasticsearch.action.search.TransportSearchAction;
1212
import org.elasticsearch.client.internal.Client;
1313
import org.elasticsearch.client.internal.OriginSettingClient;
14-
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
15-
import org.elasticsearch.cluster.service.ClusterService;
1614
import org.elasticsearch.index.reindex.BulkByScrollResponse;
1715
import org.elasticsearch.index.reindex.DeleteByQueryAction;
1816
import org.elasticsearch.index.reindex.DeleteByQueryRequest;
19-
import org.elasticsearch.indices.TestIndexNameExpressionResolver;
2017
import org.elasticsearch.tasks.TaskId;
2118
import org.elasticsearch.test.ESTestCase;
2219
import org.elasticsearch.threadpool.ThreadPool;
@@ -54,8 +51,6 @@ public class ExpiredResultsRemoverTests extends ESTestCase {
5451
private OriginSettingClient originSettingClient;
5552
private List<DeleteByQueryRequest> capturedDeleteByQueryRequests;
5653
private ActionListener<Boolean> listener;
57-
private ClusterService clusterService;
58-
private IndexNameExpressionResolver indexNameExpressionResolver = TestIndexNameExpressionResolver.newInstance();
5954

6055
@Before
6156
@SuppressWarnings("unchecked")
@@ -65,7 +60,6 @@ public void setUpTests() {
6560
client = mock(Client.class);
6661
originSettingClient = MockOriginSettingClient.mockOriginSettingClient(client, ClientHelper.ML_ORIGIN);
6762
listener = mock(ActionListener.class);
68-
clusterService = mock(ClusterService.class);
6963
when(listener.delegateFailureAndWrap(any())).thenCallRealMethod();
7064
}
7165

@@ -141,6 +135,22 @@ public void testRemove_GivenClientRequestsFailed() {
141135
verify(listener).onFailure(any());
142136
}
143137

138+
public void testRemove_GivenIndexNotWritable_ShouldHandleGracefully() {
139+
givenBucket(new Bucket("id_not_important", new Date(), 60));
140+
141+
// Prepare one job with a retention policy
142+
List<Job> jobs = Arrays.asList(
143+
JobTests.buildJobBuilder("results-1").setResultsRetentionDays(10L).build(),
144+
JobTests.buildJobBuilder("results-1").setResultsRetentionDays(20L).build()
145+
);
146+
147+
createExpiredResultsRemover(jobs.iterator(), false).remove(1.0f, listener, () -> false);
148+
149+
// Assert: success callback invoked, no DBQ requests
150+
verify(listener).onResponse(true);
151+
assertThat(capturedDeleteByQueryRequests.size(), equalTo(0));
152+
}
153+
144154
@SuppressWarnings("unchecked")
145155
public void testCalcCutoffEpochMs() {
146156
String jobId = "calc-cutoff";
@@ -191,7 +201,13 @@ private void givenBucket(Bucket bucket) {
191201
}).when(client).execute(eq(TransportSearchAction.TYPE), any(), any());
192202
}
193203

204+
205+
194206
private ExpiredResultsRemover createExpiredResultsRemover(Iterator<Job> jobIterator) {
207+
return createExpiredResultsRemover(jobIterator, true);
208+
}
209+
210+
private ExpiredResultsRemover createExpiredResultsRemover(Iterator<Job> jobIterator, boolean isResultsIndexWritable) {
195211
ThreadPool threadPool = mock(ThreadPool.class);
196212
ExecutorService executor = mock(ExecutorService.class);
197213

@@ -203,11 +219,13 @@ private ExpiredResultsRemover createExpiredResultsRemover(Iterator<Job> jobItera
203219
return null;
204220
}).when(executor).execute(any());
205221

222+
WritableIndexExpander writableIndexExpander = MockWritableIndexExpander.create(isResultsIndexWritable);
223+
206224
return new ExpiredResultsRemover(
207225
originSettingClient,
208226
jobIterator,
209227
new TaskId("test", 0L),
210-
new WritableIndexExpander(clusterService, indexNameExpressionResolver),
228+
writableIndexExpander,
211229
mock(AnomalyDetectionAuditor.class),
212230
threadPool
213231
);
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License
4+
* 2.0; you may not use this file except in compliance with the Elastic License
5+
* 2.0.
6+
*/
7+
8+
package org.elasticsearch.xpack.ml.job.retention;
9+
10+
import org.mockito.ArgumentMatchers;
11+
12+
import java.util.ArrayList;
13+
import java.util.Collection;
14+
import java.util.List;
15+
16+
import static org.mockito.ArgumentMatchers.anyString;
17+
import static org.mockito.Mockito.mock;
18+
import static org.mockito.Mockito.when;
19+
20+
public class MockWritableIndexExpander {
21+
public static WritableIndexExpander create(boolean stateIndexWritable) {
22+
WritableIndexExpander writableIndexExpander = mock(WritableIndexExpander.class);
23+
if (stateIndexWritable) {
24+
mockWhenIndicesAreWritable(writableIndexExpander);
25+
} else {
26+
mockWhenIndicesAreNotWritable(writableIndexExpander);
27+
}
28+
return writableIndexExpander;
29+
}
30+
31+
private static void mockWhenIndicesAreNotWritable(WritableIndexExpander writableIndexExpander) {
32+
when(writableIndexExpander.getWritableIndices(anyString()))
33+
.thenReturn(new ArrayList<>());
34+
when(writableIndexExpander.getWritableIndices(ArgumentMatchers.<Collection<String>>any()))
35+
.thenReturn(new ArrayList<>());
36+
}
37+
38+
private static void mockWhenIndicesAreWritable(WritableIndexExpander writableIndexExpander) {
39+
when(writableIndexExpander.getWritableIndices(anyString())).thenAnswer(invocation -> {
40+
String input = invocation.getArgument(0);
41+
return new ArrayList<>(List.of(input));
42+
});
43+
when(writableIndexExpander.getWritableIndices(ArgumentMatchers.<Collection<String>>any())).thenAnswer(
44+
invocation -> new ArrayList<>(invocation.getArgument(0))
45+
);
46+
}
47+
}

0 commit comments

Comments
 (0)