1818 */
1919package org .apache .polaris .service .dropwizard .admin ;
2020
21- import static org .apache .polaris .service .context .DefaultRealmContextResolver .REALM_PROPERTY_KEY ;
2221import static org .assertj .core .api .Assertions .assertThat ;
22+ import static org .assertj .core .api .Assertions .assertThatThrownBy ;
2323
24- import io .dropwizard .testing .ConfigOverride ;
25- import io .dropwizard .testing .ResourceHelpers ;
26- import io .dropwizard .testing .junit5 .DropwizardAppExtension ;
27- import io .dropwizard .testing .junit5 .DropwizardExtensionsSupport ;
28- import jakarta .ws .rs .client .Entity ;
29- import jakarta .ws .rs .client .Invocation ;
3024import jakarta .ws .rs .core .Response ;
31- import java .io .IOException ;
3225import java .util .ArrayList ;
3326import java .util .Arrays ;
3427import java .util .List ;
28+ import java .util .Map ;
3529import java .util .UUID ;
30+ import org .apache .iceberg .exceptions .ValidationException ;
3631import org .apache .polaris .core .admin .model .AwsStorageConfigInfo ;
3732import org .apache .polaris .core .admin .model .Catalog ;
3833import org .apache .polaris .core .admin .model .CatalogProperties ;
3934import org .apache .polaris .core .admin .model .CreateCatalogRequest ;
4035import org .apache .polaris .core .admin .model .StorageConfigInfo ;
41- import org .apache .polaris .service .dropwizard .PolarisApplication ;
42- import org .apache .polaris .service .dropwizard .config .PolarisApplicationConfig ;
43- import org .apache .polaris .service .dropwizard .test .PolarisConnectionExtension ;
44- import org .apache .polaris .service .dropwizard .test .PolarisRealm ;
45- import org .apache .polaris .service .dropwizard .test .TestEnvironmentExtension ;
46- import org .junit .jupiter .api .BeforeAll ;
47- import org .junit .jupiter .api .extension .ExtendWith ;
36+ import org .apache .polaris .service .dropwizard .TestServices ;
37+ import org .apache .polaris .service .dropwizard .catalog .io .TestFileIOFactory ;
4838import org .junit .jupiter .params .ParameterizedTest ;
4939import org .junit .jupiter .params .provider .CsvSource ;
5040
51- @ ExtendWith ({
52- DropwizardExtensionsSupport .class ,
53- TestEnvironmentExtension .class ,
54- PolarisConnectionExtension .class
55- })
5641public class PolarisOverlappingCatalogTest {
57- private static final DropwizardAppExtension <PolarisApplicationConfig > EXT =
58- new DropwizardAppExtension <>(
59- PolarisApplication .class ,
60- ResourceHelpers .resourceFilePath ("polaris-server-integrationtest.yml" ),
61- // Bind to random port to support parallelism
62- ConfigOverride .config ("server.applicationConnectors[0].port" , "0" ),
63- ConfigOverride .config ("server.adminConnectors[0].port" , "0" ),
64- // Block overlapping catalog paths:
65- ConfigOverride .config ("featureConfiguration.ALLOW_OVERLAPPING_CATALOG_URLS" , "false" ));
66- private static String userToken ;
67- private static String realm ;
68-
69- @ BeforeAll
70- public static void setup (
71- PolarisConnectionExtension .PolarisToken adminToken , @ PolarisRealm String polarisRealm )
72- throws IOException {
73- userToken = adminToken .token ();
74- realm = polarisRealm ;
75-
76- // Set up the database location
77- PolarisConnectionExtension .createTestDir (realm );
78- }
42+
43+ static TestServices services =
44+ TestServices .inMemory (
45+ new TestFileIOFactory (), Map .of ("ALLOW_OVERLAPPING_CATALOG_URLS" , "false" ));
7946
8047 private Response createCatalog (String prefix , String defaultBaseLocation , boolean isExternal ) {
8148 return createCatalog (prefix , defaultBaseLocation , isExternal , new ArrayList <String >());
8249 }
8350
84- private static Invocation .Builder request () {
85- return EXT .client ()
86- .target (String .format ("http://localhost:%d/api/management/v1/catalogs" , EXT .getLocalPort ()))
87- .request ("application/json" )
88- .header ("Authorization" , "Bearer " + userToken )
89- .header (REALM_PROPERTY_KEY , realm );
90- }
91-
9251 private Response createCatalog (
9352 String prefix ,
9453 String defaultBaseLocation ,
@@ -118,9 +77,10 @@ private Response createCatalog(
11877 System .currentTimeMillis (),
11978 1 ,
12079 config );
121- try (Response response = request ().post (Entity .json (new CreateCatalogRequest (catalog )))) {
122- return response ;
123- }
80+ return services
81+ .catalogsApi ()
82+ .createCatalog (
83+ new CreateCatalogRequest (catalog ), services .realmContext (), services .securityContext ());
12484 }
12585
12686 @ ParameterizedTest
@@ -144,12 +104,14 @@ public void testBasicOverlappingCatalogs(boolean initiallyExternal, boolean late
144104 .returns (Response .Status .CREATED .getStatusCode (), Response ::getStatus );
145105
146106 // inside `root`
147- assertThat (createCatalog (prefix , "root/child" , laterExternal ))
148- .returns (Response .Status .BAD_REQUEST .getStatusCode (), Response ::getStatus );
107+ assertThatThrownBy (() -> createCatalog (prefix , "root/child" , laterExternal ))
108+ .isInstanceOf (ValidationException .class )
109+ .hasMessageContaining ("One or more of its locations overlaps with an existing catalog" );
149110
150111 // `root` is inside this
151- assertThat (createCatalog (prefix , "" , laterExternal ))
152- .returns (Response .Status .BAD_REQUEST .getStatusCode (), Response ::getStatus );
112+ assertThatThrownBy (() -> createCatalog (prefix , "" , laterExternal ))
113+ .isInstanceOf (ValidationException .class )
114+ .hasMessageContaining ("One or more of its locations overlaps with an existing catalog" );
153115 }
154116
155117 @ ParameterizedTest
@@ -166,17 +128,24 @@ public void testAllowedLocationOverlappingCatalogs(
166128 .returns (Response .Status .CREATED .getStatusCode (), Response ::getStatus );
167129
168130 // This DBL overlaps with initial AL
169- assertThat (createCatalog (prefix , "dogs" , initiallyExternal , Arrays .asList ("huskies" , "labs" )))
170- .returns (Response .Status .BAD_REQUEST .getStatusCode (), Response ::getStatus );
131+ assertThatThrownBy (
132+ () ->
133+ createCatalog (prefix , "dogs" , initiallyExternal , Arrays .asList ("huskies" , "labs" )))
134+ .isInstanceOf (ValidationException .class )
135+ .hasMessageContaining ("One or more of its locations overlaps with an existing catalog" );
171136
172137 // This AL overlaps with initial DBL
173- assertThat (
174- createCatalog (
175- prefix , "kingdoms" , initiallyExternal , Arrays .asList ("plants" , "animals" )))
176- .returns (Response .Status .BAD_REQUEST .getStatusCode (), Response ::getStatus );
138+ assertThatThrownBy (
139+ () ->
140+ createCatalog (
141+ prefix , "kingdoms" , initiallyExternal , Arrays .asList ("plants" , "animals" )))
142+ .isInstanceOf (ValidationException .class )
143+ .hasMessageContaining ("One or more of its locations overlaps with an existing catalog" );
177144
178145 // This AL overlaps with an initial AL
179- assertThat (createCatalog (prefix , "plays" , initiallyExternal , Arrays .asList ("rent" , "cats" )))
180- .returns (Response .Status .BAD_REQUEST .getStatusCode (), Response ::getStatus );
146+ assertThatThrownBy (
147+ () -> createCatalog (prefix , "plays" , initiallyExternal , Arrays .asList ("rent" , "cats" )))
148+ .isInstanceOf (ValidationException .class )
149+ .hasMessageContaining ("One or more of its locations overlaps with an existing catalog" );
181150 }
182151}
0 commit comments