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 263eb80c9f6 cover distsql handler and MySQL process list branches
(#37612)
263eb80c9f6 is described below
commit 263eb80c9f6e92c73b4baf9eeec5192c4189cdd1
Author: Liang Zhang <[email protected]>
AuthorDate: Thu Jan 1 23:02:58 2026 +0800
cover distsql handler and MySQL process list branches (#37612)
---
.../yaml/YamlProxyDatabaseConfigurationTest.java | 56 +++++++++++++++++
.../yaml/YamlProxyServerConfigurationTest.java | 72 ++++++++++++++++++++++
.../DistSQLQueryProxyBackendHandlerTest.java | 41 +++++++++++-
.../show/MySQLShowProcessListExecutorTest.java | 56 ++++++++++++++---
4 files changed, 215 insertions(+), 10 deletions(-)
diff --git
a/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/config/yaml/YamlProxyDatabaseConfigurationTest.java
b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/config/yaml/YamlProxyDatabaseConfigurationTest.java
new file mode 100644
index 00000000000..5bff3a1f388
--- /dev/null
+++
b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/config/yaml/YamlProxyDatabaseConfigurationTest.java
@@ -0,0 +1,56 @@
+/*
+ * 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.proxy.backend.config.yaml;
+
+import
org.apache.shardingsphere.infra.yaml.config.pojo.rule.YamlRuleConfiguration;
+import org.junit.jupiter.api.Test;
+
+import java.util.Collections;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.Mockito.mock;
+
+class YamlProxyDatabaseConfigurationTest {
+
+ @Test
+ void assertIsEmptyWithAllFieldsEmpty() {
+ assertTrue(new YamlProxyDatabaseConfiguration().isEmpty());
+ }
+
+ @Test
+ void assertIsEmptyWhenDatabaseNameExists() {
+ YamlProxyDatabaseConfiguration actual = new
YamlProxyDatabaseConfiguration();
+ actual.setDatabaseName("foo_db");
+ assertFalse(actual.isEmpty());
+ }
+
+ @Test
+ void assertIsEmptyWhenDataSourcesExist() {
+ YamlProxyDatabaseConfiguration actual = new
YamlProxyDatabaseConfiguration();
+ actual.getDataSources().put("ds_0", new
YamlProxyDataSourceConfiguration());
+ assertFalse(actual.isEmpty());
+ }
+
+ @Test
+ void assertIsEmptyWhenRulesExist() {
+ YamlProxyDatabaseConfiguration actual = new
YamlProxyDatabaseConfiguration();
+
actual.setRules(Collections.singleton(mock(YamlRuleConfiguration.class)));
+ assertFalse(actual.isEmpty());
+ }
+}
diff --git
a/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/config/yaml/YamlProxyServerConfigurationTest.java
b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/config/yaml/YamlProxyServerConfigurationTest.java
new file mode 100644
index 00000000000..264b98389d4
--- /dev/null
+++
b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/config/yaml/YamlProxyServerConfigurationTest.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.proxy.backend.config.yaml;
+
+import
org.apache.shardingsphere.infra.yaml.config.pojo.rule.YamlRuleConfiguration;
+import org.junit.jupiter.api.Test;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.Properties;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.sameInstance;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.Mockito.mock;
+
+class YamlProxyServerConfigurationTest {
+
+ @Test
+ void assertSetRulesIgnoresNull() {
+ YamlProxyServerConfiguration actual = new
YamlProxyServerConfiguration();
+ Collection<YamlRuleConfiguration> expectedRules = new
LinkedList<>(Collections.singleton(mock(YamlRuleConfiguration.class)));
+ actual.setRules(expectedRules);
+ actual.setRules(null);
+ assertThat(actual.getRules(), sameInstance(expectedRules));
+ }
+
+ @Test
+ void assertSetRulesReplacesWhenNotNull() {
+ YamlProxyServerConfiguration actual = new
YamlProxyServerConfiguration();
+ Collection<YamlRuleConfiguration> expectedRules =
Collections.singletonList(mock(YamlRuleConfiguration.class));
+ actual.setRules(expectedRules);
+ assertThat(actual.getRules(), is(expectedRules));
+ }
+
+ @Test
+ void assertSetPropsIgnoresNull() {
+ YamlProxyServerConfiguration actual = new
YamlProxyServerConfiguration();
+ Properties expectedProps = new Properties();
+ expectedProps.setProperty("key", "value");
+ actual.setProps(expectedProps);
+ actual.setProps(null);
+ assertThat(actual.getProps(), sameInstance(expectedProps));
+ }
+
+ @Test
+ void assertSetPropsReplacesWhenNotNull() {
+ YamlProxyServerConfiguration actual = new
YamlProxyServerConfiguration();
+ Properties expectedProps = new Properties();
+ expectedProps.setProperty("proxy-port", "3307");
+ actual.setProps(expectedProps);
+ assertTrue(actual.getProps().containsKey("proxy-port"));
+ assertThat(actual.getProps(), is(expectedProps));
+ }
+}
diff --git
a/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/distsql/DistSQLQueryProxyBackendHandlerTest.java
b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/distsql/DistSQLQueryProxyBackendHandlerTest.java
index e5823715b19..8f06edc80fa 100644
---
a/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/distsql/DistSQLQueryProxyBackendHandlerTest.java
+++
b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/distsql/DistSQLQueryProxyBackendHandlerTest.java
@@ -20,11 +20,14 @@ package
org.apache.shardingsphere.proxy.backend.handler.distsql;
import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
import
org.apache.shardingsphere.database.exception.core.exception.syntax.database.NoDatabaseSelectedException;
import
org.apache.shardingsphere.database.exception.core.exception.syntax.database.UnknownDatabaseException;
+import
org.apache.shardingsphere.distsql.handler.engine.query.DistSQLQueryExecutor;
+import org.apache.shardingsphere.distsql.statement.DistSQLStatement;
import
org.apache.shardingsphere.distsql.statement.type.ral.queryable.QueryableRALStatement;
import
org.apache.shardingsphere.distsql.statement.type.ral.queryable.export.ExportDatabaseConfigurationStatement;
import
org.apache.shardingsphere.distsql.statement.type.ral.queryable.show.ShowTableMetaDataStatement;
import org.apache.shardingsphere.infra.config.mode.ModeConfiguration;
import org.apache.shardingsphere.infra.instance.ComputeNodeInstanceContext;
+import
org.apache.shardingsphere.infra.merge.result.impl.local.LocalDataQueryResultRow;
import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData;
import
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
import
org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereColumn;
@@ -37,24 +40,32 @@ import
org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
import org.apache.shardingsphere.mode.manager.ContextManager;
import org.apache.shardingsphere.mode.metadata.MetaDataContexts;
import org.apache.shardingsphere.mode.spi.repository.PersistRepository;
+import org.apache.shardingsphere.proxy.backend.response.data.QueryResponseRow;
+import
org.apache.shardingsphere.proxy.backend.response.header.query.QueryResponseHeader;
import org.apache.shardingsphere.proxy.backend.session.ConnectionSession;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.dal.FromDatabaseSegment;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.generic.DatabaseSegment;
+import
org.apache.shardingsphere.sql.parser.statement.core.statement.attribute.SQLStatementAttributes;
import
org.apache.shardingsphere.sql.parser.statement.core.value.identifier.IdentifierValue;
import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.MockedStatic;
+import java.sql.SQLException;
import java.util.Collection;
import java.util.Collections;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.contains;
+import static org.hamcrest.Matchers.is;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.mockStatic;
import static org.mockito.Mockito.when;
-@ExtendWith(MockitoExtension.class)
class DistSQLQueryProxyBackendHandlerTest {
private final DatabaseType databaseType =
TypedSPILoader.getService(DatabaseType.class, "FIXTURE");
@@ -102,4 +113,28 @@ class DistSQLQueryProxyBackendHandlerTest {
private ShowTableMetaDataStatement createSqlStatement() {
return new
ShowTableMetaDataStatement(Collections.singleton("t_order"), new
FromDatabaseSegment(0, new DatabaseSegment(0, 0, new
IdentifierValue("foo_db"))));
}
+
+ @SuppressWarnings("unchecked")
+ @Test
+ void assertGetRowData() throws SQLException {
+ DistSQLStatement sqlStatement = mock(DistSQLStatement.class);
+ when(sqlStatement.getAttributes()).thenReturn(new
SQLStatementAttributes());
+ ConnectionSession connectionSession = mock(ConnectionSession.class,
RETURNS_DEEP_STUBS);
+
when(connectionSession.getDatabaseConnectionManager().getConnectionSize()).thenReturn(1);
+ DistSQLQueryExecutor<DistSQLStatement> executor =
mock(DistSQLQueryExecutor.class);
+
when(executor.getColumnNames(sqlStatement)).thenReturn(Collections.singleton("name"));
+ ContextManager contextManager = mock(ContextManager.class);
+ when(executor.getRows(sqlStatement,
contextManager)).thenReturn(Collections.singleton(new
LocalDataQueryResultRow("value")));
+ try (MockedStatic<TypedSPILoader> typedSPILoader =
mockStatic(TypedSPILoader.class)) {
+ typedSPILoader.when(() ->
TypedSPILoader.getService(DistSQLQueryExecutor.class,
sqlStatement.getClass())).thenReturn(executor);
+ DistSQLQueryProxyBackendHandler handler = new
DistSQLQueryProxyBackendHandler(sqlStatement, mock(), connectionSession,
contextManager);
+ assertFalse(handler.next());
+ QueryResponseHeader responseHeader = (QueryResponseHeader)
handler.execute();
+ assertThat(responseHeader.getQueryHeaders().size(), is(1));
+ assertTrue(handler.next());
+ QueryResponseRow row = handler.getRowData();
+ assertThat(row.getData(), contains("value"));
+ assertFalse(handler.next());
+ }
+ }
}
diff --git
a/proxy/backend/dialect/mysql/src/test/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/executor/show/MySQLShowProcessListExecutorTest.java
b/proxy/backend/dialect/mysql/src/test/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/executor/show/MySQLShowProcessListExecutorTest.java
index 2cc937beea2..d6ef530d69c 100644
---
a/proxy/backend/dialect/mysql/src/test/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/executor/show/MySQLShowProcessListExecutorTest.java
+++
b/proxy/backend/dialect/mysql/src/test/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/executor/show/MySQLShowProcessListExecutorTest.java
@@ -32,13 +32,14 @@ import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import java.sql.SQLException;
-import java.util.Collection;
+import java.util.Arrays;
import java.util.Collections;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.startsWith;
import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -53,7 +54,9 @@ class MySQLShowProcessListExecutorTest {
void assertExecute() throws SQLException {
ContextManager contextManager = mock(ContextManager.class,
RETURNS_DEEP_STUBS);
when(ProxyContext.getInstance().getContextManager()).thenReturn(contextManager);
-
when(contextManager.getPersistServiceFacade().getModeFacade().getProcessService().getProcessList()).thenReturn(mockProcessList());
+ Process process = new Process("f6c2336a-63ba-41bf-941e-2e3504eb2c80",
1617939785160L, "ALTER TABLE t_order ADD COLUMN a varchar(64) AFTER order_id",
+ "foo_db", "root", "127.0.0.1", new AtomicInteger(2), new
AtomicInteger(1), new AtomicBoolean(false), new AtomicBoolean());
+
when(contextManager.getPersistServiceFacade().getModeFacade().getProcessService().getProcessList()).thenReturn(Collections.singleton(process));
MySQLShowProcessListExecutor showProcessListExecutor = new
MySQLShowProcessListExecutor(new MySQLShowProcessListStatement(databaseType,
false));
showProcessListExecutor.execute(new ConnectionSession(databaseType,
new DefaultAttributeMap()), mock());
assertThat(showProcessListExecutor.getQueryResultMetaData().getColumnCount(),
is(8));
@@ -68,10 +71,49 @@ class MySQLShowProcessListExecutorTest {
}
}
- private Collection<Process> mockProcessList() {
- Process process = new Process("f6c2336a-63ba-41bf-941e-2e3504eb2c80",
1617939785160L,
- "ALTER TABLE t_order ADD COLUMN a varchar(64) AFTER order_id",
"foo_db", "root", "127.0.0.1", new AtomicInteger(2), new AtomicInteger(1), new
AtomicBoolean(false),
- new AtomicBoolean());
- return Collections.singleton(process);
+ @Test
+ void assertExecuteCoversIdleAndTruncatedProcess() throws SQLException {
+ ContextManager contextManager = mock(ContextManager.class,
RETURNS_DEEP_STUBS);
+
when(ProxyContext.getInstance().getContextManager()).thenReturn(contextManager);
+ String longSql = "SELECT * FROM t_order WHERE user_id = 1 AND status =
'PAID' ORDER BY create_time DESC LIMIT 100 OFFSET 10";
+ String repeatedSql = longSql + longSql;
+
when(contextManager.getPersistServiceFacade().getModeFacade().getProcessService().getProcessList()).thenReturn(Arrays.asList(
+ new Process("idle-id",
+ System.currentTimeMillis() - 1000L, "", "foo_db",
"guest", "192.168.0.1", new AtomicInteger(0), new AtomicInteger(0), new
AtomicBoolean(true), new AtomicBoolean()),
+ new Process("busy-id",
+ System.currentTimeMillis() - 1000L, repeatedSql,
"foo_db", "root", "127.0.0.1", new AtomicInteger(4), new AtomicInteger(2), new
AtomicBoolean(false), new AtomicBoolean())));
+ MySQLShowProcessListExecutor showProcessListExecutor = new
MySQLShowProcessListExecutor(new MySQLShowProcessListStatement(databaseType,
false));
+ showProcessListExecutor.execute(new ConnectionSession(databaseType,
new DefaultAttributeMap()), mock());
+ MergedResult mergedResult = showProcessListExecutor.getMergedResult();
+ int rowCount = 0;
+ assertThat(mergedResult.next(), is(true));
+ rowCount++;
+ assertThat(mergedResult.getValue(5, String.class), is("Sleep"));
+ assertThat(mergedResult.getValue(7, String.class), is(""));
+ assertThat(mergedResult.getValue(8, String.class), is(""));
+ assertThat(mergedResult.next(), is(true));
+ rowCount++;
+ assertThat(mergedResult.getValue(5, String.class), is("Execute"));
+ assertThat(mergedResult.getValue(7, String.class), is("Executing
2/4"));
+ assertThat(((String) mergedResult.getValue(8, String.class)).length(),
is(100));
+ assertThat((String) mergedResult.getValue(8, String.class),
startsWith(longSql.substring(0, 50)));
+ assertThat(mergedResult.next(), is(false));
+ assertThat(rowCount, is(2));
+ }
+
+ @Test
+ void assertExecuteWithFullOutputKeepsLongSql() throws SQLException {
+ ContextManager contextManager = mock(ContextManager.class,
RETURNS_DEEP_STUBS);
+
when(ProxyContext.getInstance().getContextManager()).thenReturn(contextManager);
+ String longSql = String.join("", Collections.nCopies(120, "a"));
+ Process process = new Process("long-sql-id",
System.currentTimeMillis(), longSql, "foo_db", "root", "127.0.0.1",
+ new AtomicInteger(3), new AtomicInteger(1), new
AtomicBoolean(false), new AtomicBoolean());
+
when(contextManager.getPersistServiceFacade().getModeFacade().getProcessService().getProcessList()).thenReturn(Collections.singleton(process));
+ MySQLShowProcessListExecutor executor = new
MySQLShowProcessListExecutor(new MySQLShowProcessListStatement(databaseType,
true));
+ executor.execute(new ConnectionSession(databaseType, new
DefaultAttributeMap()), mock());
+ MergedResult mergedResult = executor.getMergedResult();
+ assertThat(mergedResult.next(), is(true));
+ assertThat(((String) mergedResult.getValue(8, String.class)).length(),
is(120));
+ assertThat(mergedResult.next(), is(false));
}
}