6060import org .opensearch .indices .replication .SegmentReplicationState ;
6161import org .opensearch .indices .replication .SegmentReplicationTarget ;
6262import org .opensearch .indices .replication .SegmentReplicationTargetService ;
63+ import org .opensearch .indices .replication .checkpoint .MergedSegmentPublisher ;
6364import org .opensearch .indices .replication .checkpoint .ReferencedSegmentsCheckpoint ;
6465import org .opensearch .indices .replication .checkpoint .ReplicationCheckpoint ;
6566import org .opensearch .indices .replication .checkpoint .SegmentReplicationCheckpointPublisher ;
@@ -158,7 +159,66 @@ public void testReplication() throws Exception {
158159 @ LockFeatureFlag (MERGED_SEGMENT_WARMER_EXPERIMENTAL_FLAG )
159160 public void testMergedSegmentReplication () throws Exception {
160161 // Test that the pre-copy merged segment logic does not block the merge process of the primary shard when there are 1 replica shard.
161- try (ReplicationGroup shards = createGroup (1 , getIndexSettings (), indexMapping , new NRTReplicationEngineFactory ());) {
162+ final RecoverySettings recoverySettings = new RecoverySettings (
163+ Settings .builder ().put (RecoverySettings .INDICES_MERGED_SEGMENT_REPLICATION_WARMER_ENABLED_SETTING .getKey (), true ).build (),
164+ new ClusterSettings (Settings .EMPTY , ClusterSettings .BUILT_IN_CLUSTER_SETTINGS )
165+ );
166+ try (
167+ ReplicationGroup shards = createGroup (
168+ 1 ,
169+ getIndexSettings (),
170+ indexMapping ,
171+ new NRTReplicationEngineFactory (),
172+ recoverySettings ,
173+ MergedSegmentPublisher .EMPTY
174+ )
175+ ) {
176+ shards .startAll ();
177+ final IndexShard primaryShard = shards .getPrimary ();
178+ final IndexShard replicaShard = shards .getReplicas ().get (0 );
179+
180+ // index and replicate segments to replica.
181+ int numDocs = randomIntBetween (10 , 20 );
182+ shards .indexDocs (numDocs );
183+ primaryShard .refresh ("test" );
184+ flushShard (primaryShard );
185+
186+ shards .indexDocs (numDocs );
187+ primaryShard .refresh ("test" );
188+ flushShard (primaryShard );
189+ replicateSegments (primaryShard , List .of (replicaShard ));
190+ shards .assertAllEqual (2 * numDocs );
191+
192+ primaryShard .forceMerge (new ForceMergeRequest ("test" ).maxNumSegments (1 ));
193+ replicateMergedSegments (primaryShard , List .of (replicaShard ));
194+ primaryShard .refresh ("test" );
195+ assertEquals (1 , primaryShard .segments (false ).size ());
196+ // After the pre-copy merged segment is completed, the merged segment is not visible in the replica, and the number of segments
197+ // in the replica shard is still 2.
198+ assertEquals (2 , replicaShard .segments (false ).size ());
199+ }
200+ }
201+
202+ @ LockFeatureFlag (MERGED_SEGMENT_WARMER_EXPERIMENTAL_FLAG )
203+ public void testMergedSegmentReplicationWithException () throws Exception {
204+ // Test that the pre-copy merged segment exception will not cause primary shard to fail
205+ MergedSegmentPublisher mergedSegmentPublisherWithException = new MergedSegmentPublisher ((indexShard , checkpoint ) -> {
206+ throw new RuntimeException ("mock exception" );
207+ });
208+ final RecoverySettings recoverySettings = new RecoverySettings (
209+ Settings .builder ().put (RecoverySettings .INDICES_MERGED_SEGMENT_REPLICATION_WARMER_ENABLED_SETTING .getKey (), true ).build (),
210+ new ClusterSettings (Settings .EMPTY , ClusterSettings .BUILT_IN_CLUSTER_SETTINGS )
211+ );
212+ try (
213+ ReplicationGroup shards = createGroup (
214+ 1 ,
215+ getIndexSettings (),
216+ indexMapping ,
217+ new NRTReplicationEngineFactory (),
218+ recoverySettings ,
219+ mergedSegmentPublisherWithException
220+ )
221+ ) {
162222 shards .startAll ();
163223 final IndexShard primaryShard = shards .getPrimary ();
164224 final IndexShard replicaShard = shards .getReplicas ().get (0 );
@@ -188,7 +248,20 @@ public void testMergedSegmentReplication() throws Exception {
188248 @ LockFeatureFlag (MERGED_SEGMENT_WARMER_EXPERIMENTAL_FLAG )
189249 public void testMergedSegmentReplicationWithZeroReplica () throws Exception {
190250 // Test that the pre-copy merged segment logic does not block the merge process of the primary shard when there are 0 replica shard.
191- try (ReplicationGroup shards = createGroup (0 , getIndexSettings (), indexMapping , new NRTReplicationEngineFactory ());) {
251+ final RecoverySettings recoverySettings = new RecoverySettings (
252+ Settings .builder ().put (RecoverySettings .INDICES_MERGED_SEGMENT_REPLICATION_WARMER_ENABLED_SETTING .getKey (), true ).build (),
253+ new ClusterSettings (Settings .EMPTY , ClusterSettings .BUILT_IN_CLUSTER_SETTINGS )
254+ );
255+ try (
256+ ReplicationGroup shards = createGroup (
257+ 0 ,
258+ getIndexSettings (),
259+ indexMapping ,
260+ new NRTReplicationEngineFactory (),
261+ recoverySettings ,
262+ MergedSegmentPublisher .EMPTY
263+ )
264+ ) {
192265 shards .startAll ();
193266 final IndexShard primaryShard = shards .getPrimary ();
194267
@@ -210,7 +283,20 @@ public void testMergedSegmentReplicationWithZeroReplica() throws Exception {
210283
211284 @ LockFeatureFlag (MERGED_SEGMENT_WARMER_EXPERIMENTAL_FLAG )
212285 public void testCleanupRedundantPendingMergeSegment () throws Exception {
213- try (ReplicationGroup shards = createGroup (1 , getIndexSettings (), indexMapping , new NRTReplicationEngineFactory ());) {
286+ final RecoverySettings recoverySettings = new RecoverySettings (
287+ Settings .builder ().put (RecoverySettings .INDICES_MERGED_SEGMENT_REPLICATION_WARMER_ENABLED_SETTING .getKey (), true ).build (),
288+ new ClusterSettings (Settings .EMPTY , ClusterSettings .BUILT_IN_CLUSTER_SETTINGS )
289+ );
290+ try (
291+ ReplicationGroup shards = createGroup (
292+ 1 ,
293+ getIndexSettings (),
294+ indexMapping ,
295+ new NRTReplicationEngineFactory (),
296+ recoverySettings ,
297+ MergedSegmentPublisher .EMPTY
298+ )
299+ ) {
214300 shards .startAll ();
215301 final IndexShard primaryShard = shards .getPrimary ();
216302 final IndexShard replicaShard = shards .getReplicas ().get (0 );
0 commit comments