-
Notifications
You must be signed in to change notification settings - Fork 297
Fix createViewWithCustomMetadataLocation tests for cloudTest task #2405
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
tmater
wants to merge
3
commits into
apache:main
Choose a base branch
from
tmater:cloud_test_fix
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
@@ -23,13 +23,13 @@ | |||||||||
import com.google.common.collect.ImmutableMap; | ||||||||||
import java.lang.reflect.Method; | ||||||||||
import java.nio.file.Path; | ||||||||||
import java.nio.file.Paths; | ||||||||||
import java.util.Map; | ||||||||||
import org.apache.iceberg.catalog.TableIdentifier; | ||||||||||
import org.apache.iceberg.exceptions.ForbiddenException; | ||||||||||
import org.apache.iceberg.rest.RESTCatalog; | ||||||||||
import org.apache.iceberg.view.BaseView; | ||||||||||
import org.apache.iceberg.view.View; | ||||||||||
import org.apache.iceberg.view.ViewBuilder; | ||||||||||
import org.apache.iceberg.view.ViewCatalogTests; | ||||||||||
import org.apache.polaris.core.admin.model.Catalog; | ||||||||||
import org.apache.polaris.core.admin.model.CatalogProperties; | ||||||||||
|
@@ -45,6 +45,7 @@ | |||||||||
import org.apache.polaris.service.it.env.PolarisApiEndpoints; | ||||||||||
import org.apache.polaris.service.it.env.PolarisClient; | ||||||||||
import org.apache.polaris.service.it.ext.PolarisIntegrationTestExtension; | ||||||||||
import org.assertj.core.api.AbstractBooleanAssert; | ||||||||||
import org.assertj.core.api.Assertions; | ||||||||||
import org.assertj.core.api.Assumptions; | ||||||||||
import org.assertj.core.configuration.PreferredAssumptionException; | ||||||||||
|
@@ -55,7 +56,6 @@ | |||||||||
import org.junit.jupiter.api.Test; | ||||||||||
import org.junit.jupiter.api.TestInfo; | ||||||||||
import org.junit.jupiter.api.extension.ExtendWith; | ||||||||||
import org.junit.jupiter.api.io.TempDir; | ||||||||||
|
||||||||||
/** | ||||||||||
* Import the full core Iceberg catalog tests by hitting the REST service via the RESTCatalog | ||||||||||
|
@@ -86,6 +86,8 @@ public abstract class PolarisRestCatalogViewIntegrationBase extends ViewCatalogT | |||||||||
private static PolarisApiEndpoints endpoints; | ||||||||||
private static PolarisClient client; | ||||||||||
private static ManagementApi managementApi; | ||||||||||
protected static final String POLARIS_IT_SUBDIR = "polaris_it"; | ||||||||||
protected static final String POLARIS_IT_CUSTOM_SUBDIR = "polaris_it_custom"; | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This constant seems unused. |
||||||||||
|
||||||||||
private RESTCatalog restCatalog; | ||||||||||
|
||||||||||
|
@@ -104,8 +106,6 @@ static void close() throws Exception { | |||||||||
|
||||||||||
@BeforeEach | ||||||||||
public void before(TestInfo testInfo) { | ||||||||||
Assumptions.assumeThat(shouldSkip()).isFalse(); | ||||||||||
|
||||||||||
String principalName = client.newEntityName("snowman-rest"); | ||||||||||
String principalRoleName = client.newEntityName("rest-admin"); | ||||||||||
PrincipalWithCredentials principalCredentials = | ||||||||||
|
@@ -157,12 +157,6 @@ public void cleanUp() { | |||||||||
*/ | ||||||||||
protected abstract StorageConfigInfo getStorageConfigInfo(); | ||||||||||
|
||||||||||
/** | ||||||||||
* @return Whether the tests should be skipped, for example due to environment variables not being | ||||||||||
* specified. | ||||||||||
*/ | ||||||||||
protected abstract boolean shouldSkip(); | ||||||||||
|
||||||||||
@Override | ||||||||||
protected RESTCatalog catalog() { | ||||||||||
return restCatalog; | ||||||||||
|
@@ -188,33 +182,89 @@ protected boolean overridesRequestedLocation() { | |||||||||
return true; | ||||||||||
} | ||||||||||
|
||||||||||
@Override | ||||||||||
protected String getCustomMetadataLocationDir() { | ||||||||||
return ""; | ||||||||||
} | ||||||||||
Comment on lines
+185
to
+187
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||
|
||||||||||
@Test | ||||||||||
@Override | ||||||||||
public void createViewWithCustomMetadataLocation() { | ||||||||||
Assertions.assertThatThrownBy(super::createViewWithCustomMetadataLocation) | ||||||||||
TableIdentifier identifier = TableIdentifier.of("ns", "view"); | ||||||||||
String baseLocation = catalog().properties().get(CatalogEntity.DEFAULT_BASE_LOCATION_KEY); | ||||||||||
if (this.requiresNamespaceCreate()) { | ||||||||||
// Use the default baseLocation of the catalog. No "write.metadata.path" set. | ||||||||||
catalog().createNamespace(identifier.namespace()); | ||||||||||
} | ||||||||||
|
||||||||||
// Negative test, we cannot create views outside of base location | ||||||||||
((AbstractBooleanAssert) | ||||||||||
Assertions.assertThat(this.catalog().viewExists(identifier)) | ||||||||||
.as("View should not exist", new Object[0])) | ||||||||||
.isFalse(); | ||||||||||
ViewBuilder viewBuilder = | ||||||||||
catalog() | ||||||||||
.buildView(identifier) | ||||||||||
.withSchema(SCHEMA) | ||||||||||
.withDefaultNamespace(identifier.namespace()) | ||||||||||
.withDefaultCatalog(catalog().name()) | ||||||||||
.withQuery("spark", "select * from ns.tbl") | ||||||||||
.withProperty( | ||||||||||
IcebergTableLikeEntity.USER_SPECIFIED_WRITE_METADATA_LOCATION_KEY, | ||||||||||
getCustomMetadataLocationDir()) | ||||||||||
.withLocation(baseLocation); | ||||||||||
Assertions.assertThatThrownBy(viewBuilder::create) | ||||||||||
.isInstanceOf(ForbiddenException.class) | ||||||||||
.hasMessageContaining("Forbidden: Invalid locations"); | ||||||||||
|
||||||||||
// Positive, we can create views in the default base location's subdirectory | ||||||||||
String baseViewLocation = catalog().properties().get(CatalogEntity.DEFAULT_BASE_LOCATION_KEY); | ||||||||||
String baseCustomWriteMetadataLocation = baseViewLocation + "/custom_location"; | ||||||||||
View view = | ||||||||||
this.catalog() | ||||||||||
.buildView(identifier) | ||||||||||
.withSchema(SCHEMA) | ||||||||||
.withDefaultNamespace(identifier.namespace()) | ||||||||||
.withDefaultCatalog(this.catalog().name()) | ||||||||||
.withQuery("spark", "select * from ns.tbl") | ||||||||||
.withProperty("write.metadata.path", baseCustomWriteMetadataLocation) | ||||||||||
.withLocation(baseViewLocation) | ||||||||||
.create(); | ||||||||||
Assertions.assertThat(view).isNotNull(); | ||||||||||
((AbstractBooleanAssert) | ||||||||||
Assertions.assertThat(this.catalog().viewExists(identifier)) | ||||||||||
.as("View should exist", new Object[0])) | ||||||||||
.isTrue(); | ||||||||||
Assertions.assertThat(view.properties()) | ||||||||||
.containsEntry("write.metadata.path", baseCustomWriteMetadataLocation); | ||||||||||
|
||||||||||
Assertions.assertThat(((BaseView) view).operations().current().metadataFileLocation()) | ||||||||||
.isNotNull(); | ||||||||||
// Normalize paths, remove schema before comparing | ||||||||||
String metadataFileLocationPath = | ||||||||||
Path.of(((BaseView) view).operations().current().metadataFileLocation()).toUri().getPath(); | ||||||||||
String baseCustomWriteMetadataLocationPath = | ||||||||||
Path.of(baseCustomWriteMetadataLocation).toUri().getPath(); | ||||||||||
Assertions.assertThat(metadataFileLocationPath).startsWith(baseCustomWriteMetadataLocationPath); | ||||||||||
} | ||||||||||
|
||||||||||
@Test | ||||||||||
public void createViewWithCustomMetadataLocationUsingPolaris(@TempDir Path tempDir) { | ||||||||||
public void createViewWithCustomMetadataLocationInheritedFromNamespace() { | ||||||||||
TableIdentifier identifier = TableIdentifier.of("ns", "view"); | ||||||||||
|
||||||||||
String location = Paths.get(tempDir.toUri().toString()).toString(); | ||||||||||
String customLocation = Paths.get(tempDir.toUri().toString(), "custom-location").toString(); | ||||||||||
String customLocation2 = Paths.get(tempDir.toUri().toString(), "custom-location2").toString(); | ||||||||||
String customLocationChild = | ||||||||||
Paths.get(tempDir.toUri().toString(), "custom-location/child").toString(); | ||||||||||
|
||||||||||
catalog() | ||||||||||
.createNamespace( | ||||||||||
identifier.namespace(), | ||||||||||
ImmutableMap.of( | ||||||||||
IcebergTableLikeEntity.USER_SPECIFIED_WRITE_METADATA_LOCATION_KEY, location)); | ||||||||||
|
||||||||||
String viewBaseLocation = getCustomMetadataLocationDir(); | ||||||||||
String customWriteMetadataLocation = viewBaseLocation + "/custom-location"; | ||||||||||
String customWriteMetadataLocation2 = viewBaseLocation + "/custom-location2"; | ||||||||||
String customWriteMetadataLocationChild = viewBaseLocation + "/custom-location/child"; | ||||||||||
if (this.requiresNamespaceCreate()) { | ||||||||||
// Views can inherit the namespace's "write.metadata.path" setting in Polaris. | ||||||||||
catalog() | ||||||||||
.createNamespace( | ||||||||||
identifier.namespace(), | ||||||||||
ImmutableMap.of( | ||||||||||
IcebergTableLikeEntity.USER_SPECIFIED_WRITE_METADATA_LOCATION_KEY, | ||||||||||
viewBaseLocation)); | ||||||||||
} | ||||||||||
Assertions.assertThat(catalog().viewExists(identifier)).as("View should not exist").isFalse(); | ||||||||||
|
||||||||||
// CAN create a view with a custom metadata location `baseLocation/customLocation`, | ||||||||||
// CAN create a view with a custom metadata location `viewLocation/customLocation`, | ||||||||||
// as long as the location is within the parent namespace's `write.metadata.path=baseLocation` | ||||||||||
View view = | ||||||||||
catalog() | ||||||||||
|
@@ -224,17 +274,17 @@ public void createViewWithCustomMetadataLocationUsingPolaris(@TempDir Path tempD | |||||||||
.withDefaultCatalog(catalog().name()) | ||||||||||
.withQuery("spark", "select * from ns.tbl") | ||||||||||
.withProperty( | ||||||||||
IcebergTableLikeEntity.USER_SPECIFIED_WRITE_METADATA_LOCATION_KEY, customLocation) | ||||||||||
.withLocation(location) | ||||||||||
IcebergTableLikeEntity.USER_SPECIFIED_WRITE_METADATA_LOCATION_KEY, | ||||||||||
customWriteMetadataLocation) | ||||||||||
.withLocation(viewBaseLocation) | ||||||||||
.create(); | ||||||||||
|
||||||||||
Assertions.assertThat(view).isNotNull(); | ||||||||||
Assertions.assertThat(catalog().viewExists(identifier)).as("View should exist").isTrue(); | ||||||||||
Assertions.assertThat(view.properties()).containsEntry("write.metadata.path", customLocation); | ||||||||||
Assertions.assertThat(view.properties()) | ||||||||||
.containsEntry("write.metadata.path", customWriteMetadataLocation); | ||||||||||
Assertions.assertThat(((BaseView) view).operations().current().metadataFileLocation()) | ||||||||||
.isNotNull() | ||||||||||
.startsWith(customLocation); | ||||||||||
|
||||||||||
.startsWith(customWriteMetadataLocation); | ||||||||||
// CANNOT update the view with a new metadata location `baseLocation/customLocation2`, | ||||||||||
// even though the new location is still under the parent namespace's | ||||||||||
// `write.metadata.path=baseLocation`. | ||||||||||
|
@@ -245,11 +295,10 @@ public void createViewWithCustomMetadataLocationUsingPolaris(@TempDir Path tempD | |||||||||
.updateProperties() | ||||||||||
.set( | ||||||||||
IcebergTableLikeEntity.USER_SPECIFIED_WRITE_METADATA_LOCATION_KEY, | ||||||||||
customLocation2) | ||||||||||
customWriteMetadataLocation2) | ||||||||||
.commit()) | ||||||||||
.isInstanceOf(ForbiddenException.class) | ||||||||||
.hasMessageContaining("Forbidden: Invalid locations"); | ||||||||||
|
||||||||||
// CANNOT update the view with a child metadata location `baseLocation/customLocation/child`, | ||||||||||
// even though it is a subpath of the original view's | ||||||||||
// `write.metadata.path=baseLocation/customLocation`. | ||||||||||
|
@@ -260,7 +309,7 @@ public void createViewWithCustomMetadataLocationUsingPolaris(@TempDir Path tempD | |||||||||
.updateProperties() | ||||||||||
.set( | ||||||||||
IcebergTableLikeEntity.USER_SPECIFIED_WRITE_METADATA_LOCATION_KEY, | ||||||||||
customLocationChild) | ||||||||||
customWriteMetadataLocationChild) | ||||||||||
.commit()) | ||||||||||
.isInstanceOf(ForbiddenException.class) | ||||||||||
.hasMessageContaining("Forbidden: Invalid locations"); | ||||||||||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this be: