-
Notifications
You must be signed in to change notification settings - Fork 3k
Core: Adjust namespace separator in TestRESTCatalog #14808
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
Changes from all commits
d379d99
0e26d23
4ca1294
b8c26de
e82ee75
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -118,7 +118,10 @@ | |
| public class TestRESTCatalog extends CatalogTests<RESTCatalog> { | ||
| private static final ObjectMapper MAPPER = RESTObjectMapper.mapper(); | ||
| private static final ResourcePaths RESOURCE_PATHS = | ||
| ResourcePaths.forCatalogProperties(Maps.newHashMap()); | ||
| ResourcePaths.forCatalogProperties( | ||
| ImmutableMap.of( | ||
| RESTCatalogProperties.NAMESPACE_SEPARATOR, | ||
| RESTCatalogAdapter.NAMESPACE_SEPARATOR_URLENCODED_UTF_8)); | ||
|
|
||
| @TempDir public Path temp; | ||
|
|
||
|
|
@@ -944,8 +947,6 @@ public void testTableSnapshotLoading() { | |
| .build()) | ||
| .commit(); | ||
|
|
||
| ResourcePaths paths = ResourcePaths.forCatalogProperties(Maps.newHashMap()); | ||
|
|
||
| Table refsTable = catalog.loadTable(TABLE); | ||
|
|
||
| // don't call snapshots() directly as that would cause to load all snapshots. Instead, | ||
|
|
@@ -960,7 +961,8 @@ public void testTableSnapshotLoading() { | |
| // verify that the table was loaded with the refs argument | ||
| verify(adapter, times(1)) | ||
| .execute( | ||
| reqMatcher(HTTPMethod.GET, paths.table(TABLE), Map.of(), Map.of("snapshots", "refs")), | ||
| reqMatcher( | ||
| HTTPMethod.GET, RESOURCE_PATHS.table(TABLE), Map.of(), Map.of("snapshots", "refs")), | ||
| eq(LoadTableResponse.class), | ||
| any(), | ||
| any()); | ||
|
|
@@ -969,7 +971,8 @@ public void testTableSnapshotLoading() { | |
| assertThat(refsTable.snapshots()).containsExactlyInAnyOrderElementsOf(table.snapshots()); | ||
| verify(adapter, times(1)) | ||
| .execute( | ||
| reqMatcher(HTTPMethod.GET, paths.table(TABLE), Map.of(), Map.of("snapshots", "all")), | ||
| reqMatcher( | ||
| HTTPMethod.GET, RESOURCE_PATHS.table(TABLE), Map.of(), Map.of("snapshots", "all")), | ||
| eq(LoadTableResponse.class), | ||
| any(), | ||
| any()); | ||
|
|
@@ -1038,8 +1041,6 @@ public void testTableSnapshotLoadingWithDivergedBranches(String formatVersion) { | |
| .toBranch(branch) | ||
| .commit(); | ||
|
|
||
| ResourcePaths paths = ResourcePaths.forCatalogProperties(Maps.newHashMap()); | ||
|
|
||
| Table refsTable = catalog.loadTable(TABLE); | ||
|
|
||
| // don't call snapshots() directly as that would cause to load all snapshots. Instead, | ||
|
|
@@ -1054,7 +1055,8 @@ public void testTableSnapshotLoadingWithDivergedBranches(String formatVersion) { | |
| // verify that the table was loaded with the refs argument | ||
| verify(adapter, times(1)) | ||
| .execute( | ||
| reqMatcher(HTTPMethod.GET, paths.table(TABLE), Map.of(), Map.of("snapshots", "refs")), | ||
| reqMatcher( | ||
| HTTPMethod.GET, RESOURCE_PATHS.table(TABLE), Map.of(), Map.of("snapshots", "refs")), | ||
| eq(LoadTableResponse.class), | ||
| any(), | ||
| any()); | ||
|
|
@@ -1064,7 +1066,8 @@ public void testTableSnapshotLoadingWithDivergedBranches(String formatVersion) { | |
| .containsExactlyInAnyOrderElementsOf(table.snapshots()); | ||
| verify(adapter, times(1)) | ||
| .execute( | ||
| reqMatcher(HTTPMethod.GET, paths.table(TABLE), Map.of(), Map.of("snapshots", "all")), | ||
| reqMatcher( | ||
| HTTPMethod.GET, RESOURCE_PATHS.table(TABLE), Map.of(), Map.of("snapshots", "all")), | ||
| eq(LoadTableResponse.class), | ||
| any(), | ||
| any()); | ||
|
|
@@ -2956,14 +2959,12 @@ public void testNotModified() { | |
| any(), | ||
| any()); | ||
|
|
||
| // RESTCatalogAdapter uses %2E as a namespace separator, and we're verifying here which | ||
| // server-side path was called | ||
| ResourcePaths paths = | ||
| ResourcePaths.forCatalogProperties( | ||
| ImmutableMap.of(RESTCatalogProperties.NAMESPACE_SEPARATOR, "%2E")); | ||
| verify(adapterForRESTServer) | ||
| .execute( | ||
| reqMatcher(HTTPMethod.GET, paths.table(metadataTableIdentifier)), any(), any(), any()); | ||
| reqMatcher(HTTPMethod.GET, RESOURCE_PATHS.table(metadataTableIdentifier)), | ||
| any(), | ||
| any(), | ||
| any()); | ||
| } | ||
|
|
||
| @Test | ||
|
|
@@ -3311,6 +3312,111 @@ public void testClientDoesNotSendIdempotencyWhenServerNotAdvertising() { | |
| local.dropTable(ident); | ||
| } | ||
|
|
||
| @Test | ||
| public void nestedNamespaceWithLegacySeparator() { | ||
| RESTCatalogAdapter adapter = Mockito.spy(new RESTCatalogAdapter(backendCatalog)); | ||
|
|
||
| // Simulate that the server doesn't send the namespace separator in the overrides | ||
| Mockito.doAnswer( | ||
| invocation -> { | ||
| ConfigResponse configResponse = (ConfigResponse) invocation.callRealMethod(); | ||
|
|
||
| Map<String, String> overridesWithoutNamespaceSeparator = configResponse.overrides(); | ||
| overridesWithoutNamespaceSeparator.remove(RESTCatalogProperties.NAMESPACE_SEPARATOR); | ||
nastra marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| return ConfigResponse.builder() | ||
| .withDefaults(configResponse.defaults()) | ||
| .withOverrides(overridesWithoutNamespaceSeparator) | ||
| .withEndpoints(configResponse.endpoints()) | ||
| .withIdempotencyKeyLifetime(configResponse.idempotencyKeyLifetime()) | ||
| .build(); | ||
| }) | ||
| .when(adapter) | ||
| .execute( | ||
| reqMatcher(HTTPMethod.GET, ResourcePaths.config()), | ||
| eq(ConfigResponse.class), | ||
| any(), | ||
| any()); | ||
|
|
||
| RESTCatalog catalog = catalog(adapter); | ||
|
|
||
| ResourcePaths pathsWithLegacySeparator = ResourcePaths.forCatalogProperties(ImmutableMap.of()); | ||
|
|
||
| runConfigurableNamespaceSeparatorTest( | ||
| catalog, adapter, pathsWithLegacySeparator, RESTUtil.NAMESPACE_SEPARATOR_URLENCODED_UTF_8); | ||
| } | ||
|
|
||
| @Test | ||
| public void nestedNamespaceWithOverriddenSeparator() { | ||
| RESTCatalogAdapter adapter = Mockito.spy(new RESTCatalogAdapter(backendCatalog)); | ||
|
Contributor
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. you might want to add a comment that says that the server now always sends back the separator in the config response so that this is clear here
Collaborator
Author
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. Done. I added an extra check also to verify the override is sent by the adapter. Makes the test more future proof, however, this may be an overkill. Let me know and I'll remove the check |
||
|
|
||
| // When initializing the catalog, the adapter always sends an override for the namespace | ||
| // separator. | ||
| Mockito.doAnswer( | ||
| invocation -> { | ||
| ConfigResponse configResponse = (ConfigResponse) invocation.callRealMethod(); | ||
|
|
||
| assertThat(configResponse.overrides()) | ||
| .containsEntry( | ||
| RESTCatalogProperties.NAMESPACE_SEPARATOR, | ||
| RESTCatalogAdapter.NAMESPACE_SEPARATOR_URLENCODED_UTF_8); | ||
|
|
||
| return configResponse; | ||
| }) | ||
| .when(adapter) | ||
| .execute( | ||
| reqMatcher(HTTPMethod.GET, ResourcePaths.config()), | ||
| eq(ConfigResponse.class), | ||
| any(), | ||
| any()); | ||
|
|
||
| RESTCatalog catalog = catalog(adapter); | ||
|
|
||
| runConfigurableNamespaceSeparatorTest( | ||
| catalog, adapter, RESOURCE_PATHS, RESTCatalogAdapter.NAMESPACE_SEPARATOR_URLENCODED_UTF_8); | ||
| } | ||
|
|
||
| private void runConfigurableNamespaceSeparatorTest( | ||
| RESTCatalog catalog, | ||
| RESTCatalogAdapter adapter, | ||
| ResourcePaths expectedPaths, | ||
| String expectedSeparator) { | ||
| Namespace nestedNamespace = Namespace.of("ns1", "ns2", "ns3"); | ||
| Namespace parentNamespace = Namespace.of("ns1", "ns2"); | ||
| TableIdentifier table = TableIdentifier.of(nestedNamespace, "tbl"); | ||
|
|
||
| catalog.createNamespace(nestedNamespace); | ||
|
|
||
| catalog.createTable(table, SCHEMA); | ||
|
Contributor
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. we don't really need the table creation here
Collaborator
Author
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. I use this so that I can also verify that the paths use the desired namespace separators. I know you've commented that it rather belongs to TestResourcePaths, but in general I think whenever an end-to-end scenario is easy to do, it makes sense to add test coverage there (besides narrower unit testing). In this case it's pretty simple to cover, and add more test coverage not just to ResourcePaths but also to the RESTCatalog code around creating and using the paths. This gives use more complete tests here: the paths and the params together. |
||
|
|
||
| assertThat(catalog.listNamespaces(parentNamespace)).containsExactly(nestedNamespace); | ||
|
|
||
| // Verify the namespace separator in the path | ||
| Mockito.verify(adapter) | ||
| .execute( | ||
| reqMatcher(HTTPMethod.POST, expectedPaths.tables(nestedNamespace)), | ||
| eq(LoadTableResponse.class), | ||
| any(), | ||
| any()); | ||
|
|
||
| // Verify the namespace separator in query parameters | ||
| Mockito.verify(adapter) | ||
| .execute( | ||
| reqMatcher( | ||
| HTTPMethod.GET, | ||
| expectedPaths.namespaces(), | ||
| Map.of(), | ||
| Map.of( | ||
| "parent", | ||
| RESTUtil.namespaceToQueryParam(parentNamespace, expectedSeparator), | ||
| "pageToken", | ||
| ""), | ||
| null), | ||
| eq(ListNamespacesResponse.class), | ||
| any(), | ||
| any()); | ||
| } | ||
|
|
||
| private RESTCatalog createCatalogWithIdempAdapter(ConfigResponse cfg, boolean expectOnMutations) { | ||
| RESTCatalogAdapter adapter = | ||
| Mockito.spy( | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.