From 962af3a83413d573cdf89d4f25abf742c72e038b Mon Sep 17 00:00:00 2001 From: Nils Bandener Date: Thu, 18 Dec 2025 12:59:38 +0100 Subject: [PATCH 1/2] New tests for protected indices feature Signed-off-by: Nils Bandener --- .../ProtectedIndexAuthorizationIntTests.java | 340 ++++++++++++++++++ 1 file changed, 340 insertions(+) create mode 100644 src/integrationTest/java/org/opensearch/security/privileges/int_tests/ProtectedIndexAuthorizationIntTests.java diff --git a/src/integrationTest/java/org/opensearch/security/privileges/int_tests/ProtectedIndexAuthorizationIntTests.java b/src/integrationTest/java/org/opensearch/security/privileges/int_tests/ProtectedIndexAuthorizationIntTests.java new file mode 100644 index 0000000000..0feb565b1d --- /dev/null +++ b/src/integrationTest/java/org/opensearch/security/privileges/int_tests/ProtectedIndexAuthorizationIntTests.java @@ -0,0 +1,340 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + * + * Modifications Copyright OpenSearch Contributors. See + * GitHub history for details. + */ + +package org.opensearch.security.privileges.int_tests; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +import com.google.common.collect.ImmutableList; +import org.junit.AfterClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + +import org.opensearch.test.framework.TestSecurityConfig; +import org.opensearch.test.framework.cluster.LocalCluster; +import org.opensearch.test.framework.cluster.TestRestClient; +import org.opensearch.test.framework.data.TestAlias; +import org.opensearch.test.framework.data.TestIndex; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.opensearch.test.framework.TestSecurityConfig.AuthcDomain.AUTHC_HTTPBASIC_INTERNAL; +import static org.opensearch.test.framework.cluster.TestRestClient.json; +import static org.opensearch.test.framework.matcher.RestIndexMatchers.IndexMatcher; +import static org.opensearch.test.framework.matcher.RestIndexMatchers.OnResponseIndexMatcher.containsExactly; +import static org.opensearch.test.framework.matcher.RestIndexMatchers.OnUserIndexMatcher.limitedTo; +import static org.opensearch.test.framework.matcher.RestMatchers.isCreated; +import static org.opensearch.test.framework.matcher.RestMatchers.isForbidden; +import static org.opensearch.test.framework.matcher.RestMatchers.isOk; + +/** + * This class tests protected indices functionality with different cluster configurations. + * It uses the following dimensions: + * + */ +@RunWith(Parameterized.class) +public class ProtectedIndexAuthorizationIntTests { + + // ------------------------------------------------------------------------------------------------------- + // Test indices used by this test suite + // ------------------------------------------------------------------------------------------------------- + + static final TestIndex protected_index1 = TestIndex.name("protected_index1").documentCount(10).seed(1).build(); + static final TestIndex protected_index2 = TestIndex.name("protected_index2").documentCount(10).seed(2).build(); + static final TestIndex unprotected_index = TestIndex.name("unprotected_index").documentCount(10).seed(4).build(); + + static final TestAlias alias_protected = new TestAlias("alias_protected").on(protected_index1); + + static final TestSecurityConfig.User.MetadataKey ALLOWED = new TestSecurityConfig.User.MetadataKey<>( + "allowed", + IndexMatcher.class + ); + + // ------------------------------------------------------------------------------------------------------- + // Test users with different privilege configurations + // ------------------------------------------------------------------------------------------------------- + + static final TestSecurityConfig.Role PROTECTED_INDEX_ROLE = new TestSecurityConfig.Role("protected_index_role"); + + /** + * User with all index permissions but NOT member of protected index roles. + * When protected indices are enabled, they should NOT have access to protected indices. + */ + static final TestSecurityConfig.User NORMAL_USER = new TestSecurityConfig.User("normal_user")// + .description("all_access but no protected role")// + .roles( + new TestSecurityConfig.Role("all_access_role")// + .clusterPermissions("*") + .indexPermissions("*") + .on("*") + )// + .reference(ALLOWED, limitedTo(unprotected_index)); + + /** + * User with all index permissions AND member of protected_index_role. + * When protected indices are enabled, they SHOULD have full access to protected indices. + */ + static final TestSecurityConfig.User PROTECTED_INDEX_USER = new TestSecurityConfig.User("protected_index_user")// + .description("all_access with protected role")// + .roles( + new TestSecurityConfig.Role("all_access_role")// + .clusterPermissions("*") + .indexPermissions("*") + .on("*") + ) + .referencedRoles(PROTECTED_INDEX_ROLE)// + .reference(ALLOWED, limitedTo(protected_index1, protected_index2, unprotected_index)); + + static final List USERS = ImmutableList.of(NORMAL_USER, PROTECTED_INDEX_USER); + + static LocalCluster.Builder clusterBuilder() { + return new LocalCluster.Builder().singleNode() + .authc(AUTHC_HTTPBASIC_INTERNAL) + .users(USERS) + .indices(protected_index1, protected_index2, unprotected_index) + .aliases(alias_protected) + .roles(PROTECTED_INDEX_ROLE) + .nodeSettings( + Map.of( + "plugins.security.protected_indices.enabled", + true, + "plugins.security.protected_indices.indices", + "protected_index*", + "plugins.security.protected_indices.roles", + "protected_index_role" + ) + ); + } + + @AfterClass + public static void stopClusters() { + for (ClusterConfig clusterConfig : ClusterConfig.values()) { + clusterConfig.shutdown(); + } + } + + final TestSecurityConfig.User user; + final LocalCluster cluster; + final ClusterConfig clusterConfig; + + @Test + public void search_protectedIndex() { + try (TestRestClient restClient = cluster.getRestClient(user)) { + String matchAllQuery = "{\"query\": {\"match_all\": {}}}"; + + TestRestClient.HttpResponse response = restClient.postJson("protected_index1/_search", matchAllQuery); + if (user == PROTECTED_INDEX_USER) { + assertThat(response, isOk()); + assertThat(response, containsExactly(protected_index1).at("hits.hits[*]._index")); + } else if (clusterConfig.legacyPrivilegeEvaluation) { + assertThat(response, isOk()); + assertThat(response, containsExactly().at("hits.hits[*]._index")); + } else { + // Thew new privilege evaluation just forbids this request; this follows the normal index reduction semantics + assertThat(response, isForbidden()); + } + } + } + + @Test + public void search_unprotectedIndex() { + try (TestRestClient restClient = cluster.getRestClient(user)) { + String matchAllQuery = "{\"query\": {\"match_all\": {}}}"; + + TestRestClient.HttpResponse response = restClient.postJson("unprotected_index/_search", matchAllQuery); + assertThat(response, isOk()); + assertThat(response, containsExactly(unprotected_index).at("hits.hits[*]._index")); + } + } + + @Test + public void search_protectedIndexPattern() { + try (TestRestClient restClient = cluster.getRestClient(user)) { + String matchAllQuery = "{\"query\": {\"match_all\": {}}}"; + + TestRestClient.HttpResponse response = restClient.postJson("protected_index*/_search?size=100", matchAllQuery); + + if (user == PROTECTED_INDEX_USER) { + assertThat(response, isOk()); + assertThat(response, containsExactly(protected_index1, protected_index2).at("hits.hits[*]._index")); + } else { + assertThat(response, isOk()); + assertThat(response, containsExactly().at("hits.hits[*]._index")); + } + } + } + + @Test + public void search_aliasContainingProtectedIndices() { + try (TestRestClient restClient = cluster.getRestClient(user)) { + String matchAllQuery = "{\"query\": {\"match_all\": {}}}"; + + TestRestClient.HttpResponse response = restClient.postJson("alias_protected/_search?size=100", matchAllQuery); + + if (user == PROTECTED_INDEX_USER) { + assertThat(response, isOk()); + assertThat(response, containsExactly(protected_index1).at("hits.hits[*]._index")); + } else { + assertThat(response, isOk()); + assertThat(response, containsExactly().at("hits.hits[*]._index")); + } + } + } + + @Test + public void createDocument_protectedIndex() { + String docId = "protected_index1/_doc/create_test_doc"; + try (TestRestClient restClient = cluster.getRestClient(user)) { + TestRestClient.HttpResponse response = restClient.put(docId, json("foo", "bar")); + if (user == PROTECTED_INDEX_USER) { + assertThat(response, isCreated()); + } else { + assertThat(response, isForbidden()); + } + } finally { + delete(docId); + } + } + + @Test + public void deleteDocument_protectedIndex() { + String docId = "protected_index1/_doc/create_test_doc"; + try (TestRestClient restClient = cluster.getRestClient(user); TestRestClient adminRestClient = cluster.getAdminCertRestClient()) { + + // Initialization: Create document as admin + { + TestRestClient.HttpResponse httpResponse = adminRestClient.put(docId + "?refresh=true", json("foo", "bar")); + assertThat(httpResponse, isCreated()); + } + + TestRestClient.HttpResponse response = restClient.delete(docId); + if (user == PROTECTED_INDEX_USER) { + assertThat(response, isOk()); + } else { + assertThat(response, isForbidden()); + } + } finally { + delete(docId); + } + } + + @Test + public void updateMappings_protectedIndex() { + try (TestRestClient restClient = cluster.getRestClient(user)) { + String newMappings = "{\"properties\": {\"user_name\": {\"type\": \"text\"}}}"; + TestRestClient.HttpResponse response = restClient.putJson("protected_index1/_mapping", newMappings); + if (user == PROTECTED_INDEX_USER) { + assertThat(response, isOk()); + } else { + assertThat(response, isForbidden()); + } + } + } + + @Test + public void closeIndex_protectedIndex() { + try (TestRestClient restClient = cluster.getRestClient(user)) { + TestRestClient.HttpResponse response = restClient.post("protected_index2/_close"); + if (user == PROTECTED_INDEX_USER) { + assertThat(response, isOk()); + } else { + assertThat(response, isForbidden()); + } + } finally { + try (TestRestClient adminRestClient = cluster.getAdminCertRestClient()) { + adminRestClient.post("protected_index2/_open"); + } + } + } + + @Test + public void updateSettings_protectedIndex() { + try (TestRestClient restClient = cluster.getRestClient(user)) { + String indexSettings = "{\"index\": {\"refresh_interval\": \"5s\"}}"; + TestRestClient.HttpResponse response = restClient.putJson("protected_index1/_settings", indexSettings); + if (user == PROTECTED_INDEX_USER) { + assertThat(response, isOk()); + } else { + assertThat(response, isForbidden()); + } + } finally { + try (TestRestClient adminRestClient = cluster.getAdminCertRestClient()) { + adminRestClient.putJson("protected_index1/_settings", "{\"index\": {\"refresh_interval\": null}}"); + } + } + } + + @Test + public void aliasOperations_protectedIndex() { + String aliasName = "test_alias_protected"; + try (TestRestClient restClient = cluster.getRestClient(user)) { + String addAliasBody = """ + {"actions": [{"add": {"index": "protected_index1", "alias": "%s"}}]} + """.formatted(aliasName); + + TestRestClient.HttpResponse response = restClient.postJson("_aliases", addAliasBody); + + if (user == PROTECTED_INDEX_USER) { + assertThat(response, isOk()); + } else { + assertThat(response, isForbidden()); + } + } finally { + // Cleanup - remove alias + try (TestRestClient adminRestClient = cluster.getAdminCertRestClient()) { + String removeAliasBody = """ + {"actions": [{"remove": {"index": "protected_index1", "alias": "%s"}}]} + """.formatted(aliasName); + adminRestClient.postJson("_aliases", removeAliasBody); + } + } + } + + @Parameterized.Parameters(name = "{0}, {2}") + public static Collection params() { + List result = new ArrayList<>(); + + for (ClusterConfig clusterConfig : ClusterConfig.values()) { + for (TestSecurityConfig.User user : USERS) { + result.add(new Object[] { clusterConfig, user, user.getDescription() }); + } + } + return result; + } + + public ProtectedIndexAuthorizationIntTests( + ClusterConfig clusterConfig, + TestSecurityConfig.User user, + @SuppressWarnings("unused") String description + ) { + this.user = user; + this.cluster = clusterConfig.cluster(ProtectedIndexAuthorizationIntTests::clusterBuilder); + this.clusterConfig = clusterConfig; + } + + private void delete(String... paths) { + try (TestRestClient adminRestClient = cluster.getAdminCertRestClient()) { + for (String path : paths) { + TestRestClient.HttpResponse response = adminRestClient.delete(path); + if (response.getStatusCode() != 200 && response.getStatusCode() != 404) { + throw new RuntimeException("Error while deleting " + path + "\n" + response.getBody()); + } + } + } + } +} From 76ea28b64f384959b8894be2f33b23d298ebb96a Mon Sep 17 00:00:00 2001 From: Nils Bandener Date: Mon, 29 Dec 2025 07:18:53 +0100 Subject: [PATCH 2/2] Changed management of clusters created via ClusterConfig to avoid concurrency issue Signed-off-by: Nils Bandener --- .../privileges/int_tests/ClusterConfig.java | 50 ++++++++++++------- .../CrossClusterAuthorizationIntTests.java | 13 ++--- .../DashboardMultiTenancyIntTests.java | 14 +++--- ...taStreamAuthorizationReadOnlyIntTests.java | 14 +++--- ...aStreamAuthorizationReadWriteIntTests.java | 14 +++--- .../IndexAuthorizationReadOnlyIntTests.java | 14 +++--- .../IndexAuthorizationReadWriteIntTests.java | 14 +++--- ...uthorizationWithClosedIndicesIntTests.java | 10 ++-- .../ProtectedIndexAuthorizationIntTests.java | 14 +++--- .../SnapshotAuthorizationIntTests.java | 14 +++--- .../test/framework/cluster/LocalCluster.java | 11 ++++ 11 files changed, 97 insertions(+), 85 deletions(-) diff --git a/src/integrationTest/java/org/opensearch/security/privileges/int_tests/ClusterConfig.java b/src/integrationTest/java/org/opensearch/security/privileges/int_tests/ClusterConfig.java index 2d3a1627e0..cfed0b4262 100644 --- a/src/integrationTest/java/org/opensearch/security/privileges/int_tests/ClusterConfig.java +++ b/src/integrationTest/java/org/opensearch/security/privileges/int_tests/ClusterConfig.java @@ -12,9 +12,12 @@ package org.opensearch.security.privileges.int_tests; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; import java.util.function.Function; import java.util.function.Supplier; +import org.junit.rules.ExternalResource; + import org.opensearch.test.framework.cluster.LocalCluster; /** @@ -46,8 +49,6 @@ public enum ClusterConfig { final boolean systemIndexPrivilegeEnabled; final boolean allowsEmptyResultSets; - private LocalCluster cluster; - ClusterConfig( String name, Function clusterConfiguration, @@ -62,25 +63,38 @@ public enum ClusterConfig { this.allowsEmptyResultSets = allowsEmptyResultSets; } - LocalCluster cluster(Supplier clusterBuilder) { - if (cluster == null) { - cluster = this.clusterConfiguration.apply(clusterBuilder.get()).build(); - cluster.before(); - } - return cluster; + @Override + public String toString() { + return name; } - void shutdown() { - if (cluster != null) { - try { - cluster.close(); - } catch (Exception e) {} - cluster = null; + public static class ClusterInstances extends ExternalResource { + private final Supplier clusterBuilder; + + public ClusterInstances(Supplier clusterBuilder) { + this.clusterBuilder = clusterBuilder; } - } - @Override - public String toString() { - return name; + private Map configToInstanceMap = new ConcurrentHashMap<>(); + + public LocalCluster get(ClusterConfig config) { + LocalCluster cluster = configToInstanceMap.get(config); + if (cluster == null) { + cluster = config.clusterConfiguration.apply(clusterBuilder.get()).build(); + cluster.before(); + configToInstanceMap.put(config, cluster); + } + + return cluster; + } + + @Override + protected void after() { + for (Map.Entry entry : configToInstanceMap.entrySet()) { + entry.getValue().stopSafe(); + } + configToInstanceMap.clear(); + }; + } } diff --git a/src/integrationTest/java/org/opensearch/security/privileges/int_tests/CrossClusterAuthorizationIntTests.java b/src/integrationTest/java/org/opensearch/security/privileges/int_tests/CrossClusterAuthorizationIntTests.java index be24358308..76f28dd96a 100644 --- a/src/integrationTest/java/org/opensearch/security/privileges/int_tests/CrossClusterAuthorizationIntTests.java +++ b/src/integrationTest/java/org/opensearch/security/privileges/int_tests/CrossClusterAuthorizationIntTests.java @@ -16,7 +16,6 @@ import java.util.List; import com.google.common.collect.ImmutableList; -import org.junit.AfterClass; import org.junit.ClassRule; import org.junit.Test; import org.junit.runner.RunWith; @@ -189,12 +188,10 @@ static LocalCluster.Builder clusterBuilder() { .indices(LocalIndices.index_a1, LocalIndices.index_a2); } - @AfterClass - public static void stopClusters() { - for (ClusterConfig clusterConfig : ClusterConfig.values()) { - clusterConfig.shutdown(); - } - } + @ClassRule + public static final ClusterConfig.ClusterInstances clusters = new ClusterConfig.ClusterInstances( + CrossClusterAuthorizationIntTests::clusterBuilder + ); final TestSecurityConfig.User user; final LocalCluster cluster; @@ -479,7 +476,7 @@ public static Collection params() { public CrossClusterAuthorizationIntTests(ClusterConfig clusterConfig, TestSecurityConfig.User user, String description) throws Exception { this.user = user; - this.cluster = clusterConfig.cluster(CrossClusterAuthorizationIntTests::clusterBuilder); + this.cluster = clusters.get(clusterConfig); this.clusterConfig = clusterConfig; } diff --git a/src/integrationTest/java/org/opensearch/security/privileges/int_tests/DashboardMultiTenancyIntTests.java b/src/integrationTest/java/org/opensearch/security/privileges/int_tests/DashboardMultiTenancyIntTests.java index cc7ab237c1..5b67d241e2 100644 --- a/src/integrationTest/java/org/opensearch/security/privileges/int_tests/DashboardMultiTenancyIntTests.java +++ b/src/integrationTest/java/org/opensearch/security/privileges/int_tests/DashboardMultiTenancyIntTests.java @@ -17,7 +17,7 @@ import java.util.UUID; import org.apache.hc.core5.http.message.BasicHeader; -import org.junit.AfterClass; +import org.junit.ClassRule; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; @@ -361,12 +361,10 @@ static LocalCluster.Builder clusterBuilder() { ); } - @AfterClass - public static void stopClusters() { - for (ClusterConfig clusterConfig : ClusterConfig.values()) { - clusterConfig.shutdown(); - } - } + @ClassRule + public static final ClusterConfig.ClusterInstances clusterInstances = new ClusterConfig.ClusterInstances( + DashboardMultiTenancyIntTests::clusterBuilder + ); final TestSecurityConfig.User user; final LocalCluster cluster; @@ -763,7 +761,7 @@ public DashboardMultiTenancyIntTests( @SuppressWarnings("unused") String description ) { this.user = user; - this.cluster = clusterConfig.cluster(DashboardMultiTenancyIntTests::clusterBuilder); + this.cluster = clusterInstances.get(clusterConfig); this.clusterConfig = clusterConfig; } diff --git a/src/integrationTest/java/org/opensearch/security/privileges/int_tests/DataStreamAuthorizationReadOnlyIntTests.java b/src/integrationTest/java/org/opensearch/security/privileges/int_tests/DataStreamAuthorizationReadOnlyIntTests.java index 2eaf0b5012..a43be48ca6 100644 --- a/src/integrationTest/java/org/opensearch/security/privileges/int_tests/DataStreamAuthorizationReadOnlyIntTests.java +++ b/src/integrationTest/java/org/opensearch/security/privileges/int_tests/DataStreamAuthorizationReadOnlyIntTests.java @@ -15,7 +15,7 @@ import java.util.Collection; import java.util.List; -import org.junit.AfterClass; +import org.junit.ClassRule; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; @@ -228,12 +228,10 @@ static LocalCluster.Builder clusterBuilder() { .indices(index_c1); } - @AfterClass - public static void stopClusters() { - for (ClusterConfig clusterConfig : ClusterConfig.values()) { - clusterConfig.shutdown(); - } - } + @ClassRule + public static final ClusterConfig.ClusterInstances clusterInstances = new ClusterConfig.ClusterInstances( + DataStreamAuthorizationReadOnlyIntTests::clusterBuilder + ); final TestSecurityConfig.User user; final LocalCluster cluster; @@ -875,7 +873,7 @@ public static Collection params() { public DataStreamAuthorizationReadOnlyIntTests(ClusterConfig clusterConfig, TestSecurityConfig.User user, String description) throws Exception { this.user = user; - this.cluster = clusterConfig.cluster(DataStreamAuthorizationReadOnlyIntTests::clusterBuilder); + this.cluster = clusterInstances.get(clusterConfig); this.clusterConfig = clusterConfig; } } diff --git a/src/integrationTest/java/org/opensearch/security/privileges/int_tests/DataStreamAuthorizationReadWriteIntTests.java b/src/integrationTest/java/org/opensearch/security/privileges/int_tests/DataStreamAuthorizationReadWriteIntTests.java index a378609ff4..b43111158e 100644 --- a/src/integrationTest/java/org/opensearch/security/privileges/int_tests/DataStreamAuthorizationReadWriteIntTests.java +++ b/src/integrationTest/java/org/opensearch/security/privileges/int_tests/DataStreamAuthorizationReadWriteIntTests.java @@ -19,7 +19,7 @@ import com.google.common.collect.ImmutableList; import org.junit.After; -import org.junit.AfterClass; +import org.junit.ClassRule; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; @@ -420,12 +420,10 @@ static LocalCluster.Builder clusterBuilder() { .plugin(IndexAuthorizationReadOnlyIntTests.SystemIndexTestPlugin.class); } - @AfterClass - public static void stopClusters() { - for (ClusterConfig clusterConfig : ClusterConfig.values()) { - clusterConfig.shutdown(); - } - } + @ClassRule + public static final ClusterConfig.ClusterInstances clusterInstances = new ClusterConfig.ClusterInstances( + DataStreamAuthorizationReadWriteIntTests::clusterBuilder + ); final TestSecurityConfig.User user; final LocalCluster cluster; @@ -601,7 +599,7 @@ public static Collection params() { public DataStreamAuthorizationReadWriteIntTests(ClusterConfig clusterConfig, TestSecurityConfig.User user, String description) throws Exception { this.user = user; - this.cluster = clusterConfig.cluster(DataStreamAuthorizationReadWriteIntTests::clusterBuilder); + this.cluster = clusterInstances.get(clusterConfig); this.clusterConfig = clusterConfig; } diff --git a/src/integrationTest/java/org/opensearch/security/privileges/int_tests/IndexAuthorizationReadOnlyIntTests.java b/src/integrationTest/java/org/opensearch/security/privileges/int_tests/IndexAuthorizationReadOnlyIntTests.java index 75c35ebbf5..1642398de3 100644 --- a/src/integrationTest/java/org/opensearch/security/privileges/int_tests/IndexAuthorizationReadOnlyIntTests.java +++ b/src/integrationTest/java/org/opensearch/security/privileges/int_tests/IndexAuthorizationReadOnlyIntTests.java @@ -19,7 +19,7 @@ import java.util.stream.Stream; import com.google.common.collect.ImmutableList; -import org.junit.AfterClass; +import org.junit.ClassRule; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; @@ -395,12 +395,10 @@ static LocalCluster.Builder clusterBuilder() { .plugin(SystemIndexTestPlugin.class, MustacheModulePlugin.class); } - @AfterClass - public static void stopClusters() { - for (ClusterConfig clusterConfig : ClusterConfig.values()) { - clusterConfig.shutdown(); - } - } + @ClassRule + public static final ClusterConfig.ClusterInstances clusterInstances = new ClusterConfig.ClusterInstances( + IndexAuthorizationReadOnlyIntTests::clusterBuilder + ); final TestSecurityConfig.User user; final LocalCluster cluster; @@ -1878,7 +1876,7 @@ public static Collection params() { public IndexAuthorizationReadOnlyIntTests(ClusterConfig clusterConfig, TestSecurityConfig.User user, String description) throws Exception { this.user = user; - this.cluster = clusterConfig.cluster(IndexAuthorizationReadOnlyIntTests::clusterBuilder); + this.cluster = clusterInstances.get(clusterConfig); this.clusterConfig = clusterConfig; } diff --git a/src/integrationTest/java/org/opensearch/security/privileges/int_tests/IndexAuthorizationReadWriteIntTests.java b/src/integrationTest/java/org/opensearch/security/privileges/int_tests/IndexAuthorizationReadWriteIntTests.java index 1dbbee4a78..db46b42820 100644 --- a/src/integrationTest/java/org/opensearch/security/privileges/int_tests/IndexAuthorizationReadWriteIntTests.java +++ b/src/integrationTest/java/org/opensearch/security/privileges/int_tests/IndexAuthorizationReadWriteIntTests.java @@ -18,7 +18,7 @@ import com.google.common.collect.ImmutableList; import org.junit.After; -import org.junit.AfterClass; +import org.junit.ClassRule; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; @@ -570,12 +570,10 @@ static LocalCluster.Builder clusterBuilder() { .plugin(IndexAuthorizationReadOnlyIntTests.SystemIndexTestPlugin.class); } - @AfterClass - public static void stopClusters() { - for (ClusterConfig clusterConfig : ClusterConfig.values()) { - clusterConfig.shutdown(); - } - } + @ClassRule + public static final ClusterConfig.ClusterInstances clusterInstances = new ClusterConfig.ClusterInstances( + IndexAuthorizationReadWriteIntTests::clusterBuilder + ); final TestSecurityConfig.User user; final LocalCluster cluster; @@ -1157,7 +1155,7 @@ public static Collection params() { public IndexAuthorizationReadWriteIntTests(ClusterConfig clusterConfig, TestSecurityConfig.User user, String description) throws Exception { this.user = user; - this.cluster = clusterConfig.cluster(IndexAuthorizationReadWriteIntTests::clusterBuilder); + this.cluster = clusterInstances.get(clusterConfig); this.clusterConfig = clusterConfig; } diff --git a/src/integrationTest/java/org/opensearch/security/privileges/int_tests/IndexAuthorizationWithClosedIndicesIntTests.java b/src/integrationTest/java/org/opensearch/security/privileges/int_tests/IndexAuthorizationWithClosedIndicesIntTests.java index e94d377704..eddf0cb69e 100644 --- a/src/integrationTest/java/org/opensearch/security/privileges/int_tests/IndexAuthorizationWithClosedIndicesIntTests.java +++ b/src/integrationTest/java/org/opensearch/security/privileges/int_tests/IndexAuthorizationWithClosedIndicesIntTests.java @@ -20,6 +20,7 @@ import org.apache.logging.log4j.Logger; import org.junit.After; import org.junit.Before; +import org.junit.ClassRule; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; @@ -140,9 +141,13 @@ static LocalCluster.Builder clusterBuilder() { .plugin(MustacheModulePlugin.class); } + @ClassRule + public static final ClusterConfig.ClusterInstances clusterInstances = new ClusterConfig.ClusterInstances( + IndexAuthorizationWithClosedIndicesIntTests::clusterBuilder + ); + private final TestSecurityConfig.User user; private final LocalCluster cluster; - private final ClusterConfig clusterConfig; @Parameters(name = "{0}, {2}") public static Collection params() { @@ -159,8 +164,7 @@ public static Collection params() { public IndexAuthorizationWithClosedIndicesIntTests(ClusterConfig clusterConfig, TestSecurityConfig.User user, String description) throws Exception { this.user = user; - this.cluster = clusterConfig.cluster(IndexAuthorizationWithClosedIndicesIntTests::clusterBuilder); - this.clusterConfig = clusterConfig; + this.cluster = clusterInstances.get(clusterConfig); } @Before diff --git a/src/integrationTest/java/org/opensearch/security/privileges/int_tests/ProtectedIndexAuthorizationIntTests.java b/src/integrationTest/java/org/opensearch/security/privileges/int_tests/ProtectedIndexAuthorizationIntTests.java index 0feb565b1d..2a6e887069 100644 --- a/src/integrationTest/java/org/opensearch/security/privileges/int_tests/ProtectedIndexAuthorizationIntTests.java +++ b/src/integrationTest/java/org/opensearch/security/privileges/int_tests/ProtectedIndexAuthorizationIntTests.java @@ -17,7 +17,7 @@ import java.util.Map; import com.google.common.collect.ImmutableList; -import org.junit.AfterClass; +import org.junit.ClassRule; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; @@ -121,12 +121,10 @@ static LocalCluster.Builder clusterBuilder() { ); } - @AfterClass - public static void stopClusters() { - for (ClusterConfig clusterConfig : ClusterConfig.values()) { - clusterConfig.shutdown(); - } - } + @ClassRule + public static final ClusterConfig.ClusterInstances clusterInstances = new ClusterConfig.ClusterInstances( + ProtectedIndexAuthorizationIntTests::clusterBuilder + ); final TestSecurityConfig.User user; final LocalCluster cluster; @@ -323,7 +321,7 @@ public ProtectedIndexAuthorizationIntTests( @SuppressWarnings("unused") String description ) { this.user = user; - this.cluster = clusterConfig.cluster(ProtectedIndexAuthorizationIntTests::clusterBuilder); + this.cluster = clusterInstances.get(clusterConfig); this.clusterConfig = clusterConfig; } diff --git a/src/integrationTest/java/org/opensearch/security/privileges/int_tests/SnapshotAuthorizationIntTests.java b/src/integrationTest/java/org/opensearch/security/privileges/int_tests/SnapshotAuthorizationIntTests.java index 3f999cbc69..bf0b4b9e4f 100644 --- a/src/integrationTest/java/org/opensearch/security/privileges/int_tests/SnapshotAuthorizationIntTests.java +++ b/src/integrationTest/java/org/opensearch/security/privileges/int_tests/SnapshotAuthorizationIntTests.java @@ -18,7 +18,7 @@ import com.google.common.collect.ImmutableList; import org.apache.hc.core5.http.HttpEntity; import org.junit.After; -import org.junit.AfterClass; +import org.junit.ClassRule; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; @@ -195,12 +195,10 @@ static LocalCluster.Builder clusterBuilder() { .plugin(IndexAuthorizationReadOnlyIntTests.SystemIndexTestPlugin.class); } - @AfterClass - public static void stopClusters() { - for (ClusterConfig clusterConfig : ClusterConfig.values()) { - clusterConfig.shutdown(); - } - } + @ClassRule + public static final ClusterConfig.ClusterInstances clusterInstances = new ClusterConfig.ClusterInstances( + SnapshotAuthorizationIntTests::clusterBuilder + ); final TestSecurityConfig.User user; final LocalCluster cluster; @@ -354,7 +352,7 @@ public static Collection params() { public SnapshotAuthorizationIntTests(ClusterConfig clusterConfig, TestSecurityConfig.User user, String description) throws Exception { this.user = user; - this.cluster = clusterConfig.cluster(SnapshotAuthorizationIntTests::clusterBuilder); + this.cluster = clusterInstances.get(clusterConfig); this.clusterConfig = clusterConfig; } diff --git a/src/integrationTest/java/org/opensearch/test/framework/cluster/LocalCluster.java b/src/integrationTest/java/org/opensearch/test/framework/cluster/LocalCluster.java index c84601dcc5..1be176ec8c 100644 --- a/src/integrationTest/java/org/opensearch/test/framework/cluster/LocalCluster.java +++ b/src/integrationTest/java/org/opensearch/test/framework/cluster/LocalCluster.java @@ -201,6 +201,17 @@ public void close() { } } + /** + * Stops the cluster without throwing an exception in case of an error. + */ + public void stopSafe() { + try { + close(); + } catch (Exception e) { + log.error("Error while stopping LocalCluster", e); + } + }; + @Override public String getClusterName() { return clusterName;