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

zhangliang 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 24d14120df6 Add more test cases on MetaDataLoaderTest (#38103)
24d14120df6 is described below

commit 24d14120df6072c389f391b7759b10ab95a8cd65
Author: Liang Zhang <[email protected]>
AuthorDate: Thu Feb 19 22:51:03 2026 +0800

    Add more test cases on MetaDataLoaderTest (#38103)
    
    * Add more test cases on MetaDataLoaderTest
    
    * Add more test cases on MetaDataLoaderTest
---
 .../metadata/data/loader/MetaDataLoaderTest.java   | 160 +++++++++++++++++++++
 1 file changed, 160 insertions(+)

diff --git 
a/database/connector/core/src/test/java/org/apache/shardingsphere/database/connector/core/metadata/data/loader/MetaDataLoaderTest.java
 
b/database/connector/core/src/test/java/org/apache/shardingsphere/database/connector/core/metadata/data/loader/MetaDataLoaderTest.java
new file mode 100644
index 00000000000..ef202760b64
--- /dev/null
+++ 
b/database/connector/core/src/test/java/org/apache/shardingsphere/database/connector/core/metadata/data/loader/MetaDataLoaderTest.java
@@ -0,0 +1,160 @@
+/*
+ * 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.database.connector.core.metadata.data.loader;
+
+import lombok.SneakyThrows;
+import 
org.apache.shardingsphere.database.connector.core.metadata.data.model.SchemaMetaData;
+import 
org.apache.shardingsphere.database.connector.core.metadata.data.model.TableMetaData;
+import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
+import org.apache.shardingsphere.infra.spi.ShardingSphereServiceLoader;
+import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
+import org.junit.jupiter.api.Test;
+import org.mockito.internal.configuration.plugins.Plugins;
+
+import javax.sql.DataSource;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.isA;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+class MetaDataLoaderTest {
+    
+    private final DatabaseType databaseType = 
TypedSPILoader.getService(DatabaseType.class, "FIXTURE");
+    
+    @Test
+    void assertLoadWithDialectLoader() throws Exception {
+        MetaDataLoaderMaterial material = new 
MetaDataLoaderMaterial(Collections.emptyList(), "dialect_success", 
mock(DataSource.class, RETURNS_DEEP_STUBS), databaseType, "foo_db");
+        DialectMetaDataLoader dialectMetaDataLoader = 
mock(DialectMetaDataLoader.class);
+        when(dialectMetaDataLoader.getType()).thenReturn(databaseType);
+        
when(dialectMetaDataLoader.load(material)).thenReturn(Collections.singleton(
+                new SchemaMetaData("foo_db", Collections.singleton(new 
TableMetaData("foo_tbl", Collections.emptyList(), Collections.emptyList(), 
Collections.emptyList())))));
+        try (AutoCloseable ignored = 
registerDialectMetaDataLoader(dialectMetaDataLoader)) {
+            Map<String, SchemaMetaData> actual = 
MetaDataLoader.load(Collections.singleton(material));
+            
assertThat(actual.get("foo_db").getTables().iterator().next().getName(), 
is("foo_tbl"));
+        }
+    }
+    
+    @Test
+    void assertLoadWithDialectLoaderSQLException() throws Exception {
+        MetaDataLoaderMaterial material = new 
MetaDataLoaderMaterial(Collections.emptyList(), "dialect_sql_exception", 
mock(DataSource.class, RETURNS_DEEP_STUBS), databaseType, "foo_db");
+        DialectMetaDataLoader dialectMetaDataLoader = 
mock(DialectMetaDataLoader.class);
+        when(dialectMetaDataLoader.getType()).thenReturn(databaseType);
+        
when(dialectMetaDataLoader.load(any(MetaDataLoaderMaterial.class))).thenThrow(SQLException.class);
+        try (AutoCloseable ignored = 
registerDialectMetaDataLoader(dialectMetaDataLoader)) {
+            Map<String, SchemaMetaData> actual = 
MetaDataLoader.load(Collections.singleton(material));
+            assertThat(actual.size(), is(1));
+            assertTrue(actual.get("foo_db").getTables().isEmpty());
+        }
+    }
+    
+    @Test
+    void assertLoadWithMergedSchemaMetaData() throws SQLException {
+        MetaDataLoaderMaterial firstMaterial = new 
MetaDataLoaderMaterial(Collections.emptyList(), "foo_ds_1", 
mock(DataSource.class, RETURNS_DEEP_STUBS), databaseType, "foo_db");
+        MetaDataLoaderMaterial secondMaterial = new 
MetaDataLoaderMaterial(Collections.emptyList(), "foo_ds_2", 
mock(DataSource.class, RETURNS_DEEP_STUBS), databaseType, "foo_db");
+        Map<String, SchemaMetaData> actual = 
MetaDataLoader.load(Arrays.asList(firstMaterial, secondMaterial));
+        assertThat(actual.size(), is(1));
+        assertTrue(actual.get("foo_db").getTables().isEmpty());
+    }
+    
+    @Test
+    void assertLoadWithDefaultLoader() throws SQLException {
+        MetaDataLoaderMaterial material = new 
MetaDataLoaderMaterial(Collections.singleton("t_order"), "foo_ds", 
mock(DataSource.class, RETURNS_DEEP_STUBS), databaseType, "foo_db");
+        Map<String, SchemaMetaData> actual = 
MetaDataLoader.load(Collections.singleton(material));
+        assertThat(actual.size(), is(1));
+        assertTrue(actual.get("foo_db").getTables().isEmpty());
+    }
+    
+    @Test
+    void assertLoadWhenInterrupted() throws SQLException {
+        MetaDataLoaderMaterial material = new 
MetaDataLoaderMaterial(Collections.emptyList(), "foo_ds", 
mock(DataSource.class, RETURNS_DEEP_STUBS), databaseType, "foo_db");
+        Thread.currentThread().interrupt();
+        try {
+            Map<String, SchemaMetaData> actual = 
MetaDataLoader.load(Collections.singleton(material));
+            assertTrue(actual.isEmpty());
+            assertTrue(Thread.currentThread().isInterrupted());
+        } finally {
+            Thread.interrupted();
+        }
+    }
+    
+    @Test
+    void assertLoadWhenExecutionExceptionCauseIsSQLException() throws 
SQLException {
+        DataSource dataSource = mock(DataSource.class);
+        when(dataSource.getConnection()).thenReturn(mock(Connection.class, 
RETURNS_DEEP_STUBS)).thenThrow(SQLException.class);
+        MetaDataLoaderMaterial material = new 
MetaDataLoaderMaterial(Collections.singleton("t_order"), "foo_ds", dataSource, 
databaseType, "foo_db");
+        SQLException ex = assertThrows(SQLException.class, () -> 
MetaDataLoader.load(Collections.singleton(material)));
+        assertNull(ex.getCause());
+    }
+    
+    @Test
+    void assertLoadWhenExecutionExceptionCauseIsNotSQLException() throws 
SQLException {
+        DataSource dataSource = mock(DataSource.class);
+        when(dataSource.getConnection()).thenReturn(mock(Connection.class, 
RETURNS_DEEP_STUBS)).thenThrow(IllegalStateException.class);
+        MetaDataLoaderMaterial material = new 
MetaDataLoaderMaterial(Collections.singleton("t_order"), "foo_ds", dataSource, 
databaseType, "foo_db");
+        SQLException ex = assertThrows(SQLException.class, () -> 
MetaDataLoader.load(Collections.singleton(material)));
+        assertThat(ex.getCause().getCause(), isA(IllegalStateException.class));
+    }
+    
+    @SneakyThrows(ReflectiveOperationException.class)
+    private AutoCloseable registerDialectMetaDataLoader(final 
DialectMetaDataLoader service) {
+        Map<Class<?>, Object> registeredServices = getRegisteredServices();
+        Object original = registeredServices.put(DialectMetaDataLoader.class, 
createRegisteredService(service));
+        return () -> restoreDialectMetaDataLoader(registeredServices, 
original);
+    }
+    
+    @SuppressWarnings("unchecked")
+    private Map<Class<?>, Object> getRegisteredServices() throws 
ReflectiveOperationException {
+        Field registeredServicesField = 
ShardingSphereServiceLoader.class.getDeclaredField("REGISTERED_SERVICES");
+        return (Map<Class<?>, Object>) 
Plugins.getMemberAccessor().get(registeredServicesField, 
ShardingSphereServiceLoader.class);
+    }
+    
+    @SuppressWarnings("unchecked")
+    private Object createRegisteredService(final DialectMetaDataLoader 
service) throws ReflectiveOperationException {
+        Class<?> registeredServiceClass = 
Class.forName("org.apache.shardingsphere.infra.spi.RegisteredShardingSphereSPI");
+        Constructor<?> constructor = 
registeredServiceClass.getDeclaredConstructor(Class.class);
+        Object result = Plugins.getMemberAccessor().newInstance(constructor, 
DialectMetaDataLoader.class);
+        Field servicesField = 
registeredServiceClass.getDeclaredField("services");
+        Collection<DialectMetaDataLoader> services = 
(Collection<DialectMetaDataLoader>) 
Plugins.getMemberAccessor().get(servicesField, result);
+        services.clear();
+        services.add(service);
+        return result;
+    }
+    
+    private void restoreDialectMetaDataLoader(final Map<Class<?>, Object> 
registeredServices, final Object original) {
+        if (null == original) {
+            registeredServices.remove(DialectMetaDataLoader.class);
+        } else {
+            registeredServices.put(DialectMetaDataLoader.class, original);
+        }
+    }
+}

Reply via email to