Skip to content

Commit

Permalink
Add some assert case for db-discovery (#22484)
Browse files Browse the repository at this point in the history
* Add some case to discovry IT

* Fix scenarios

* Adjustment scenario

* Add some cases

* Rename and fix checkstyle

* Add newline

* Revise

* Fix error

* Fix it

* Fix it
  • Loading branch information
zhaojinchao95 authored Nov 29, 2022
1 parent 1926b4d commit 288fc4d
Show file tree
Hide file tree
Showing 14 changed files with 249 additions and 65 deletions.
88 changes: 88 additions & 0 deletions .github/workflows/it-discovery.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#
# 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.
#

name: IT - Discovery

on:
push:
branches: [ master, dev ]
paths:
- '.github/workflows/it-discovery.yml'
- 'infra/common/src/main/**'
- 'features/db-discovery/src/main/**'
- 'features/readwrite-splitting/src/main/**'
- 'proxy/**/src/main/**'
- 'jdbc/core/src/main/**'
- '!test/**'
- 'test/pom.xml'
- 'test/integration-test/fixture/**'
- 'test/integration-test/env/**'
- 'test/integration-test/discovery/**'
- '!*.md'
pull_request:
branches: [ master ]
paths:
- '.github/workflows/it-discovery.yml'
- 'infra/common/src/main/**'
- 'features/db-discovery/src/main/**'
- 'features/readwrite-splitting/src/main/**'
- 'proxy/**/src/main/**'
- 'jdbc/core/src/main/**'
- '!test/**'
- 'test/pom.xml'
- 'test/integration-test/fixture/**'
- 'test/integration-test/env/**'
- 'test/integration-test/discovery/**'
- '!*.md'
workflow_dispatch:

concurrency:
group: it-discovery-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

env:
MAVEN_OPTS: -Dhttp.keepAlive=false -Dmaven.wagon.http.pool=false -Dmaven.wagon.http.retryHandler.class=standard -Dmaven.wagon.http.retryHandler.count=3 -Dmaven.javadoc.skip=true -Dcheckstyle.skip=true -Dspotless.apply.skip=true -Djacoco.skip=true -Drat.skip=true -Dfailsafe.skipAfterFailureCount=1 -Dio.netty.leakDetectionLevel=advanced

jobs:
discovery-it-test:
name: discovery-it-test
runs-on: ubuntu-latest
env:
mysql_version: 5.7
timeout-minutes: 10
strategy:
matrix:
mode: [ Cluster ]
steps:
- uses: actions/checkout@v3
- name: Cache Maven Repos
uses: actions/cache@v3
with:
path: ~/.m2/repository
key: shardingsphere-maven-third-party-it-cache${{ github.sha }}
restore-keys: |
shardingsphere-maven-third-party-it-cache
shardingsphere-maven-third-party-
- name: Set up JDK 8
uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: 8
- name: Build Discovery IT image
run: ./mvnw -B clean install -am -pl test/integration-test/discovery -Pit.env.docker -DskipTests
- name: Run MySQL Discovery Integration Test
run: ./mvnw -nsu -B install -f test/integration-test/discovery/pom.xml -Dit.env.type=docker -Dit.docker.mysql.version=mysql:5.7
Original file line number Diff line number Diff line change
Expand Up @@ -18,24 +18,17 @@
package org.apache.shardingsphere.test.integration.discovery.cases;

import javax.sql.DataSource;
import java.util.List;
import java.util.Map;

/**
* Database cluster environment.
*/
public interface DatabaseClusterEnvironment {

/**
* Get primary data source.
* Get data sources.
*
* @return primary data source
* @return data sources
*/
DataSource getPrimaryDataSource();

/**
* Get replication data sources.
*
* @return replication data sources
*/
List<DataSource> getReplicationDataSources();
Map<String, DataSource> getDataSources();
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import org.apache.shardingsphere.data.pipeline.core.util.ThreadUtil;
import org.apache.shardingsphere.infra.database.type.DatabaseType;
import org.apache.shardingsphere.test.integration.discovery.build.DiscoveryRuleBuilder;
import org.apache.shardingsphere.test.integration.discovery.cases.DatabaseClusterEnvironment;
import org.apache.shardingsphere.test.integration.discovery.env.IntegrationTestEnvironment;
import org.apache.shardingsphere.test.integration.discovery.framework.container.compose.BaseContainerComposer;
import org.apache.shardingsphere.test.integration.discovery.framework.container.compose.DockerContainerComposer;
Expand All @@ -36,6 +37,8 @@
import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

import static org.junit.Assert.assertNotEquals;
Expand Down Expand Up @@ -77,18 +80,24 @@ public void initDiscoveryEnvironment() throws SQLException {
}

/**
* Get primary data source name.
*
* @return primary data source name
* @throws SQLException SQL exception
* Assert close primary data source.
* @param mgrEnvironment mgr environment
* @throws SQLException SQL Exception
*/
public String getPrimaryDataSourceName() throws SQLException {
public void assertClosePrimaryDataSource(final DatabaseClusterEnvironment mgrEnvironment) throws SQLException {
String oldPrimaryDataSourceName = getPrimaryDataSourceName();
closeDataSource(mgrEnvironment.getDataSources().get(oldPrimaryDataSourceName));
String newPrimaryDataSourceName = getPrimaryDataSourceName();
assertPrimaryDataSourceChanged(oldPrimaryDataSourceName, newPrimaryDataSourceName);
mgrEnvironment.getDataSources().remove(oldPrimaryDataSourceName);
}

private String getPrimaryDataSourceName() throws SQLException {
try (
Connection connection = proxyDataSource.getConnection();
Statement statement = connection.createStatement()) {
String expectedPrimaryDataSourceName = getDiscoveryRulePrimaryDataSourceName(statement);
String actualPrimaryDataSourceName = getReadwriteSplittingRulePrimaryDataSourceName(statement);
assertPrimaryDataSource(actualPrimaryDataSourceName, expectedPrimaryDataSourceName);
assertPrimaryDataSource(actualPrimaryDataSourceName, getDiscoveryRulePrimaryDataSourceName(statement));
return actualPrimaryDataSourceName;
}
}
Expand All @@ -106,38 +115,70 @@ private String getDiscoveryRulePrimaryDataSourceName(final Statement statement)
}

private void assertPrimaryDataSource(final String actualPrimaryDataSourceName, final String expectedPrimaryDataSourceName) {
Preconditions.checkState(StringUtils.isNotBlank(expectedPrimaryDataSourceName) && StringUtils.isNotBlank(actualPrimaryDataSourceName));
Preconditions.checkState(StringUtils.isNotBlank(actualPrimaryDataSourceName) && StringUtils.isNotBlank(expectedPrimaryDataSourceName));
assertThat(actualPrimaryDataSourceName, is(expectedPrimaryDataSourceName));
}

private void closeDataSource(final DataSource dataSource) throws SQLException {
try (
Connection connection = dataSource.getConnection();
Statement statement = connection.createStatement()) {
statement.execute("SHUTDOWN");
}
ThreadUtil.sleep(30, TimeUnit.SECONDS);
}

private void assertPrimaryDataSourceChanged(final String oldPrimaryDataSourceName, final String newPrimaryDataSourceName) {
assertNotEquals(oldPrimaryDataSourceName, newPrimaryDataSourceName);
}

/**
* Close data sources.
*
* @param dataSources data sources
* @throws SQLException SQL exception
* Assert close replication data source.
* @param mgrEnvironment mgr environment
* @throws SQLException SQL Exception
*/
public void closeDataSources(final List<DataSource> dataSources) throws SQLException {
for (DataSource each : dataSources) {
close(each);
public void assertCloseReplicationDataSource(final DatabaseClusterEnvironment mgrEnvironment) throws SQLException {
mgrEnvironment.getDataSources().remove(getPrimaryDataSourceName());
String closedRoutingDataSourceName = getCloseReplicationDataSourceName(mgrEnvironment);
mgrEnvironment.getDataSources().remove(closedRoutingDataSourceName);
String routeDataSourceName = getRouteDataSourceName();
assertRouteDataSourceName(routeDataSourceName, Objects.requireNonNull(mgrEnvironment.getDataSources().entrySet().stream().findFirst().orElse(null)).getKey());
}

private String getCloseReplicationDataSourceName(final DatabaseClusterEnvironment mgrEnvironment) throws SQLException {
for (Map.Entry<String, DataSource> entry : mgrEnvironment.getDataSources().entrySet()) {
closeDataSource(mgrEnvironment.getDataSources().get(entry.getKey()));
return entry.getKey();
}
ThreadUtil.sleep(20, TimeUnit.SECONDS);
return null;
}

private void close(final DataSource dataSource) throws SQLException {
private String getRouteDataSourceName() throws SQLException {
try (
Connection connection = dataSource.getConnection();
Connection connection = proxyDataSource.getConnection();
Statement statement = connection.createStatement()) {
statement.execute("SHUTDOWN");
return getRouteDataSourceName(statement);
}
}

private String getRouteDataSourceName(final Statement statement) throws SQLException {
try (ResultSet resultSet = statement.executeQuery("PREVIEW SELECT 1")) {
return resultSet.next() ? resultSet.getString("data_source_name") : "";
}
}

private void assertRouteDataSourceName(final String actualRouteDataSourceName, final String expectedRouteDataSourceName) {
Preconditions.checkState(StringUtils.isNotBlank(actualRouteDataSourceName) && StringUtils.isNotBlank(expectedRouteDataSourceName));
assertThat(actualRouteDataSourceName, is(expectedRouteDataSourceName));
}

/**
* Assert primary data source changed.
*
* @param oldPrimaryDataSourceName old primary data source name
* @param newPrimaryDataSourceName new primary data source name
* Assert close all replication data source.
* @param mgrEnvironment mgr environment
* @throws SQLException SQL Exception
*/
public void assertPrimaryDataSourceChanged(final String oldPrimaryDataSourceName, final String newPrimaryDataSourceName) {
assertNotEquals(oldPrimaryDataSourceName, newPrimaryDataSourceName);
public void assertCloseAllReplicationDataSource(final DatabaseClusterEnvironment mgrEnvironment) throws SQLException {
closeDataSource(Objects.requireNonNull(mgrEnvironment.getDataSources().values().stream().findFirst().orElse(null)));
assertRouteDataSourceName(getRouteDataSourceName(), getPrimaryDataSourceName());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,16 @@

import java.sql.SQLException;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;

/**
* MySQL MGR primary data source changed Integration Test.
* Discovery MySQL MGR Integration Test.
*/
@Slf4j
@RunWith(Parameterized.class)
public final class MySQLMGRPrimaryDataSourceChangedIT extends BaseITCase {
public final class DiscoveryMGRGeneralIT extends BaseITCase {

public MySQLMGRPrimaryDataSourceChangedIT(final DiscoveryParameterized discoveryParameterized) {
public DiscoveryMGRGeneralIT(final DiscoveryParameterized discoveryParameterized) {
super(discoveryParameterized);
}

Expand All @@ -49,17 +48,17 @@ public static Collection<DiscoveryParameterized> getParameters() {
Collection<DiscoveryParameterized> result = new LinkedList<>();
MySQLDatabaseType databaseType = new MySQLDatabaseType();
for (String each : ENV.listStorageContainerImages(databaseType)) {
result.add(new DiscoveryParameterized(databaseType, each, "discovery"));
result.add(new DiscoveryParameterized(databaseType, each, "mgr_discovery"));
}
return result;
}

@Test
public void assertMySQLMGRPrimaryDataSourceChanged() throws SQLException {
public void assertDiscoveryMySQLMGR() throws SQLException {
DatabaseClusterEnvironment mgrEnvironment = DatabaseClusterEnvironmentFactory.newInstance("MySQL.MGR", getMappedDataSources());
initDiscoveryEnvironment();
String oldPrimaryDataSourceName = getPrimaryDataSourceName();
closeDataSources(Collections.singletonList(mgrEnvironment.getPrimaryDataSource()));
assertPrimaryDataSourceChanged(oldPrimaryDataSourceName, getPrimaryDataSourceName());
assertClosePrimaryDataSource(mgrEnvironment);
assertCloseReplicationDataSource(mgrEnvironment);
assertCloseAllReplicationDataSource(mgrEnvironment);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
Expand All @@ -39,21 +41,38 @@ public final class MySQLMGREnvironment implements DatabaseClusterEnvironment {
private final MGRPrimaryReplicaCommand mgrPrimaryReplicaCommand;

@Getter
private final Map<String, DataSource> dataSources;

private final DataSource primaryDataSource;

@Getter
private final List<DataSource> replicationDataSources;

public MySQLMGREnvironment(final List<DataSource> dataSources) throws SQLException {
primaryDataSource = dataSources.get(0);
replicationDataSources = dataSources.subList(1, dataSources.size());
this.dataSources = getAllDataSources();
mgrPrimaryReplicaCommand = JAXB.unmarshal(Objects.requireNonNull(BaseITCase.class.getClassLoader().getResource("env/common/mgr-primary-replica-command.xml")),
MGRPrimaryReplicaCommand.class);
buildMGRPrimaryDataSource();
buildMGRReplicaDataSources();
createDatabase();
}

private Map<String, DataSource> getAllDataSources() {
Map<String, DataSource> result = new LinkedHashMap<>(4, 1);
result.put("ds_0", primaryDataSource);
result.putAll(getReplicationDataSources());
return result;
}

private Map<String, DataSource> getReplicationDataSources() {
Map<String, DataSource> result = new LinkedHashMap<>(3, 1);
for (int i = 0; i < replicationDataSources.size(); i++) {
result.put("ds_" + (i + 1), replicationDataSources.get(i));
}
return result;
}

private void buildMGRPrimaryDataSource() throws SQLException {
try (
Connection connection = primaryDataSource.getConnection();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,6 @@ public final class MySQLContainerConfigurationFactory {
*/
public static List<StorageContainerConfiguration> newInstance(final String scenario, final DatabaseType databaseType) {
Integer containerQuantity = DiscoveryContainerUtil.loadContainerRawNamesAndQuantity(scenario).get(databaseType.getType().toLowerCase());
if (null == containerQuantity) {
return getDefaultConfiguration(databaseType);
}
if (1 == containerQuantity) {
return Collections.singletonList(new StorageContainerConfiguration(getCommand(), getContainerEnvironments(), getMountedResources(scenario, databaseType, 0)));
}
List<StorageContainerConfiguration> result = new LinkedList<>();
for (int i = 1; i <= containerQuantity; i++) {
result.add(new StorageContainerConfiguration(getCommand(), getContainerEnvironments(), getMountedResources(scenario, databaseType, i)));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public final class DiscoveryContainerUtil {
* @return container names and quantity
*/
public static Map<String, Integer> loadContainerRawNamesAndQuantity(final String scenario) {
Map<String, Integer> result = new HashMap<>(3, 1);
Map<String, Integer> result = new HashMap<>(4, 1);
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
URL resource = classLoader.getResource("env/scenario/" + scenario);
if (null != resource) {
Expand Down
Loading

0 comments on commit 288fc4d

Please sign in to comment.