@VisibleForTesting
    Map<ResourceUri, ResourceCounter> functionResourceInfos() {
        return functionResourceInfos;
    }
@Test
    void testRegisterFunctionWithResource() {
        ResourceUri resourceUri = new ResourceUri(ResourceType.JAR, udfJar.getPath());
        List<ResourceUri> resourceUris = Collections.singletonList(resourceUri);

        Configuration configuration = new Configuration();
        FunctionCatalog functionCatalog =
                new FunctionCatalog(
                        configuration,
                        resourceManager,
                        CatalogManagerMocks.preparedCatalogManager()
                                .defaultCatalog(
                                        DEFAULT_CATALOG,
                                        new GenericInMemoryCatalog(
                                                DEFAULT_CATALOG, DEFAULT_DATABASE))
                                .build(),
                        new ModuleManager());

        functionCatalog.registerCatalogFunction(
                FULL_UNRESOLVED_IDENTIFIER1, GENERATED_LOWER_UDF_CLASS, resourceUris, false);

        Map<ResourceUri, ResourceManager.ResourceCounter> functionResourceInfos =
                resourceManager.functionResourceInfos();
        // Register catalog function will not register its resource to function resources.
        assertThat(functionResourceInfos.containsKey(resourceUri)).isFalse();
        functionCatalog.dropCatalogFunction(FULL_UNRESOLVED_IDENTIFIER1, false);

        // Register catalog function again to validate that unregister catalog function will not
        // decrease the reference count of resourceUris.
        functionCatalog.registerCatalogFunction(
                FULL_UNRESOLVED_IDENTIFIER1, GENERATED_LOWER_UDF_CLASS, resourceUris, false);
        functionCatalog.registerTemporaryCatalogFunction(
                FULL_UNRESOLVED_IDENTIFIER2,
                new CatalogFunctionImpl(
                        GENERATED_LOWER_UDF_CLASS, FunctionLanguage.JAVA, resourceUris),
                false);
        functionCatalog.registerTemporaryCatalogFunction(
                FULL_UNRESOLVED_IDENTIFIER3,
                new CatalogFunctionImpl(
                        GENERATED_LOWER_UDF_CLASS, FunctionLanguage.JAVA, resourceUris),
                false);
        functionCatalog.registerTemporarySystemFunction(
                GENERATED_LOWER_UDF_CLASS,
                new CatalogFunctionImpl(
                        GENERATED_LOWER_UDF_CLASS, FunctionLanguage.JAVA, resourceUris),
                false);

        // There will be three resources for temporary and system functions without catalog
        // function.
        assertThat(functionResourceInfos.get(resourceUri).counter).isEqualTo(3);
        // Drop catalog function will not decrease the reference count of resourceUris.
        functionCatalog.dropCatalogFunction(FULL_UNRESOLVED_IDENTIFIER1, false);
        // There will be three resources for temporary and system functions.
        assertThat(functionResourceInfos.get(resourceUri).counter).isEqualTo(3);

        functionCatalog.dropTemporaryCatalogFunction(FULL_UNRESOLVED_IDENTIFIER2, false);
        assertThat(functionResourceInfos.get(resourceUri).counter).isEqualTo(2);

        functionCatalog.dropTemporaryCatalogFunction(FULL_UNRESOLVED_IDENTIFIER3, false);
        assertThat(functionResourceInfos.get(resourceUri).counter).isEqualTo(1);

        functionCatalog.dropTemporarySystemFunction(GENERATED_LOWER_UDF_CLASS, false);
        assertThat(functionResourceInfos.containsKey(resourceUri)).isFalse();
    }