Skip to content

Conversation

@gaborkaszab
Copy link
Collaborator

The resource paths used for comparisons in the REST catalog test use different namespace separator than the test REST catalogs. This PR brings them in line.

@github-actions github-actions bot added the core label Dec 9, 2025
@gaborkaszab
Copy link
Collaborator Author

When we get the path in the REST catalog tests we use e.g. TestRESTCatalog.RESOURCE_PATHS that uses %1F as namespace separator. However, the test REST catalog use %2E as NS separator, so verification on paths being called fail if there is a multi-level namespace, or metadata table name involved.
One workaround can be to create a new ResourcePaths instance with the particular NS-separator for each such test (one example is in testNotModified()) but I think it's more future-proof to configure the RESOURCE_PATHS member to use such separator. For instance I ran into this issue when rebasing my freshness-aware loading PR and then some of my path checks started failing.

@gaborkaszab
Copy link
Collaborator Author

cc @nastra as the owner of the configurable namespace separator change

@gaborkaszab gaborkaszab force-pushed the main_namespace_separator_in_rest_catalog_tests branch from 31d1ba0 to 019e40f Compare December 10, 2025 10:26
@gaborkaszab gaborkaszab requested a review from nastra December 10, 2025 10:26
@gaborkaszab gaborkaszab force-pushed the main_namespace_separator_in_rest_catalog_tests branch from 019e40f to bb52da6 Compare December 10, 2025 12:42
catalog.createTable(table, SCHEMA);

ResourcePaths paths = ResourcePaths.forCatalogProperties(ImmutableMap.of());
assertThat(paths.tables(ns))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it seems like what you're really trying to test is

  @Test
  public void nestedNamespaceWithLegacyAndNewSeparator() {
    Namespace namespace = Namespace.of("first", "second", "third");
    String legacySeparator = RESTUtil.NAMESPACE_SEPARATOR_URLENCODED_UTF_8;
    String newSeparator = "%2E";

    // legacy separator is always used by default, so no need to configure it
    ResourcePaths withLegacySeparator = ResourcePaths.forCatalogProperties(ImmutableMap.of());
    ResourcePaths withNewSeparator =
        ResourcePaths.forCatalogProperties(
            ImmutableMap.of(RESTCatalogProperties.NAMESPACE_SEPARATOR, newSeparator));

    // old client would call encodeNamespace without specifying a separator when constructing a
    // resource path
    String legacyEncodedNamespace = RESTUtil.encodeNamespace(namespace);
    assertThat(withLegacySeparator.namespace(namespace))
        .contains(legacyEncodedNamespace)
        .contains(legacySeparator);

    // old client would decode without specifying the separator
    assertThat(RESTUtil.decodeNamespace(legacyEncodedNamespace)).isEqualTo(namespace);

    // new server would decode the namespace using the new separator
    assertThat(RESTUtil.decodeNamespace(legacyEncodedNamespace, newSeparator)).isEqualTo(namespace);

    // new client would call encodeNamespace with specifying a separator when constructing a
    // resource path
    String newEncodedSeparator = RESTUtil.encodeNamespace(namespace, newSeparator);
    assertThat(withNewSeparator.namespace(namespace))
        .contains(newEncodedSeparator)
        .contains(newSeparator);

    // new server would decode the namespace using the new separator
    assertThat(RESTUtil.decodeNamespace(newEncodedSeparator, newSeparator)).isEqualTo(namespace);
  }

In that case the test should probably live in TestResourcePaths

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gaborkaszab can you also add ^ to TestResourcePaths

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure. I've split this into 2

@gaborkaszab gaborkaszab force-pushed the main_namespace_separator_in_rest_catalog_tests branch from bb52da6 to b6da4d9 Compare December 12, 2025 10:02

RESTCatalog catalog = catalog(adapter);

// Do verification with paths using the default namespace separator.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Do verification with paths using the default namespace separator.
// Do verification with paths using the legacy namespace separator.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In fact with the suggested naming, I think this comment is redundant, so I'm removing it.


@Test
public void testClientNamespaceSeparatorOverridden() {
RESTCatalogAdapter adapter = Mockito.spy(new RESTCatalogAdapter(backendCatalog));
Copy link
Contributor

Choose a reason for hiding this comment

The 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

Copy link
Collaborator Author

Choose a reason for hiding this comment

The 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


catalog.createNamespace(nestedNamespace);

catalog.createTable(table, SCHEMA);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we don't really need the table creation here

Copy link
Collaborator Author

Choose a reason for hiding this comment

The 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.

@gaborkaszab gaborkaszab force-pushed the main_namespace_separator_in_rest_catalog_tests branch from b6da4d9 to 8c040b8 Compare December 12, 2025 10:37
ConfigResponse configResponse = (ConfigResponse) invocation.callRealMethod();

assertThat(configResponse.overrides())
.contains(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can just use containsEntry(...) directly here

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

The resource paths used for comparisons in the REST catalog test use
different namespace separator than the test REST catalogs. This PR
brings them in line.
@gaborkaszab gaborkaszab force-pushed the main_namespace_separator_in_rest_catalog_tests branch from 8c040b8 to d379d99 Compare December 12, 2025 14:19
Copy link
Collaborator Author

@gaborkaszab gaborkaszab left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for looking, @nastra !

ConfigResponse configResponse = (ConfigResponse) invocation.callRealMethod();

assertThat(configResponse.overrides())
.contains(
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done


RESTCatalog catalog = catalog(adapter);

// Do verification with paths using the default namespace separator.
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In fact with the suggested naming, I think this comment is redundant, so I'm removing it.

catalog.createTable(table, SCHEMA);

ResourcePaths paths = ResourcePaths.forCatalogProperties(ImmutableMap.of());
assertThat(paths.tables(ns))
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure. I've split this into 2

@nastra nastra merged commit bc23a77 into apache:main Dec 13, 2025
44 checks passed
@gaborkaszab
Copy link
Collaborator Author

Thanks for reviewing, @nastra !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants