Skip to content

Commit 82ae2cf

Browse files
authored
Abstract polaris-runtime-service tests for all persistence implementations (#2106)
The NoSQL persistence implementation has to run the Iceberg table & view catalog plus the Polaris specific tests as well. Reusing existing tests is beneficial to avoid a lot of code duplcation. This change moves the actual tests to `Abstract*` classes and refactors the existing tests to extend those. The NoSQL persistence work extends the same `Abstract*` classes but runs with different Quarkus test profiles.
1 parent 79ebe84 commit 82ae2cf

11 files changed

+182
-121
lines changed

runtime/service/src/test/java/org/apache/polaris/service/quarkus/admin/PolarisAuthzTestBase.java

Lines changed: 11 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
import com.google.auth.oauth2.GoogleCredentials;
2525
import com.google.common.collect.ImmutableMap;
2626
import io.quarkus.test.junit.QuarkusMock;
27-
import io.quarkus.test.junit.QuarkusTestProfile;
2827
import jakarta.annotation.Nonnull;
2928
import jakarta.enterprise.context.RequestScoped;
3029
import jakarta.enterprise.inject.Alternative;
@@ -89,6 +88,7 @@
8988
import org.apache.polaris.service.context.catalog.CallContextCatalogFactory;
9089
import org.apache.polaris.service.context.catalog.PolarisCallContextCatalogFactory;
9190
import org.apache.polaris.service.events.PolarisEventListener;
91+
import org.apache.polaris.service.quarkus.catalog.Profiles;
9292
import org.apache.polaris.service.storage.PolarisStorageIntegrationProviderImpl;
9393
import org.apache.polaris.service.task.TaskExecutor;
9494
import org.apache.polaris.service.types.PolicyIdentifier;
@@ -103,7 +103,7 @@
103103
/** Base class for shared test setup logic used by various Polaris authz-related tests. */
104104
public abstract class PolarisAuthzTestBase {
105105

106-
public static class Profile implements QuarkusTestProfile {
106+
public static class Profile extends Profiles.DefaultProfile {
107107

108108
@Override
109109
public Set<Class<?>> getEnabledAlternatives() {
@@ -112,23 +112,15 @@ public Set<Class<?>> getEnabledAlternatives() {
112112

113113
@Override
114114
public Map<String, String> getConfigOverrides() {
115-
return Map.of(
116-
"polaris.features.\"ALLOW_SPECIFYING_FILE_IO_IMPL\"",
117-
"true",
118-
"polaris.features.\"ALLOW_INSECURE_STORAGE_TYPES\"",
119-
"true",
120-
"polaris.features.\"ALLOW_EXTERNAL_METADATA_FILE_LOCATION\"",
121-
"true",
122-
"polaris.features.\"SUPPORTED_CATALOG_STORAGE_TYPES\"",
123-
"[\"FILE\",\"S3\"]",
124-
"polaris.readiness.ignore-severe-issues",
125-
"true",
126-
"polaris.features.\"ENABLE_GENERIC_TABLES\"",
127-
"true",
128-
"polaris.features.\"ENFORCE_PRINCIPAL_CREDENTIAL_ROTATION_REQUIRED_CHECKING\"",
129-
"true",
130-
"polaris.features.\"DROP_WITH_PURGE_ENABLED\"",
131-
"true");
115+
return ImmutableMap.<String, String>builder()
116+
.putAll(super.getConfigOverrides())
117+
.put("polaris.features.\"ALLOW_EXTERNAL_METADATA_FILE_LOCATION\"", "true")
118+
.put("polaris.features.\"ENABLE_GENERIC_TABLES\"", "true")
119+
.put(
120+
"polaris.features.\"ENFORCE_PRINCIPAL_CREDENTIAL_ROTATION_REQUIRED_CHECKING\"",
121+
"true")
122+
.put("polaris.features.\"DROP_WITH_PURGE_ENABLED\"", "true")
123+
.build();
132124
}
133125
}
134126

Lines changed: 17 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,6 @@
3434
import com.google.common.collect.Iterables;
3535
import com.google.common.collect.Streams;
3636
import io.quarkus.test.junit.QuarkusMock;
37-
import io.quarkus.test.junit.QuarkusTestProfile;
38-
import io.quarkus.test.junit.TestProfile;
3937
import jakarta.annotation.Nonnull;
4038
import jakarta.annotation.Nullable;
4139
import jakarta.inject.Inject;
@@ -113,7 +111,7 @@
113111
import org.apache.polaris.core.persistence.PolarisEntityManager;
114112
import org.apache.polaris.core.persistence.PolarisMetaStoreManager;
115113
import org.apache.polaris.core.persistence.PolarisResolvedPathWrapper;
116-
import org.apache.polaris.core.persistence.cache.InMemoryEntityCache;
114+
import org.apache.polaris.core.persistence.cache.EntityCache;
117115
import org.apache.polaris.core.persistence.dao.entity.BaseResult;
118116
import org.apache.polaris.core.persistence.dao.entity.EntityResult;
119117
import org.apache.polaris.core.persistence.pagination.Page;
@@ -179,8 +177,7 @@
179177
import software.amazon.awssdk.services.sts.model.AssumeRoleResponse;
180178
import software.amazon.awssdk.services.sts.model.Credentials;
181179

182-
@TestProfile(IcebergCatalogTest.Profile.class)
183-
public abstract class IcebergCatalogTest extends CatalogTests<IcebergCatalog> {
180+
public abstract class AbstractIcebergCatalogTest extends CatalogTests<IcebergCatalog> {
184181
static {
185182
org.assertj.core.api.Assumptions.setPreferredAssumptionException(
186183
PreferredAssumptionException.JUNIT5);
@@ -195,27 +192,14 @@ public abstract class IcebergCatalogTest extends CatalogTests<IcebergCatalog> {
195192
.withRecordCount(1)
196193
.build();
197194

198-
public static class Profile implements QuarkusTestProfile {
199-
195+
public static class Profile extends Profiles.DefaultProfile {
200196
@Override
201197
public Map<String, String> getConfigOverrides() {
202-
return Map.of(
203-
"polaris.features.\"ALLOW_SPECIFYING_FILE_IO_IMPL\"",
204-
"true",
205-
"polaris.features.\"ALLOW_INSECURE_STORAGE_TYPES\"",
206-
"true",
207-
"polaris.features.\"SUPPORTED_CATALOG_STORAGE_TYPES\"",
208-
"[\"FILE\",\"S3\"]",
209-
"polaris.features.\"LIST_PAGINATION_ENABLED\"",
210-
"true",
211-
"polaris.event-listener.type",
212-
"test",
213-
"polaris.readiness.ignore-severe-issues",
214-
"true",
215-
"LIST_PAGINATION_ENABLED",
216-
"true",
217-
"polaris.features.\"ALLOW_TABLE_LOCATION_OVERLAP\"",
218-
"true");
198+
return ImmutableMap.<String, String>builder()
199+
.putAll(super.getConfigOverrides())
200+
.put("polaris.features.\"ALLOW_TABLE_LOCATION_OVERLAP\"", "true")
201+
.put("polaris.features.\"LIST_PAGINATION_ENABLED\"", "true")
202+
.build();
219203
}
220204
}
221205

@@ -271,16 +255,20 @@ public static void setUpMocks() {
271255
}
272256

273257
@Nullable
274-
protected abstract InMemoryEntityCache createEntityCache(
258+
protected abstract EntityCache createEntityCache(
275259
RealmConfig realmConfig, PolarisMetaStoreManager metaStoreManager);
276260

261+
protected void bootstrapRealm(String realmName) {}
262+
277263
@BeforeEach
278264
@SuppressWarnings("unchecked")
279265
public void before(TestInfo testInfo) {
280266
realmName =
281267
"realm_%s_%s"
282268
.formatted(
283269
testInfo.getTestMethod().map(Method::getName).orElse("test"), System.nanoTime());
270+
bootstrapRealm(realmName);
271+
284272
RealmContext realmContext = () -> realmName;
285273
QuarkusMock.installMockForType(realmContext, RealmContext.class);
286274
metaStoreManager = metaStoreManagerFactory.getOrCreateMetaStoreManager(realmContext);
@@ -301,6 +289,10 @@ public void before(TestInfo testInfo) {
301289
storageCredentialCache,
302290
createEntityCache(polarisContext.getRealmConfig(), metaStoreManager));
303291

292+
// LocalPolarisMetaStoreManagerFactory.bootstrapServiceAndCreatePolarisPrincipalForRealm sets
293+
// the CallContext.setCurrentContext() but never clears it, whereas the NoSQL one resets it.
294+
CallContext.setCurrentContext(polarisContext);
295+
304296
PrincipalEntity rootEntity =
305297
new PrincipalEntity(
306298
PolarisEntity.of(
Lines changed: 13 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,6 @@
2222

2323
import com.google.common.collect.ImmutableMap;
2424
import io.quarkus.test.junit.QuarkusMock;
25-
import io.quarkus.test.junit.QuarkusTest;
26-
import io.quarkus.test.junit.QuarkusTestProfile;
27-
import io.quarkus.test.junit.TestProfile;
2825
import jakarta.inject.Inject;
2926
import jakarta.ws.rs.core.SecurityContext;
3027
import java.io.IOException;
@@ -58,7 +55,6 @@
5855
import org.apache.polaris.core.persistence.MetaStoreManagerFactory;
5956
import org.apache.polaris.core.persistence.PolarisEntityManager;
6057
import org.apache.polaris.core.persistence.PolarisMetaStoreManager;
61-
import org.apache.polaris.core.persistence.cache.InMemoryEntityCache;
6258
import org.apache.polaris.core.secrets.UserSecretsManager;
6359
import org.apache.polaris.core.secrets.UserSecretsManagerFactory;
6460
import org.apache.polaris.core.storage.cache.StorageCredentialCache;
@@ -89,32 +85,20 @@
8985
import org.junit.jupiter.api.io.TempDir;
9086
import org.mockito.Mockito;
9187

92-
@QuarkusTest
93-
@TestProfile(IcebergCatalogViewTest.Profile.class)
94-
public class IcebergCatalogViewTest extends ViewCatalogTests<IcebergCatalog> {
88+
public abstract class AbstractIcebergCatalogViewTest extends ViewCatalogTests<IcebergCatalog> {
9589
static {
9690
Assumptions.setPreferredAssumptionException(PreferredAssumptionException.JUNIT5);
9791
}
9892

99-
public static class Profile implements QuarkusTestProfile {
100-
93+
public static class Profile extends Profiles.DefaultProfile {
10194
@Override
10295
public Map<String, String> getConfigOverrides() {
103-
return Map.of(
104-
"polaris.features.\"ALLOW_WILDCARD_LOCATION\"",
105-
"true",
106-
"polaris.features.\"SKIP_CREDENTIAL_SUBSCOPING_INDIRECTION\"",
107-
"true",
108-
"polaris.features.\"ALLOW_SPECIFYING_FILE_IO_IMPL\"",
109-
"true",
110-
"polaris.features.\"ALLOW_INSECURE_STORAGE_TYPES\"",
111-
"true",
112-
"polaris.features.\"SUPPORTED_CATALOG_STORAGE_TYPES\"",
113-
"[\"FILE\",\"S3\"]",
114-
"polaris.event-listener.type",
115-
"test",
116-
"polaris.readiness.ignore-severe-issues",
117-
"true");
96+
return ImmutableMap.<String, String>builder()
97+
.putAll(super.getConfigOverrides())
98+
.put("polaris.features.\"ALLOW_WILDCARD_LOCATION\"", "true")
99+
.put("polaris.features.\"SKIP_CREDENTIAL_SUBSCOPING_INDIRECTION\"", "true")
100+
.put("polaris.features.\"LIST_PAGINATION_ENABLED\"", "true")
101+
.build();
118102
}
119103
}
120104

@@ -159,12 +143,15 @@ public void setUpTempDir(@TempDir Path tempDir) throws Exception {
159143
field.set(this, tempDir);
160144
}
161145

146+
protected void bootstrapRealm(String realmName) {}
147+
162148
@BeforeEach
163149
public void before(TestInfo testInfo) {
164150
realmName =
165151
"realm_%s_%s"
166152
.formatted(
167153
testInfo.getTestMethod().map(Method::getName).orElse("test"), System.nanoTime());
154+
bootstrapRealm(realmName);
168155
RealmContext realmContext = () -> realmName;
169156
QuarkusMock.installMockForType(realmContext, RealmContext.class);
170157

@@ -184,7 +171,8 @@ public void before(TestInfo testInfo) {
184171
new PolarisEntityManager(
185172
metaStoreManager,
186173
storageCredentialCache,
187-
new InMemoryEntityCache(polarisContext.getRealmConfig(), metaStoreManager));
174+
metaStoreManagerFactory.getOrCreateEntityCache(
175+
polarisContext.getRealmContext(), polarisContext.getRealmConfig()));
188176

189177
CallContext.setCurrentContext(polarisContext);
190178

Lines changed: 7 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,6 @@
2424

2525
import com.google.common.collect.ImmutableMap;
2626
import io.quarkus.test.junit.QuarkusMock;
27-
import io.quarkus.test.junit.QuarkusTest;
28-
import io.quarkus.test.junit.QuarkusTestProfile;
29-
import io.quarkus.test.junit.TestProfile;
3027
import jakarta.inject.Inject;
3128
import jakarta.ws.rs.core.SecurityContext;
3229
import java.io.IOException;
@@ -59,7 +56,6 @@
5956
import org.apache.polaris.core.persistence.MetaStoreManagerFactory;
6057
import org.apache.polaris.core.persistence.PolarisEntityManager;
6158
import org.apache.polaris.core.persistence.PolarisMetaStoreManager;
62-
import org.apache.polaris.core.persistence.cache.InMemoryEntityCache;
6359
import org.apache.polaris.core.secrets.UserSecretsManager;
6460
import org.apache.polaris.core.secrets.UserSecretsManagerFactory;
6561
import org.apache.polaris.core.storage.PolarisStorageIntegration;
@@ -91,25 +87,7 @@
9187
import software.amazon.awssdk.services.sts.model.AssumeRoleResponse;
9288
import software.amazon.awssdk.services.sts.model.Credentials;
9389

94-
@QuarkusTest
95-
@TestProfile(PolarisGenericTableCatalogTest.Profile.class)
96-
public class PolarisGenericTableCatalogTest {
97-
98-
public static class Profile implements QuarkusTestProfile {
99-
100-
@Override
101-
public Map<String, String> getConfigOverrides() {
102-
return Map.of(
103-
"polaris.features.\"ALLOW_SPECIFYING_FILE_IO_IMPL\"",
104-
"true",
105-
"polaris.features.\"ALLOW_INSECURE_STORAGE_TYPES\"",
106-
"true",
107-
"polaris.features.\"SUPPORTED_CATALOG_STORAGE_TYPES\"",
108-
"[\"FILE\"]",
109-
"polaris.readiness.ignore-severe-issues",
110-
"true");
111-
}
112-
}
90+
public abstract class AbstractPolarisGenericTableCatalogTest {
11391

11492
protected static final Namespace NS = Namespace.of("newdb");
11593
protected static final TableIdentifier TABLE = TableIdentifier.of(NS, "table");
@@ -152,13 +130,17 @@ public static void setUpMocks() {
152130
QuarkusMock.installMockForType(mock, PolarisStorageIntegrationProviderImpl.class);
153131
}
154132

133+
protected void bootstrapRealm(String realmName) {}
134+
155135
@BeforeEach
156136
@SuppressWarnings("unchecked")
157137
public void before(TestInfo testInfo) {
158138
realmName =
159139
"realm_%s_%s"
160140
.formatted(
161141
testInfo.getTestMethod().map(Method::getName).orElse("test"), System.nanoTime());
142+
bootstrapRealm(realmName);
143+
162144
RealmContext realmContext = () -> realmName;
163145
QuarkusMock.installMockForType(realmContext, RealmContext.class);
164146
metaStoreManager = metaStoreManagerFactory.getOrCreateMetaStoreManager(realmContext);
@@ -176,7 +158,8 @@ public void before(TestInfo testInfo) {
176158
new PolarisEntityManager(
177159
metaStoreManager,
178160
storageCredentialCache,
179-
new InMemoryEntityCache(polarisContext.getRealmConfig(), metaStoreManager));
161+
metaStoreManagerFactory.getOrCreateEntityCache(
162+
realmContext, polarisContext.getRealmConfig()));
180163

181164
PrincipalEntity rootEntity =
182165
new PrincipalEntity(

runtime/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolicyCatalogTest.java renamed to runtime/service/src/test/java/org/apache/polaris/service/quarkus/catalog/AbstractPolicyCatalogTest.java

Lines changed: 7 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -30,17 +30,13 @@
3030

3131
import com.google.common.collect.ImmutableMap;
3232
import io.quarkus.test.junit.QuarkusMock;
33-
import io.quarkus.test.junit.QuarkusTest;
34-
import io.quarkus.test.junit.QuarkusTestProfile;
35-
import io.quarkus.test.junit.TestProfile;
3633
import jakarta.inject.Inject;
3734
import jakarta.ws.rs.core.SecurityContext;
3835
import java.io.IOException;
3936
import java.lang.reflect.Method;
4037
import java.time.Clock;
4138
import java.util.Arrays;
4239
import java.util.List;
43-
import java.util.Map;
4440
import java.util.Set;
4541
import org.apache.iceberg.CatalogProperties;
4642
import org.apache.iceberg.Schema;
@@ -68,7 +64,6 @@
6864
import org.apache.polaris.core.persistence.PolarisEntityManager;
6965
import org.apache.polaris.core.persistence.PolarisMetaStoreManager;
7066
import org.apache.polaris.core.persistence.PolicyMappingAlreadyExistsException;
71-
import org.apache.polaris.core.persistence.cache.InMemoryEntityCache;
7267
import org.apache.polaris.core.policy.PredefinedPolicyTypes;
7368
import org.apache.polaris.core.policy.exceptions.NoSuchPolicyException;
7469
import org.apache.polaris.core.policy.exceptions.PolicyInUseException;
@@ -108,24 +103,7 @@
108103
import software.amazon.awssdk.services.sts.model.AssumeRoleResponse;
109104
import software.amazon.awssdk.services.sts.model.Credentials;
110105

111-
@QuarkusTest
112-
@TestProfile(PolicyCatalogTest.Profile.class)
113-
public class PolicyCatalogTest {
114-
public static class Profile implements QuarkusTestProfile {
115-
116-
@Override
117-
public Map<String, String> getConfigOverrides() {
118-
return Map.of(
119-
"polaris.features.\"ALLOW_SPECIFYING_FILE_IO_IMPL\"",
120-
"true",
121-
"polaris.features.\"SUPPORTED_CATALOG_STORAGE_TYPES\"",
122-
"[\"FILE\"]",
123-
"polaris.features.\"ALLOW_INSECURE_STORAGE_TYPES\"",
124-
"true",
125-
"polaris.readiness.ignore-severe-issues",
126-
"true");
127-
}
128-
}
106+
public abstract class AbstractPolicyCatalogTest {
129107

130108
private static final Namespace NS = Namespace.of("ns1");
131109
private static final TableIdentifier TABLE = TableIdentifier.of(NS, "table");
@@ -178,13 +156,17 @@ public static void setUpMocks() {
178156
QuarkusMock.installMockForType(mock, PolarisStorageIntegrationProviderImpl.class);
179157
}
180158

159+
protected void bootstrapRealm(String realmName) {}
160+
181161
@BeforeEach
182162
@SuppressWarnings("unchecked")
183163
public void before(TestInfo testInfo) {
184164
realmName =
185165
"realm_%s_%s"
186166
.formatted(
187167
testInfo.getTestMethod().map(Method::getName).orElse("test"), System.nanoTime());
168+
bootstrapRealm(realmName);
169+
188170
RealmContext realmContext = () -> realmName;
189171
QuarkusMock.installMockForType(realmContext, RealmContext.class);
190172
metaStoreManager = metaStoreManagerFactory.getOrCreateMetaStoreManager(realmContext);
@@ -202,7 +184,8 @@ public void before(TestInfo testInfo) {
202184
new PolarisEntityManager(
203185
metaStoreManager,
204186
storageCredentialCache,
205-
new InMemoryEntityCache(polarisContext.getRealmConfig(), metaStoreManager));
187+
metaStoreManagerFactory.getOrCreateEntityCache(
188+
realmContext, polarisContext.getRealmConfig()));
206189

207190
callContext = polarisContext;
208191

0 commit comments

Comments
 (0)