This is an automated email from the ASF dual-hosted git repository.

sandynz pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shardingsphere.git


The following commit(s) were added to refs/heads/master by this push:
     new 681fa8cbce1 Support native storage connection customization in E2E 
(#39086)
681fa8cbce1 is described below

commit 681fa8cbce1f7b9d4a05f9bd68d65ca1f67f21c8
Author: Hongsheng Zhong <[email protected]>
AuthorDate: Mon Jul 13 19:45:19 2026 +0800

    Support native storage connection customization in E2E (#39086)
---
 .../impl/ShardingSphereProxyEmbeddedContainer.java |  26 +++--
 .../option/NativeStorageContainerOption.java       | 107 +++++++++++++++++++++
 .../option/NativeStorageContainerOptionTest.java   |  72 ++++++++++++++
 .../storage/type/NativeStorageContainer.java       |  46 +++++++--
 .../pipeline/cases/PipelineContainerComposer.java  |   8 +-
 ...aclePipelineNativeContainerDropTableOption.java |   8 +-
 ...PipelineNativeContainerDropTableOptionTest.java |  66 +++++++++++++
 7 files changed, 311 insertions(+), 22 deletions(-)

diff --git 
a/test/e2e/env/src/test/java/org/apache/shardingsphere/test/e2e/env/container/adapter/impl/ShardingSphereProxyEmbeddedContainer.java
 
b/test/e2e/env/src/test/java/org/apache/shardingsphere/test/e2e/env/container/adapter/impl/ShardingSphereProxyEmbeddedContainer.java
index 8e95cc4685d..5083042d5db 100644
--- 
a/test/e2e/env/src/test/java/org/apache/shardingsphere/test/e2e/env/container/adapter/impl/ShardingSphereProxyEmbeddedContainer.java
+++ 
b/test/e2e/env/src/test/java/org/apache/shardingsphere/test/e2e/env/container/adapter/impl/ShardingSphereProxyEmbeddedContainer.java
@@ -38,6 +38,7 @@ import 
org.apache.shardingsphere.test.e2e.env.container.adapter.AdapterContainer
 import 
org.apache.shardingsphere.test.e2e.env.container.adapter.config.AdaptorContainerConfiguration;
 import 
org.apache.shardingsphere.test.e2e.env.container.constants.ProxyContainerConstants;
 import 
org.apache.shardingsphere.test.e2e.env.container.constants.StorageContainerConstants;
+import 
org.apache.shardingsphere.test.e2e.env.container.storage.StorageContainer;
 import 
org.apache.shardingsphere.test.e2e.env.container.storage.option.StorageContainerConnectOption;
 import 
org.apache.shardingsphere.test.e2e.env.container.storage.option.StorageContainerOption;
 import 
org.apache.shardingsphere.test.e2e.env.container.storage.type.NativeStorageContainer;
@@ -59,15 +60,14 @@ import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.sql.SQLException;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.HashSet;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Objects;
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicReference;
-import java.util.stream.Collectors;
 
 /**
  * ShardingSphere proxy embedded container.
@@ -159,26 +159,29 @@ public final class ShardingSphereProxyEmbeddedContainer 
implements EmbeddedE2ECo
     }
     
     private Map<String, String> getNetworkAliasAndHostLinkMap() {
-        Map<String, String> result = new HashMap<>();
+        Map<String, String> result = new LinkedHashMap<>();
         for (Startable each : dependencies) {
             if (each instanceof GenericContainer) {
                 
result.putAll(getNetworkAliasAndHostLinkMap((GenericContainer<?>) each));
+            } else if (each instanceof StorageContainer) {
+                result.putAll(((StorageContainer) each).getLinkReplacements());
             }
         }
         return result;
     }
     
     private Map<String, String> getNetworkAliasAndHostLinkMap(final 
GenericContainer<?> genericContainer) {
-        Map<String, String> result = new HashMap<>();
+        Map<String, String> result = new LinkedHashMap<>();
         for (String each : genericContainer.getNetworkAliases()) {
-            result.putAll(genericContainer.getExposedPorts().stream()
-                    .collect(Collectors.toMap(exposedPort -> each + ":" + 
exposedPort, exposedPort -> "127.0.0.1:" + 
genericContainer.getMappedPort(exposedPort))));
+            for (Integer exposedPort : genericContainer.getExposedPorts()) {
+                result.put(each + ":" + exposedPort, "127.0.0.1:" + 
genericContainer.getMappedPort(exposedPort));
+            }
         }
         return result;
     }
     
     private Map<String, String> getStorageConnectionInfoMap() {
-        Map<String, String> result = new HashMap<>();
+        Map<String, String> result = new LinkedHashMap<>();
         for (Startable each : dependencies) {
             if (each instanceof NativeStorageContainer) {
                 
result.putAll(getStorageConnectionInfoMap((NativeStorageContainer) each));
@@ -190,9 +193,12 @@ public final class ShardingSphereProxyEmbeddedContainer 
implements EmbeddedE2ECo
     }
     
     private Map<String, String> getStorageConnectionInfoMap(final 
NativeStorageContainer container) {
-        return container.getNetworkAliases().stream().collect(Collectors.toMap(
-                each -> each + ":" + container.getExposedPort(),
-                each -> 
E2ETestEnvironment.getInstance().getNativeDatabaseEnvironment().getHost() + ":" 
+ 
E2ETestEnvironment.getInstance().getNativeDatabaseEnvironment().getPort(databaseType)));
+        Map<String, String> result = new LinkedHashMap<>();
+        for (String each : container.getNetworkAliases()) {
+            result.put(each + ":" + container.getExposedPort(), 
E2ETestEnvironment.getInstance().getNativeDatabaseEnvironment().getHost() + ":"
+                    + 
E2ETestEnvironment.getInstance().getNativeDatabaseEnvironment().getPort(container.getDatabaseType()));
+        }
+        return result;
     }
     
     private File createTempDirectory() {
diff --git 
a/test/e2e/env/src/test/java/org/apache/shardingsphere/test/e2e/env/container/storage/option/NativeStorageContainerOption.java
 
b/test/e2e/env/src/test/java/org/apache/shardingsphere/test/e2e/env/container/storage/option/NativeStorageContainerOption.java
new file mode 100644
index 00000000000..75b6594b2b5
--- /dev/null
+++ 
b/test/e2e/env/src/test/java/org/apache/shardingsphere/test/e2e/env/container/storage/option/NativeStorageContainerOption.java
@@ -0,0 +1,107 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.test.e2e.env.container.storage.option;
+
+import com.zaxxer.hikari.HikariDataSource;
+import org.apache.shardingsphere.database.connector.core.spi.DatabaseTypedSPI;
+import org.apache.shardingsphere.infra.spi.annotation.SingletonSPI;
+
+import java.util.Collections;
+import java.util.Map;
+
+/**
+ * Native storage container option.
+ */
+@SingletonSPI
+public interface NativeStorageContainerOption extends DatabaseTypedSPI {
+    
+    /**
+     * Get native storage major version for initialization resource selection.
+     *
+     * @return major version
+     */
+    int getMajorVersion();
+    
+    /**
+     * Get native storage initialization user.
+     *
+     * @param configuredUser configured user
+     * @return initialization user
+     */
+    default String getInitUser(final String configuredUser) {
+        return configuredUser;
+    }
+    
+    /**
+     * Configure native storage initialization data source.
+     *
+     * @param dataSource data source
+     */
+    default void configureInitDataSource(final HikariDataSource dataSource) {
+    }
+    
+    /**
+     * Get native storage initialization URL.
+     *
+     * @param connectOption storage connect option
+     * @param host database host
+     * @param port database port
+     * @return initialization URL
+     */
+    default String getInitURL(final StorageContainerConnectOption 
connectOption, final String host, final int port) {
+        return connectOption.getURL(host, port);
+    }
+    
+    /**
+     * Get native storage access URL.
+     *
+     * @param connectOption storage connect option
+     * @param host database host
+     * @param port database port
+     * @param dataSourceName data source name
+     * @return access URL
+     */
+    default String getAccessURL(final StorageContainerConnectOption 
connectOption, final String host, final int port, final String dataSourceName) {
+        return null == dataSourceName || dataSourceName.isEmpty() ? 
connectOption.getURL(host, port) : connectOption.getURL(host, port, 
dataSourceName);
+    }
+    
+    /**
+     * Configure native storage access data source.
+     *
+     * @param dataSource data source
+     * @param dataSourceName data source name
+     */
+    default void configureAccessDataSource(final HikariDataSource dataSource, 
final String dataSourceName) {
+    }
+    
+    /**
+     * Get native storage link replacements.
+     *
+     * <p>The iteration order defines replacement precedence, so 
implementations should put more specific replacements before general 
replacements.</p>
+     *
+     * @param connectOption storage connect option
+     * @param networkAlias network alias
+     * @param host database host
+     * @param port database port
+     * @param exposedPort exposed port in configuration resources
+     * @return link replacements
+     */
+    default Map<String, String> getLinkReplacements(final 
StorageContainerConnectOption connectOption, final String networkAlias, final 
String host, final int port, final int exposedPort) {
+        return Collections.singletonMap(networkAlias + ":" + exposedPort, host 
+ ":" + port);
+    }
+}
diff --git 
a/test/e2e/env/src/test/java/org/apache/shardingsphere/test/e2e/env/container/storage/option/NativeStorageContainerOptionTest.java
 
b/test/e2e/env/src/test/java/org/apache/shardingsphere/test/e2e/env/container/storage/option/NativeStorageContainerOptionTest.java
new file mode 100644
index 00000000000..157a39b24d5
--- /dev/null
+++ 
b/test/e2e/env/src/test/java/org/apache/shardingsphere/test/e2e/env/container/storage/option/NativeStorageContainerOptionTest.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.test.e2e.env.container.storage.option;
+
+import org.junit.jupiter.api.Test;
+
+import java.util.Collections;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+class NativeStorageContainerOptionTest {
+    
+    private final NativeStorageContainerOption option = new 
FixtureNativeStorageContainerOption();
+    
+    @Test
+    void assertGetInitURL() {
+        StorageContainerConnectOption connectOption = 
mock(StorageContainerConnectOption.class);
+        when(connectOption.getURL("127.0.0.1", 
3306)).thenReturn("jdbc:fixture://127.0.0.1:3306");
+        assertThat(option.getInitURL(connectOption, "127.0.0.1", 3306), 
is("jdbc:fixture://127.0.0.1:3306"));
+    }
+    
+    @Test
+    void assertGetAccessURL() {
+        StorageContainerConnectOption connectOption = 
mock(StorageContainerConnectOption.class);
+        when(connectOption.getURL("127.0.0.1", 3306, 
"foo_ds")).thenReturn("jdbc:fixture://127.0.0.1:3306/foo_ds");
+        assertThat(option.getAccessURL(connectOption, "127.0.0.1", 3306, 
"foo_ds"), is("jdbc:fixture://127.0.0.1:3306/foo_ds"));
+    }
+    
+    @Test
+    void assertGetAccessURLWithoutDataSourceName() {
+        StorageContainerConnectOption connectOption = 
mock(StorageContainerConnectOption.class);
+        when(connectOption.getURL("127.0.0.1", 
3306)).thenReturn("jdbc:fixture://127.0.0.1:3306");
+        assertThat(option.getAccessURL(connectOption, "127.0.0.1", 3306, ""), 
is("jdbc:fixture://127.0.0.1:3306"));
+    }
+    
+    @Test
+    void assertGetLinkReplacements() {
+        
assertThat(option.getLinkReplacements(mock(StorageContainerConnectOption.class),
 "fixture.host", "127.0.0.1", 3307, 3306),
+                is(Collections.singletonMap("fixture.host:3306", 
"127.0.0.1:3307")));
+    }
+    
+    private static final class FixtureNativeStorageContainerOption implements 
NativeStorageContainerOption {
+        
+        @Override
+        public int getMajorVersion() {
+            return 0;
+        }
+        
+        @Override
+        public String getDatabaseType() {
+            return "Fixture";
+        }
+    }
+}
diff --git 
a/test/e2e/env/src/test/java/org/apache/shardingsphere/test/e2e/env/container/storage/type/NativeStorageContainer.java
 
b/test/e2e/env/src/test/java/org/apache/shardingsphere/test/e2e/env/container/storage/type/NativeStorageContainer.java
index 9b4653e4aaf..1d8ad30e109 100644
--- 
a/test/e2e/env/src/test/java/org/apache/shardingsphere/test/e2e/env/container/storage/type/NativeStorageContainer.java
+++ 
b/test/e2e/env/src/test/java/org/apache/shardingsphere/test/e2e/env/container/storage/type/NativeStorageContainer.java
@@ -17,12 +17,14 @@
 
 package org.apache.shardingsphere.test.e2e.env.container.storage.type;
 
+import com.zaxxer.hikari.HikariDataSource;
 import lombok.Getter;
 import lombok.Setter;
 import 
org.apache.shardingsphere.database.connector.core.spi.DatabaseTypedSPILoader;
 import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
 import 
org.apache.shardingsphere.test.e2e.env.container.storage.StorageContainer;
 import 
org.apache.shardingsphere.test.e2e.env.container.storage.mount.MountSQLResourceGenerator;
+import 
org.apache.shardingsphere.test.e2e.env.container.storage.option.NativeStorageContainerOption;
 import 
org.apache.shardingsphere.test.e2e.env.container.storage.option.StorageContainerOption;
 import org.apache.shardingsphere.test.e2e.env.container.util.SQLScriptUtils;
 import 
org.apache.shardingsphere.test.e2e.env.container.util.StorageContainerUtils;
@@ -34,11 +36,11 @@ import 
org.apache.shardingsphere.test.e2e.env.runtime.type.scenario.path.Scenari
 import javax.sql.DataSource;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Optional;
 
 /**
  * Native storage container.
@@ -58,6 +60,8 @@ public final class NativeStorageContainer implements 
StorageContainer {
     
     private final StorageContainerOption option;
     
+    private final NativeStorageContainerOption nativeOption;
+    
     @Getter
     private final Map<String, DataSource> actualDataSourceMap;
     
@@ -73,6 +77,7 @@ public final class NativeStorageContainer implements 
StorageContainer {
         this.databaseType = databaseType;
         this.scenario = scenario;
         option = 
DatabaseTypedSPILoader.findService(StorageContainerOption.class, 
databaseType).orElse(null);
+        nativeOption = 
DatabaseTypedSPILoader.findService(NativeStorageContainerOption.class, 
databaseType).orElse(null);
         initDatabase();
         actualDataSourceMap = createDataSourceMap(Type.ACTUAL);
         expectedDataSourceMap = createDataSourceMap(Type.EXPECTED);
@@ -98,7 +103,11 @@ public final class NativeStorageContainer implements 
StorageContainer {
     }
     
     private Map<String, String> generateMountedResources() {
-        return new MountSQLResourceGenerator(option.getType(), 
option.getCreateOption()).generate(getDefaultMajorVersion(), scenario);
+        return new MountSQLResourceGenerator(option.getType(), 
option.getCreateOption()).generate(getMajorVersion(), scenario);
+    }
+    
+    private int getMajorVersion() {
+        return 
Optional.ofNullable(nativeOption).map(NativeStorageContainerOption::getMajorVersion).orElseGet(this::getDefaultMajorVersion);
     }
     
     private int getDefaultMajorVersion() {
@@ -115,16 +124,20 @@ public final class NativeStorageContainer implements 
StorageContainer {
     }
     
     private DataSource createInitDataSource() {
-        return 
StorageContainerUtils.generateDataSource(option.getConnectOption().getURL(env.getHost(),
 env.getPort(databaseType)),
-                getInitUser(), env.getPassword(), 2);
+        String jdbcUrl = Optional.ofNullable(nativeOption)
+                .map(optional -> 
optional.getInitURL(option.getConnectOption(), env.getHost(), 
env.getPort(databaseType)))
+                .orElseGet(() -> 
option.getConnectOption().getURL(env.getHost(), env.getPort(databaseType)));
+        HikariDataSource result = (HikariDataSource) 
StorageContainerUtils.generateDataSource(jdbcUrl, getInitUser(), 
env.getPassword(), 2);
+        Optional.ofNullable(nativeOption).ifPresent(optional -> 
optional.configureInitDataSource(result));
+        return result;
     }
     
     private String getInitUser() {
-        return env.getUser();
+        return Optional.ofNullable(nativeOption).map(optional -> 
optional.getInitUser(env.getUser())).orElseGet(env::getUser);
     }
     
     private String getInitDatabaseCacheKey() {
-        return String.join(":", String.valueOf(scenario), 
databaseType.getType(), env.getHost(), 
String.valueOf(env.getPort(databaseType)), 
String.valueOf(getDefaultMajorVersion()));
+        return String.join(":", String.valueOf(scenario), 
databaseType.getType(), env.getHost(), 
String.valueOf(env.getPort(databaseType)), String.valueOf(getMajorVersion()));
     }
     
     private Map<String, DataSource> createDataSourceMap(final Type type) {
@@ -134,13 +147,24 @@ public final class NativeStorageContainer implements 
StorageContainer {
     private Map<String, DataSource> getDataSourceMap(final Collection<String> 
databaseNames) {
         Map<String, DataSource> result = new 
LinkedHashMap<>(databaseNames.size(), 1F);
         for (String each : databaseNames) {
-            DataSource dataSource = 
StorageContainerUtils.generateDataSource(option.getConnectOption().getURL(env.getHost(),
 env.getPort(databaseType), each),
-                    env.getUser(), env.getPassword(), 2);
+            DataSource dataSource = 
StorageContainerUtils.generateDataSource(getAccessURL(each), env.getUser(), 
env.getPassword(), 2);
+            initNativeDataSource(each, dataSource);
             result.put(each, dataSource);
         }
         return result;
     }
     
+    private String getAccessURL(final String dataSourceName) {
+        return Optional.ofNullable(nativeOption).map(optional -> 
optional.getAccessURL(option.getConnectOption(), env.getHost(), 
env.getPort(databaseType), dataSourceName))
+                .orElseGet(() -> null == dataSourceName || 
dataSourceName.isEmpty()
+                        ? option.getConnectOption().getURL(env.getHost(), 
env.getPort(databaseType))
+                        : option.getConnectOption().getURL(env.getHost(), 
env.getPort(databaseType), dataSourceName));
+    }
+    
+    private void initNativeDataSource(final String dataSourceName, final 
DataSource dataSource) {
+        Optional.ofNullable(nativeOption).ifPresent(optional -> 
optional.configureAccessDataSource((HikariDataSource) dataSource, 
dataSourceName));
+    }
+    
     /**
      * Get exposed port.
      *
@@ -161,9 +185,11 @@ public final class NativeStorageContainer implements 
StorageContainer {
     
     @Override
     public Map<String, String> getLinkReplacements() {
-        Map<String, String> result = new HashMap<>(getNetworkAliases().size() 
+ 2, 1F);
+        Map<String, String> result = new 
LinkedHashMap<>(getNetworkAliases().size() + 2, 1F);
         for (String each : getNetworkAliases()) {
-            result.put(each + ":" + getExposedPort(), env.getHost() + ":" + 
env.getPort(databaseType));
+            result.putAll(Optional.ofNullable(nativeOption)
+                    .map(optional -> 
optional.getLinkReplacements(option.getConnectOption(), each, env.getHost(), 
env.getPort(databaseType), getExposedPort()))
+                    .orElseGet(() -> Collections.singletonMap(each + ":" + 
getExposedPort(), env.getHost() + ":" + env.getPort(databaseType))));
         }
         return result;
     }
diff --git 
a/test/e2e/operation/pipeline/src/test/java/org/apache/shardingsphere/test/e2e/operation/pipeline/cases/PipelineContainerComposer.java
 
b/test/e2e/operation/pipeline/src/test/java/org/apache/shardingsphere/test/e2e/operation/pipeline/cases/PipelineContainerComposer.java
index b528999ce24..55c0ef7f1dd 100644
--- 
a/test/e2e/operation/pipeline/src/test/java/org/apache/shardingsphere/test/e2e/operation/pipeline/cases/PipelineContainerComposer.java
+++ 
b/test/e2e/operation/pipeline/src/test/java/org/apache/shardingsphere/test/e2e/operation/pipeline/cases/PipelineContainerComposer.java
@@ -44,6 +44,7 @@ import 
org.apache.shardingsphere.infra.yaml.config.pojo.YamlRootConfiguration;
 import 
org.apache.shardingsphere.single.yaml.config.YamlSingleRuleConfiguration;
 import 
org.apache.shardingsphere.test.e2e.env.container.constants.ProxyContainerConstants;
 import 
org.apache.shardingsphere.test.e2e.env.container.constants.StorageContainerConstants;
+import 
org.apache.shardingsphere.test.e2e.env.container.storage.option.NativeStorageContainerOption;
 import 
org.apache.shardingsphere.test.e2e.env.container.storage.option.StorageContainerOption;
 import 
org.apache.shardingsphere.test.e2e.env.container.storage.type.DockerStorageContainer;
 import 
org.apache.shardingsphere.test.e2e.env.container.util.StorageContainerUtils;
@@ -70,6 +71,7 @@ import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Optional;
 import java.util.concurrent.TimeUnit;
 
 import static org.junit.jupiter.api.Assertions.assertFalse;
@@ -295,7 +297,11 @@ public final class PipelineContainerComposer implements 
AutoCloseable {
             }
             return option.getConnectOption().getURL(host, port, 
storageContainer.getToBeConnectedDataSourceName(databaseName));
         }
-        return option.getConnectOption().getURL("127.0.0.1", 
E2ETestEnvironment.getInstance().getNativeDatabaseEnvironment().getPort(databaseType),
 databaseName);
+        String host = 
E2ETestEnvironment.getInstance().getNativeDatabaseEnvironment().getHost();
+        int port = 
E2ETestEnvironment.getInstance().getNativeDatabaseEnvironment().getPort(databaseType);
+        Optional<NativeStorageContainerOption> nativeOption = 
DatabaseTypedSPILoader.findService(NativeStorageContainerOption.class, 
databaseType);
+        return nativeOption.map(optional -> 
optional.getAccessURL(option.getConnectOption(), host, port, databaseName))
+                .orElseGet(() -> option.getConnectOption().getURL(host, port, 
databaseName));
     }
     
     /**
diff --git 
a/test/e2e/operation/pipeline/src/test/java/org/apache/shardingsphere/test/e2e/operation/pipeline/framework/container/compose/natived/dialect/OraclePipelineNativeContainerDropTableOption.java
 
b/test/e2e/operation/pipeline/src/test/java/org/apache/shardingsphere/test/e2e/operation/pipeline/framework/container/compose/natived/dialect/OraclePipelineNativeContainerDropTableOption.java
index 879710f8758..688f5dc920c 100644
--- 
a/test/e2e/operation/pipeline/src/test/java/org/apache/shardingsphere/test/e2e/operation/pipeline/framework/container/compose/natived/dialect/OraclePipelineNativeContainerDropTableOption.java
+++ 
b/test/e2e/operation/pipeline/src/test/java/org/apache/shardingsphere/test/e2e/operation/pipeline/framework/container/compose/natived/dialect/OraclePipelineNativeContainerDropTableOption.java
@@ -17,6 +17,10 @@
 
 package 
org.apache.shardingsphere.test.e2e.operation.pipeline.framework.container.compose.natived.dialect;
 
+import 
org.apache.shardingsphere.database.connector.core.spi.DatabaseTypedSPILoader;
+import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
+import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
+import 
org.apache.shardingsphere.test.e2e.env.container.storage.option.NativeStorageContainerOption;
 import 
org.apache.shardingsphere.test.e2e.env.container.storage.option.StorageContainerConnectOption;
 import 
org.apache.shardingsphere.test.e2e.operation.pipeline.framework.container.compose.natived.DialectPipelineNativeContainerDropTableOption;
 
@@ -29,7 +33,9 @@ public final class 
OraclePipelineNativeContainerDropTableOption implements Diale
     
     @Override
     public String getJdbcUrl(final StorageContainerConnectOption 
storageContainerConnectOption, final int actualDatabasePort, final String 
databaseName) {
-        return storageContainerConnectOption.getURL("localhost", 
actualDatabasePort, "");
+        return 
DatabaseTypedSPILoader.findService(NativeStorageContainerOption.class, 
TypedSPILoader.getService(DatabaseType.class, getDatabaseType()))
+                .map(optional -> 
optional.getAccessURL(storageContainerConnectOption, "localhost", 
actualDatabasePort, databaseName))
+                .orElseGet(() -> 
storageContainerConnectOption.getURL("localhost", actualDatabasePort, ""));
     }
     
     @Override
diff --git 
a/test/e2e/operation/pipeline/src/test/java/org/apache/shardingsphere/test/e2e/operation/pipeline/framework/container/compose/natived/dialect/OraclePipelineNativeContainerDropTableOptionTest.java
 
b/test/e2e/operation/pipeline/src/test/java/org/apache/shardingsphere/test/e2e/operation/pipeline/framework/container/compose/natived/dialect/OraclePipelineNativeContainerDropTableOptionTest.java
new file mode 100644
index 00000000000..df0ef247bd0
--- /dev/null
+++ 
b/test/e2e/operation/pipeline/src/test/java/org/apache/shardingsphere/test/e2e/operation/pipeline/framework/container/compose/natived/dialect/OraclePipelineNativeContainerDropTableOptionTest.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package 
org.apache.shardingsphere.test.e2e.operation.pipeline.framework.container.compose.natived.dialect;
+
+import 
org.apache.shardingsphere.database.connector.core.spi.DatabaseTypedSPILoader;
+import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
+import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
+import 
org.apache.shardingsphere.test.e2e.env.container.storage.option.NativeStorageContainerOption;
+import 
org.apache.shardingsphere.test.e2e.env.container.storage.option.StorageContainerConnectOption;
+import org.junit.jupiter.api.Test;
+import org.mockito.MockedStatic;
+
+import java.util.Optional;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.mockStatic;
+import static org.mockito.Mockito.when;
+
+class OraclePipelineNativeContainerDropTableOptionTest {
+    
+    @Test
+    void assertGetJdbcUrl() {
+        DatabaseType databaseType = mock(DatabaseType.class);
+        StorageContainerConnectOption connectOption = 
mock(StorageContainerConnectOption.class);
+        NativeStorageContainerOption nativeOption = 
mock(NativeStorageContainerOption.class);
+        when(nativeOption.getAccessURL(connectOption, "localhost", 1521, 
"pipeline_e2e_0")).thenReturn("jdbc:oracle:thin:@localhost:1521:XE");
+        try (
+                MockedStatic<TypedSPILoader> typedSPILoader = 
mockStatic(TypedSPILoader.class);
+                MockedStatic<DatabaseTypedSPILoader> databaseTypedSPILoader = 
mockStatic(DatabaseTypedSPILoader.class)) {
+            typedSPILoader.when(() -> 
TypedSPILoader.getService(DatabaseType.class, 
"Oracle")).thenReturn(databaseType);
+            databaseTypedSPILoader.when(() -> 
DatabaseTypedSPILoader.findService(NativeStorageContainerOption.class, 
databaseType)).thenReturn(Optional.of(nativeOption));
+            assertThat(new 
OraclePipelineNativeContainerDropTableOption().getJdbcUrl(connectOption, 1521, 
"pipeline_e2e_0"), is("jdbc:oracle:thin:@localhost:1521:XE"));
+        }
+    }
+    
+    @Test
+    void assertGetJdbcUrlWithoutNativeOption() {
+        DatabaseType databaseType = mock(DatabaseType.class);
+        StorageContainerConnectOption connectOption = 
mock(StorageContainerConnectOption.class);
+        when(connectOption.getURL("localhost", 1521, 
"")).thenReturn("jdbc:oracle:thin:@localhost:1521:XE");
+        try (
+                MockedStatic<TypedSPILoader> typedSPILoader = 
mockStatic(TypedSPILoader.class);
+                MockedStatic<DatabaseTypedSPILoader> databaseTypedSPILoader = 
mockStatic(DatabaseTypedSPILoader.class)) {
+            typedSPILoader.when(() -> 
TypedSPILoader.getService(DatabaseType.class, 
"Oracle")).thenReturn(databaseType);
+            databaseTypedSPILoader.when(() -> 
DatabaseTypedSPILoader.findService(NativeStorageContainerOption.class, 
databaseType)).thenReturn(Optional.empty());
+            assertThat(new 
OraclePipelineNativeContainerDropTableOption().getJdbcUrl(connectOption, 1521, 
"pipeline_e2e_0"), is("jdbc:oracle:thin:@localhost:1521:XE"));
+        }
+    }
+}

Reply via email to