|
19 | 19 | import org.opensearch.core.xcontent.ToXContent; |
20 | 20 | import org.opensearch.core.xcontent.XContentBuilder; |
21 | 21 | import org.opensearch.plugins.Plugin; |
| 22 | +import org.opensearch.test.InternalTestCluster.RestartCallback; |
22 | 23 | import org.opensearch.test.OpenSearchIntegTestCase; |
23 | 24 | import org.opensearch.test.disruption.NetworkDisruption; |
24 | 25 | import org.opensearch.test.transport.MockTransportService; |
@@ -178,4 +179,105 @@ public void testSystemRepositorySettingIsHiddenForGetRepositoriesRequest() throw |
178 | 179 | repositoriesResponse = GetRepositoriesResponse.fromXContent(createParser(xContentBuilder)); |
179 | 180 | assertEquals(false, SYSTEM_REPOSITORY_SETTING.get(repositoriesResponse.repositories().get(0).settings())); |
180 | 181 | } |
| 182 | + |
| 183 | + /** |
| 184 | + * Test node join failure when trying to join a cluster with different remote store repository attributes. |
| 185 | + * This negative test case verifies that nodes with incompatible remote store configurations are rejected. |
| 186 | + */ |
| 187 | + public void testNodeJoinFailureWithDifferentRemoteStoreRepositoryAttributes() throws Exception { |
| 188 | + // Start initial cluster with specific remote store repository configuration |
| 189 | + internalCluster().startNode(); |
| 190 | + ensureStableCluster(1); |
| 191 | + |
| 192 | + // Attempt to start a second node with different remote store attributes |
| 193 | + // This should fail because the remote store repository attributes don't match |
| 194 | + expectThrows(IllegalStateException.class, () -> { |
| 195 | + internalCluster().startNode( |
| 196 | + Settings.builder() |
| 197 | + .put("node.attr.remote_store.segment.repository", "different-repo") |
| 198 | + .put("node.attr.remote_store.translog.repository", "different-translog-repo") |
| 199 | + .build() |
| 200 | + ); |
| 201 | + ensureStableCluster(2); |
| 202 | + }); |
| 203 | + |
| 204 | + ensureStableCluster(1); |
| 205 | + } |
| 206 | + |
| 207 | + /** |
| 208 | + * Test node rejoin failure when node attributes are changed after initial join. |
| 209 | + * This test verifies that a node cannot rejoin the cluster with different remote store attributes. |
| 210 | + */ |
| 211 | + public void testNodeRejoinFailureWithChangedRemoteStoreAttributes() throws Exception { |
| 212 | + // Start cluster with 2 nodes |
| 213 | + internalCluster().startNodes(2); |
| 214 | + ensureStableCluster(2); |
| 215 | + |
| 216 | + String nodeToRestart = internalCluster().getNodeNames()[1]; |
| 217 | + |
| 218 | + // Attempt to restart node with different remote store attributes should fail |
| 219 | + // The validation happens during node startup and throws IllegalStateException |
| 220 | + expectThrows(IllegalStateException.class, () -> { |
| 221 | + internalCluster().restartNode(nodeToRestart, new RestartCallback() { |
| 222 | + @Override |
| 223 | + public Settings onNodeStopped(String nodeName) { |
| 224 | + // Return different remote store attributes when restarting |
| 225 | + // This will fail because it's missing the required repository type attributes |
| 226 | + return Settings.builder() |
| 227 | + .put("node.attr.remote_store.segment.repository", "changed-segment-repo") |
| 228 | + .put("node.attr.remote_store.translog.repository", "changed-translog-repo") |
| 229 | + .build(); |
| 230 | + } |
| 231 | + }); |
| 232 | + }); |
| 233 | + |
| 234 | + ensureStableCluster(1); |
| 235 | + } |
| 236 | + |
| 237 | + /** |
| 238 | + * Test node join failure when missing required remote store attributes. |
| 239 | + * This test verifies that nodes without proper remote store configuration are rejected. |
| 240 | + */ |
| 241 | + public void testNodeJoinFailureWithMissingRemoteStoreAttributes() throws Exception { |
| 242 | + internalCluster().startNode(); |
| 243 | + ensureStableCluster(1); |
| 244 | + |
| 245 | + // Attempt to add a node without remote store attributes |
| 246 | + // This should fail because remote store attributes are required |
| 247 | + expectThrows(IllegalStateException.class, () -> { |
| 248 | + internalCluster().startNode( |
| 249 | + Settings.builder() |
| 250 | + .putNull("node.attr.remote_store.segment.repository") |
| 251 | + .putNull("node.attr.remote_store.translog.repository") |
| 252 | + .build() |
| 253 | + ); |
| 254 | + }); |
| 255 | + |
| 256 | + ensureStableCluster(1); |
| 257 | + } |
| 258 | + |
| 259 | + /** |
| 260 | + * Test repository verification failure during node join. |
| 261 | + * This test verifies that nodes fail to join when remote store repositories cannot be verified |
| 262 | + * due to invalid repository settings or missing repository type information. |
| 263 | + */ |
| 264 | + public void testRepositoryVerificationFailureDuringNodeJoin() throws Exception { |
| 265 | + internalCluster().startNode(); |
| 266 | + ensureStableCluster(1); |
| 267 | + |
| 268 | + // Attempt to start a node with invalid repository type - this should fail during repository validation |
| 269 | + // We use an invalid repository type that doesn't exist to trigger repository verification failure |
| 270 | + expectThrows(Exception.class, () -> { |
| 271 | + internalCluster().startNode( |
| 272 | + Settings.builder() |
| 273 | + .put("node.attr.remote_store.segment.repository", REPOSITORY_NAME) |
| 274 | + .put("node.attr.remote_store.translog.repository", REPOSITORY_NAME) |
| 275 | + .put("node.attr.remote_store.repository." + REPOSITORY_NAME + ".type", "invalid_repo_type") |
| 276 | + .build() |
| 277 | + ); |
| 278 | + }); |
| 279 | + |
| 280 | + ensureStableCluster(1); |
| 281 | + } |
| 282 | + |
181 | 283 | } |
0 commit comments