From 7aac2c416bfc19323346e15a00aa75495e8a4afa Mon Sep 17 00:00:00 2001 From: Valeriy Khakhutskyy <1292899+valeriy42@users.noreply.github.com> Date: Thu, 13 Nov 2025 21:50:59 +0100 Subject: [PATCH 1/4] Remove muted test for ClassificationIT and enhance audit message assertion in MlNativeDataFrameAnalyticsIntegTestCase to ensure all expected prefixes are found in fetched messages. --- muted-tests.yml | 3 -- ...NativeDataFrameAnalyticsIntegTestCase.java | 42 +++++++++++++++---- 2 files changed, 33 insertions(+), 12 deletions(-) diff --git a/muted-tests.yml b/muted-tests.yml index 6c8763c95bcce..98a84207e9ae6 100644 --- a/muted-tests.yml +++ b/muted-tests.yml @@ -203,9 +203,6 @@ tests: - class: org.elasticsearch.entitlement.runtime.policy.FileAccessTreeTests method: testWindowsAbsolutPathAccess issue: https://github.com/elastic/elasticsearch/issues/129168 -- class: org.elasticsearch.xpack.ml.integration.ClassificationIT - method: testWithDatastreams - issue: https://github.com/elastic/elasticsearch/issues/129457 - class: org.elasticsearch.xpack.profiling.action.GetStatusActionIT method: testWaitsUntilResourcesAreCreated issue: https://github.com/elastic/elasticsearch/issues/129486 diff --git a/x-pack/plugin/ml/qa/native-multi-node-tests/src/javaRestTest/java/org/elasticsearch/xpack/ml/integration/MlNativeDataFrameAnalyticsIntegTestCase.java b/x-pack/plugin/ml/qa/native-multi-node-tests/src/javaRestTest/java/org/elasticsearch/xpack/ml/integration/MlNativeDataFrameAnalyticsIntegTestCase.java index d4a577393b7fd..4602a6d3f5e0e 100644 --- a/x-pack/plugin/ml/qa/native-multi-node-tests/src/javaRestTest/java/org/elasticsearch/xpack/ml/integration/MlNativeDataFrameAnalyticsIntegTestCase.java +++ b/x-pack/plugin/ml/qa/native-multi-node-tests/src/javaRestTest/java/org/elasticsearch/xpack/ml/integration/MlNativeDataFrameAnalyticsIntegTestCase.java @@ -56,7 +56,6 @@ import org.elasticsearch.xpack.core.ml.utils.QueryProvider; import org.elasticsearch.xpack.ml.dataframe.StoredProgress; import org.hamcrest.Matcher; -import org.hamcrest.Matchers; import java.io.IOException; import java.io.UncheckedIOException; @@ -78,7 +77,6 @@ import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.greaterThan; import static org.hamcrest.Matchers.greaterThanOrEqualTo; -import static org.hamcrest.Matchers.hasItems; import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.nullValue; @@ -359,9 +357,9 @@ protected TrainedModelDefinition getModelDefinition(String modelId) throws IOExc /** * Asserts whether the audit messages fetched from index match provided prefixes. * More specifically, in order to pass: - * 1. the number of fetched messages must equal the number of provided prefixes + * 1. ALL expected message prefixes must be found in the fetched messages * AND - * 2. each fetched message must start with the corresponding prefix + * 2. each fetched message that matches must start with the corresponding prefix */ protected static void assertThatAuditMessagesMatch(String configId, String... expectedAuditMessagePrefixes) throws Exception { // Make sure we wrote to the audit @@ -369,13 +367,39 @@ protected static void assertThatAuditMessagesMatch(String configId, String... ex // finished the job (as this is a very short analytics job), all without the audit being fully written. awaitIndexExists(NotificationsIndex.NOTIFICATIONS_INDEX); - @SuppressWarnings("unchecked") - Matcher[] itemMatchers = Arrays.stream(expectedAuditMessagePrefixes).map(Matchers::startsWith).toArray(Matcher[]::new); assertBusy(() -> { + // Refresh the notifications index to ensure latest writes are visible + RefreshRequest refreshRequest = new RefreshRequest(NotificationsIndex.NOTIFICATIONS_INDEX); + BroadcastResponse refreshResponse = client().execute(RefreshAction.INSTANCE, refreshRequest).actionGet(); + assertThat(refreshResponse.getStatus().getStatus(), anyOf(equalTo(200), equalTo(201))); + List allAuditMessages = fetchAllAuditMessages(configId); - assertThat(allAuditMessages, hasItems(itemMatchers)); - // TODO: Consider restoring this assertion when we are sure all the audit messages are available at this point. - // assertThat("Messages: " + allAuditMessages, allAuditMessages, hasSize(expectedAuditMessagePrefixes.length)); + + // Track which expected prefixes have been found + Set foundPrefixes = new HashSet<>(); + for (String message : allAuditMessages) { + for (String expectedPrefix : expectedAuditMessagePrefixes) { + if (message.startsWith(expectedPrefix)) { + foundPrefixes.add(expectedPrefix); + break; // Each message can only match one prefix + } + } + } + + // Ensure all expected prefixes were found + Set missingPrefixes = new HashSet<>(Arrays.asList(expectedAuditMessagePrefixes)); + missingPrefixes.removeAll(foundPrefixes); + + if (missingPrefixes.isEmpty() == false) { + fail( + "Expected audit messages not found for config [" + + configId + + "]. Missing prefixes: " + + missingPrefixes + + ". Found messages: " + + allAuditMessages + ); + } }); } From 93bf8ae60f1ebbeebc53be3f2baa8a247d7504f6 Mon Sep 17 00:00:00 2001 From: Valeriy Khakhutskyy <1292899+valeriy42@users.noreply.github.com> Date: Fri, 14 Nov 2025 10:32:46 +0100 Subject: [PATCH 2/4] Refactor audit message assertion in MlNativeDataFrameAnalyticsIntegTestCase to utilize streams for improved readability and efficiency in checking expected prefixes against fetched messages. --- ...NativeDataFrameAnalyticsIntegTestCase.java | 38 ++++++++----------- 1 file changed, 16 insertions(+), 22 deletions(-) diff --git a/x-pack/plugin/ml/qa/native-multi-node-tests/src/javaRestTest/java/org/elasticsearch/xpack/ml/integration/MlNativeDataFrameAnalyticsIntegTestCase.java b/x-pack/plugin/ml/qa/native-multi-node-tests/src/javaRestTest/java/org/elasticsearch/xpack/ml/integration/MlNativeDataFrameAnalyticsIntegTestCase.java index 4602a6d3f5e0e..9a3ed2aa231e2 100644 --- a/x-pack/plugin/ml/qa/native-multi-node-tests/src/javaRestTest/java/org/elasticsearch/xpack/ml/integration/MlNativeDataFrameAnalyticsIntegTestCase.java +++ b/x-pack/plugin/ml/qa/native-multi-node-tests/src/javaRestTest/java/org/elasticsearch/xpack/ml/integration/MlNativeDataFrameAnalyticsIntegTestCase.java @@ -60,7 +60,6 @@ import java.io.IOException; import java.io.UncheckedIOException; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashSet; @@ -69,6 +68,7 @@ import java.util.Optional; import java.util.Set; import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; import static org.elasticsearch.common.xcontent.support.XContentMapValues.extractValue; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertHitCount; @@ -367,6 +367,7 @@ protected static void assertThatAuditMessagesMatch(String configId, String... ex // finished the job (as this is a very short analytics job), all without the audit being fully written. awaitIndexExists(NotificationsIndex.NOTIFICATIONS_INDEX); + Set expectedPrefixes = Set.of(expectedAuditMessagePrefixes); assertBusy(() -> { // Refresh the notifications index to ensure latest writes are visible RefreshRequest refreshRequest = new RefreshRequest(NotificationsIndex.NOTIFICATIONS_INDEX); @@ -375,29 +376,22 @@ protected static void assertThatAuditMessagesMatch(String configId, String... ex List allAuditMessages = fetchAllAuditMessages(configId); - // Track which expected prefixes have been found - Set foundPrefixes = new HashSet<>(); - for (String message : allAuditMessages) { - for (String expectedPrefix : expectedAuditMessagePrefixes) { - if (message.startsWith(expectedPrefix)) { - foundPrefixes.add(expectedPrefix); - break; // Each message can only match one prefix - } - } - } + // Find which expected prefixes match any of the audit messages + Set foundPrefixes = expectedPrefixes.stream() + .filter(prefix -> allAuditMessages.stream().anyMatch(msg -> msg.startsWith(prefix))) + .collect(Collectors.toSet()); - // Ensure all expected prefixes were found - Set missingPrefixes = new HashSet<>(Arrays.asList(expectedAuditMessagePrefixes)); - missingPrefixes.removeAll(foundPrefixes); - - if (missingPrefixes.isEmpty() == false) { + // Only calculate missing prefixes if not all were found + if (foundPrefixes.size() != expectedPrefixes.size()) { + Set missingPrefixes = new HashSet<>(expectedPrefixes); + missingPrefixes.removeAll(foundPrefixes); fail( - "Expected audit messages not found for config [" - + configId - + "]. Missing prefixes: " - + missingPrefixes - + ". Found messages: " - + allAuditMessages + String.format( + "Expected audit messages not found for config [%s]. Missing prefixes: %s. Found messages: %s", + configId, + missingPrefixes, + allAuditMessages + ) ); } }); From 10f3687fd1120912227197d5e1334ffd961c08cf Mon Sep 17 00:00:00 2001 From: Valeriy Khakhutskyy <1292899+valeriy42@users.noreply.github.com> Date: Fri, 14 Nov 2025 11:04:00 +0100 Subject: [PATCH 3/4] Add refresh action imports in MlNativeDataFrameAnalyticsIntegTestCase to support index refresh operations during tests. --- .../integration/MlNativeDataFrameAnalyticsIntegTestCase.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/x-pack/plugin/ml/qa/native-multi-node-tests/src/javaRestTest/java/org/elasticsearch/xpack/ml/integration/MlNativeDataFrameAnalyticsIntegTestCase.java b/x-pack/plugin/ml/qa/native-multi-node-tests/src/javaRestTest/java/org/elasticsearch/xpack/ml/integration/MlNativeDataFrameAnalyticsIntegTestCase.java index 9a3ed2aa231e2..3fffd794b1321 100644 --- a/x-pack/plugin/ml/qa/native-multi-node-tests/src/javaRestTest/java/org/elasticsearch/xpack/ml/integration/MlNativeDataFrameAnalyticsIntegTestCase.java +++ b/x-pack/plugin/ml/qa/native-multi-node-tests/src/javaRestTest/java/org/elasticsearch/xpack/ml/integration/MlNativeDataFrameAnalyticsIntegTestCase.java @@ -9,6 +9,9 @@ import org.apache.lucene.util.SetOnce; import org.elasticsearch.action.admin.indices.get.GetIndexAction; import org.elasticsearch.action.admin.indices.get.GetIndexRequest; +import org.elasticsearch.action.admin.indices.refresh.RefreshAction; +import org.elasticsearch.action.admin.indices.refresh.RefreshRequest; +import org.elasticsearch.action.support.broadcast.BroadcastResponse; import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.common.Strings; import org.elasticsearch.common.settings.Settings; @@ -73,6 +76,7 @@ import static org.elasticsearch.common.xcontent.support.XContentMapValues.extractValue; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertHitCount; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertResponse; +import static org.hamcrest.Matchers.anyOf; import static org.hamcrest.Matchers.arrayWithSize; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.greaterThan; From 87b4bce358992c2f33a09c160f5d6a7c0daad28b Mon Sep 17 00:00:00 2001 From: Valeriy Khakhutskyy <1292899+valeriy42@users.noreply.github.com> Date: Fri, 14 Nov 2025 11:33:48 +0100 Subject: [PATCH 4/4] fix verification error. --- .../ml/integration/MlNativeDataFrameAnalyticsIntegTestCase.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/x-pack/plugin/ml/qa/native-multi-node-tests/src/javaRestTest/java/org/elasticsearch/xpack/ml/integration/MlNativeDataFrameAnalyticsIntegTestCase.java b/x-pack/plugin/ml/qa/native-multi-node-tests/src/javaRestTest/java/org/elasticsearch/xpack/ml/integration/MlNativeDataFrameAnalyticsIntegTestCase.java index 3fffd794b1321..9088f9e91f456 100644 --- a/x-pack/plugin/ml/qa/native-multi-node-tests/src/javaRestTest/java/org/elasticsearch/xpack/ml/integration/MlNativeDataFrameAnalyticsIntegTestCase.java +++ b/x-pack/plugin/ml/qa/native-multi-node-tests/src/javaRestTest/java/org/elasticsearch/xpack/ml/integration/MlNativeDataFrameAnalyticsIntegTestCase.java @@ -67,6 +67,7 @@ import java.util.Collections; import java.util.HashSet; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Optional; import java.util.Set; @@ -391,6 +392,7 @@ protected static void assertThatAuditMessagesMatch(String configId, String... ex missingPrefixes.removeAll(foundPrefixes); fail( String.format( + Locale.ROOT, "Expected audit messages not found for config [%s]. Missing prefixes: %s. Found messages: %s", configId, missingPrefixes,