8
8
9
9
package org .opensearch .indices .settings ;
10
10
11
+ import org .opensearch .action .support .WriteRequest ;
11
12
import org .opensearch .cluster .ClusterState ;
12
13
import org .opensearch .cluster .metadata .IndexMetadata ;
13
14
import org .opensearch .cluster .metadata .Metadata ;
24
25
import static org .opensearch .cluster .metadata .IndexMetadata .SETTING_NUMBER_OF_SEARCH_REPLICAS ;
25
26
import static org .opensearch .cluster .metadata .IndexMetadata .SETTING_REPLICATION_TYPE ;
26
27
import static org .opensearch .cluster .routing .UnassignedInfo .INDEX_DELAYED_NODE_LEFT_TIMEOUT_SETTING ;
28
+ import static org .opensearch .test .hamcrest .OpenSearchAssertions .assertHitCount ;
27
29
28
30
@ OpenSearchIntegTestCase .ClusterScope (scope = OpenSearchIntegTestCase .Scope .TEST , numDataNodes = 0 )
29
31
public class SearchOnlyReplicaIT extends OpenSearchIntegTestCase {
@@ -79,9 +81,9 @@ public void testUpdateDocRepFails() {
79
81
assertEquals (expectedFailureMessage , illegalArgumentException .getMessage ());
80
82
}
81
83
82
- public void testSearchReplicasAreNotPrimaryEligible () throws IOException {
83
- int numSearchReplicas = randomIntBetween ( 0 , 3 ) ;
84
- int numWriterReplicas = randomIntBetween ( 0 , 3 ) ;
84
+ public void testFailoverWithSearchReplica_WithWriterReplicas () throws IOException {
85
+ int numSearchReplicas = 1 ;
86
+ int numWriterReplicas = 1 ;
85
87
internalCluster ().startClusterManagerOnlyNode ();
86
88
String primaryNodeName = internalCluster ().startDataOnlyNode ();
87
89
createIndex (
@@ -93,29 +95,51 @@ public void testSearchReplicasAreNotPrimaryEligible() throws IOException {
93
95
.build ()
94
96
);
95
97
ensureYellow (TEST_INDEX );
96
- for (int i = 0 ; i < numSearchReplicas + numWriterReplicas ; i ++) {
97
- internalCluster ().startDataOnlyNode ();
98
- }
98
+ // add 2 nodes for the replicas
99
+ internalCluster ().startDataOnlyNodes (2 );
99
100
ensureGreen (TEST_INDEX );
100
101
101
102
// assert shards are on separate nodes & all active
102
103
assertActiveShardCounts (numSearchReplicas , numWriterReplicas );
103
104
104
105
// stop the primary and ensure search shard is not promoted:
105
106
internalCluster ().stopRandomNode (InternalTestCluster .nameFilter (primaryNodeName ));
106
- ensureRed (TEST_INDEX );
107
+ ensureYellowAndNoInitializingShards (TEST_INDEX );
108
+
109
+ assertActiveShardCounts (numSearchReplicas , 0 ); // 1 repl is inactive that was promoted to primary
110
+ // add back a node
111
+ internalCluster ().startDataOnlyNode ();
112
+ ensureGreen (TEST_INDEX );
113
+
114
+ }
115
+
116
+ public void testFailoverWithSearchReplica_WithoutWriterReplicas () throws IOException {
117
+ int numSearchReplicas = 1 ;
118
+ int numWriterReplicas = 0 ;
119
+ internalCluster ().startClusterManagerOnlyNode ();
120
+ String primaryNodeName = internalCluster ().startDataOnlyNode ();
121
+ createIndex (
122
+ TEST_INDEX ,
123
+ Settings .builder ()
124
+ .put (indexSettings ())
125
+ .put (IndexMetadata .SETTING_NUMBER_OF_REPLICAS , numWriterReplicas )
126
+ .put (IndexMetadata .SETTING_NUMBER_OF_SEARCH_REPLICAS , numSearchReplicas )
127
+ .build ()
128
+ );
129
+ ensureYellow (TEST_INDEX );
130
+ client ().prepareIndex (TEST_INDEX ).setId ("1" ).setSource ("foo" , "bar" ).setRefreshPolicy (WriteRequest .RefreshPolicy .IMMEDIATE ).get ();
131
+ // start a node for our search replica
132
+ String replica = internalCluster ().startDataOnlyNode ();
133
+ ensureGreen (TEST_INDEX );
134
+ assertActiveSearchShards (numSearchReplicas );
135
+ assertHitCount (client (replica ).prepareSearch (TEST_INDEX ).setSize (0 ).setPreference ("_only_local" ).get (), 1 );
107
136
108
- if (numWriterReplicas > 0 ) {
109
- assertActiveShardCounts (numSearchReplicas , numWriterReplicas - 1 ); // 1 repl is inactive that was promoted to primary
110
- // add back a node
111
- internalCluster ().startDataOnlyNode ();
112
- ensureGreen (TEST_INDEX );
113
- } else {
114
- // index falls red and does not recover
115
- // Without any writer replica with n2n replication this is an unrecoverable scenario and snapshot restore is required.
116
- ensureRed (TEST_INDEX );
117
- assertActiveSearchShards (numSearchReplicas );
118
- }
137
+ // stop the primary and ensure search shard is not promoted:
138
+ internalCluster ().stopRandomNode (InternalTestCluster .nameFilter (primaryNodeName ));
139
+ ensureRed (TEST_INDEX );
140
+ assertActiveSearchShards (numSearchReplicas );
141
+ // while red our search shard is still searchable
142
+ assertHitCount (client (replica ).prepareSearch (TEST_INDEX ).setSize (0 ).setPreference ("_only_local" ).get (), 1 );
119
143
}
120
144
121
145
public void testSearchReplicaScaling () {
0 commit comments