Browse Source

Ensure backing indices will not be empty (#106073) (#106104)

In some data stream tests we are using a helper method to create the
backing indices. This helper method could return an empty list. 

A data stream is not allowed to have an empty list of backing indices,
in many test a write index was added to the list, this ensured that the
list was not empty, while in other tests that was not the case which
made these tests flaky.

In this PR we evaluate all the usages of
`org.elasticsearch.cluster.metadata.DataStreamTestHelper#randomIndexInstances()`
and we introduce
`org.elasticsearch.cluster.metadata.DataStreamTestHelper#randomNonEmptyIndexInstances`
to use in its place, in the cases we need an non-empty list.

Fixes: #106073
Mary Gouseti 1 year ago
parent
commit
49e93335aa

+ 12 - 19
server/src/test/java/org/elasticsearch/cluster/metadata/DataStreamTests.java

@@ -51,6 +51,7 @@ import java.util.function.Predicate;
 import static org.elasticsearch.cluster.metadata.DataStream.getDefaultBackingIndexName;
 import static org.elasticsearch.cluster.metadata.DataStream.getDefaultBackingIndexName;
 import static org.elasticsearch.cluster.metadata.DataStreamTestHelper.newInstance;
 import static org.elasticsearch.cluster.metadata.DataStreamTestHelper.newInstance;
 import static org.elasticsearch.cluster.metadata.DataStreamTestHelper.randomIndexInstances;
 import static org.elasticsearch.cluster.metadata.DataStreamTestHelper.randomIndexInstances;
+import static org.elasticsearch.cluster.metadata.DataStreamTestHelper.randomNonEmptyIndexInstances;
 import static org.elasticsearch.index.IndexSettings.LIFECYCLE_ORIGINATION_DATE;
 import static org.elasticsearch.index.IndexSettings.LIFECYCLE_ORIGINATION_DATE;
 import static org.hamcrest.Matchers.containsString;
 import static org.hamcrest.Matchers.containsString;
 import static org.hamcrest.Matchers.equalTo;
 import static org.hamcrest.Matchers.equalTo;
@@ -97,7 +98,7 @@ public class DataStreamTests extends AbstractXContentSerializingTestCase<DataStr
         var autoShardingEvent = instance.getAutoShardingEvent();
         var autoShardingEvent = instance.getAutoShardingEvent();
         switch (between(0, 11)) {
         switch (between(0, 11)) {
             case 0 -> name = randomAlphaOfLength(10);
             case 0 -> name = randomAlphaOfLength(10);
-            case 1 -> indices = randomValueOtherThan(List.of(), DataStreamTestHelper::randomIndexInstances);
+            case 1 -> indices = randomNonEmptyIndexInstances();
             case 2 -> generation = instance.getGeneration() + randomIntBetween(1, 10);
             case 2 -> generation = instance.getGeneration() + randomIntBetween(1, 10);
             case 3 -> metadata = randomBoolean() && metadata != null ? null : Map.of("key", randomAlphaOfLength(10));
             case 3 -> metadata = randomBoolean() && metadata != null ? null : Map.of("key", randomAlphaOfLength(10));
             case 4 -> {
             case 4 -> {
@@ -125,12 +126,8 @@ public class DataStreamTests extends AbstractXContentSerializingTestCase<DataStr
                 ? null
                 ? null
                 : DataStreamLifecycle.newBuilder().dataRetention(randomMillisUpToYear9999()).build();
                 : DataStreamLifecycle.newBuilder().dataRetention(randomMillisUpToYear9999()).build();
             case 10 -> {
             case 10 -> {
-                failureIndices = randomValueOtherThan(List.of(), DataStreamTestHelper::randomIndexInstances);
-                if (failureIndices.isEmpty()) {
-                    failureStore = false;
-                } else {
-                    failureStore = true;
-                }
+                failureIndices = randomValueOtherThan(failureIndices, DataStreamTestHelper::randomIndexInstances);
+                failureStore = failureIndices.isEmpty() == false;
             }
             }
             case 11 -> {
             case 11 -> {
                 autoShardingEvent = randomBoolean() && autoShardingEvent != null
                 autoShardingEvent = randomBoolean() && autoShardingEvent != null
@@ -631,11 +628,7 @@ public class DataStreamTests extends AbstractXContentSerializingTestCase<DataStr
 
 
     public void testSnapshotWithAllBackingIndicesRemoved() {
     public void testSnapshotWithAllBackingIndicesRemoved() {
         var preSnapshotDataStream = DataStreamTestHelper.randomInstance();
         var preSnapshotDataStream = DataStreamTestHelper.randomInstance();
-        var indicesToAdd = new ArrayList<Index>();
-        while (indicesToAdd.isEmpty()) {
-            // ensure at least one index
-            indicesToAdd.addAll(randomIndexInstances());
-        }
+        var indicesToAdd = randomNonEmptyIndexInstances();
 
 
         var postSnapshotDataStream = new DataStream(
         var postSnapshotDataStream = new DataStream(
             preSnapshotDataStream.getName(),
             preSnapshotDataStream.getName(),
@@ -1652,7 +1645,7 @@ public class DataStreamTests extends AbstractXContentSerializingTestCase<DataStr
         boolean failureStore = randomBoolean();
         boolean failureStore = randomBoolean();
         List<Index> failureIndices = List.of();
         List<Index> failureIndices = List.of();
         if (failureStore) {
         if (failureStore) {
-            failureIndices = randomIndexInstances();
+            failureIndices = randomNonEmptyIndexInstances();
         }
         }
 
 
         DataStreamLifecycle lifecycle = DataStreamLifecycle.newBuilder().dataRetention(randomMillisUpToYear9999()).build();
         DataStreamLifecycle lifecycle = DataStreamLifecycle.newBuilder().dataRetention(randomMillisUpToYear9999()).build();
@@ -1786,7 +1779,7 @@ public class DataStreamTests extends AbstractXContentSerializingTestCase<DataStr
         boolean system = hidden && randomBoolean();
         boolean system = hidden && randomBoolean();
         DataStream noFailureStoreDataStream = new DataStream(
         DataStream noFailureStoreDataStream = new DataStream(
             randomAlphaOfLength(10),
             randomAlphaOfLength(10),
-            randomIndexInstances(),
+            randomNonEmptyIndexInstances(),
             randomNonNegativeInt(),
             randomNonNegativeInt(),
             null,
             null,
             hidden,
             hidden,
@@ -1805,7 +1798,7 @@ public class DataStreamTests extends AbstractXContentSerializingTestCase<DataStr
 
 
         DataStream failureStoreDataStreamWithEmptyFailureIndices = new DataStream(
         DataStream failureStoreDataStreamWithEmptyFailureIndices = new DataStream(
             randomAlphaOfLength(10),
             randomAlphaOfLength(10),
-            randomIndexInstances(),
+            randomNonEmptyIndexInstances(),
             randomNonNegativeInt(),
             randomNonNegativeInt(),
             null,
             null,
             hidden,
             hidden,
@@ -1831,7 +1824,7 @@ public class DataStreamTests extends AbstractXContentSerializingTestCase<DataStr
         failureIndices.add(writeFailureIndex);
         failureIndices.add(writeFailureIndex);
         DataStream failureStoreDataStream = new DataStream(
         DataStream failureStoreDataStream = new DataStream(
             dataStreamName,
             dataStreamName,
-            randomIndexInstances(),
+            randomNonEmptyIndexInstances(),
             randomNonNegativeInt(),
             randomNonNegativeInt(),
             null,
             null,
             hidden,
             hidden,
@@ -1852,7 +1845,7 @@ public class DataStreamTests extends AbstractXContentSerializingTestCase<DataStr
     public void testIsFailureIndex() {
     public void testIsFailureIndex() {
         boolean hidden = randomBoolean();
         boolean hidden = randomBoolean();
         boolean system = hidden && randomBoolean();
         boolean system = hidden && randomBoolean();
-        List<Index> backingIndices = randomIndexInstances();
+        List<Index> backingIndices = randomNonEmptyIndexInstances();
         DataStream noFailureStoreDataStream = new DataStream(
         DataStream noFailureStoreDataStream = new DataStream(
             randomAlphaOfLength(10),
             randomAlphaOfLength(10),
             backingIndices,
             backingIndices,
@@ -1875,7 +1868,7 @@ public class DataStreamTests extends AbstractXContentSerializingTestCase<DataStr
             is(false)
             is(false)
         );
         );
 
 
-        backingIndices = randomIndexInstances();
+        backingIndices = randomNonEmptyIndexInstances();
         DataStream failureStoreDataStreamWithEmptyFailureIndices = new DataStream(
         DataStream failureStoreDataStreamWithEmptyFailureIndices = new DataStream(
             randomAlphaOfLength(10),
             randomAlphaOfLength(10),
             backingIndices,
             backingIndices,
@@ -1900,7 +1893,7 @@ public class DataStreamTests extends AbstractXContentSerializingTestCase<DataStr
             is(false)
             is(false)
         );
         );
 
 
-        backingIndices = randomIndexInstances();
+        backingIndices = randomNonEmptyIndexInstances();
         List<Index> failureIndices = randomIndexInstances();
         List<Index> failureIndices = randomIndexInstances();
         String dataStreamName = randomAlphaOfLength(10);
         String dataStreamName = randomAlphaOfLength(10);
         Index writeFailureIndex = new Index(
         Index writeFailureIndex = new Index(

+ 14 - 2
test/framework/src/main/java/org/elasticsearch/cluster/metadata/DataStreamTestHelper.java

@@ -263,8 +263,20 @@ public final class DataStreamTestHelper {
             + "    }";
             + "    }";
     }
     }
 
 
+    /**
+     * @return a list of random indices. NOTE: the list can be empty, if you do not want an empty list use
+     * {@link DataStreamTestHelper#randomNonEmptyIndexInstances()}
+     */
     public static List<Index> randomIndexInstances() {
     public static List<Index> randomIndexInstances() {
-        int numIndices = ESTestCase.randomIntBetween(0, 128);
+        return randomIndexInstances(0, 128);
+    }
+
+    public static List<Index> randomNonEmptyIndexInstances() {
+        return randomIndexInstances(1, 128);
+    }
+
+    public static List<Index> randomIndexInstances(int min, int max) {
+        int numIndices = ESTestCase.randomIntBetween(min, max);
         List<Index> indices = new ArrayList<>(numIndices);
         List<Index> indices = new ArrayList<>(numIndices);
         for (int i = 0; i < numIndices; i++) {
         for (int i = 0; i < numIndices; i++) {
             indices.add(new Index(randomAlphaOfLength(10).toLowerCase(Locale.ROOT), UUIDs.randomBase64UUID(LuceneTestCase.random())));
             indices.add(new Index(randomAlphaOfLength(10).toLowerCase(Locale.ROOT), UUIDs.randomBase64UUID(LuceneTestCase.random())));
@@ -296,7 +308,7 @@ public final class DataStreamTestHelper {
         List<Index> failureIndices = List.of();
         List<Index> failureIndices = List.of();
         boolean failureStore = randomBoolean();
         boolean failureStore = randomBoolean();
         if (failureStore) {
         if (failureStore) {
-            failureIndices = randomIndexInstances();
+            failureIndices = randomNonEmptyIndexInstances();
         }
         }
 
 
         return new DataStream(
         return new DataStream(