Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Perform unit testing on the Seata integration module of ShardingSphere in the multi-microservice scenario #1

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
### self for lingh ###
.idea
12 changes: 6 additions & 6 deletions springboot-example/seata-consumer/build.gradle
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
plugins {
id 'java'
id 'org.springframework.boot' version '3.3.0'
id 'org.springframework.boot' version '3.3.1'
id 'io.spring.dependency-management' version '1.1.5'
}

Expand Down Expand Up @@ -28,24 +28,24 @@ dependencies {
compileOnly 'org.projectlombok:lombok'
runtimeOnly 'com.mysql:mysql-connector-j'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
implementation('org.apache.shardingsphere:shardingsphere-jdbc:5.5.0') {
exclude group: "org.apache.shardingsphere", module: "shardingsphere-test-util"
}
implementation 'org.apache.shardingsphere:shardingsphere-transaction-base-seata-at:5.5.0'
implementation ('io.seata:seata-spring-boot-starter:2.0.0') {
implementation('io.seata:seata-spring-boot-starter:2.0.0') {
exclude group: 'org.antlr', module: 'antlr4-runtime'
}
implementation ('com.baomidou:mybatis-plus-boot-starter:3.5.6') {
implementation('com.baomidou:mybatis-plus-boot-starter:3.5.6') {
exclude group: 'org.mybatis', module: 'mybatis-spring'
}
implementation 'org.mybatis:mybatis-spring:3.0.3'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
testImplementation 'org.springframework.experimental.boot:spring-boot-testjars:0.0.1'
testImplementation 'org.testcontainers:mysql'
testImplementation 'org.testcontainers:junit-jupiter'
}

tasks.named('test') {
useJUnitPlatform()
}
}
Original file line number Diff line number Diff line change
@@ -1,31 +1,32 @@
package com.youyi.seataconsumer;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.net.URI;
import java.util.Map;
import java.util.Objects;

@RestController
public class ConsumerController {

@Autowired
AccountMapper accountMapper;
final AccountMapper accountMapper;

@Autowired
RestTemplate restTemplate;
final RestTemplate restTemplate;

@Value("${provider.port}")
String port;

public ConsumerController(AccountMapper accountMapper, RestTemplate restTemplate) {
this.accountMapper = accountMapper;
this.restTemplate = restTemplate;
}

@SuppressWarnings({"NumericOverflow", "divzero", "unused"})
@GetMapping("consume")
@Transactional
public String consume(Long id) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,16 @@
package com.youyi.seataconsumer;

import io.seata.core.context.RootContext;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.mybatis.spring.annotation.MapperScans;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.lang.NonNull;
import org.springframework.web.client.RestTemplate;

import javax.sql.DataSource;
import java.io.IOException;

@Configuration
Expand All @@ -32,7 +27,8 @@ public RestTemplate restTemplate() {

static class RestTemplateInterceptor implements ClientHttpRequestInterceptor {
@Override
public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
@NonNull
public ClientHttpResponse intercept(HttpRequest request, @NonNull byte[] body, ClientHttpRequestExecution execution) throws IOException {
// 将 TX_XID 放入请求头
request.getHeaders().add(RootContext.KEY_XID, RootContext.getXID());
return execution.execute(request, body);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,8 @@
package com.youyi.seataconsumer;

import io.seata.core.context.RootContext;
import io.seata.spring.boot.autoconfigure.SeataAutoConfiguration;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.web.client.RestTemplate;

import java.io.IOException;

// 排除 SeataAutoConfiguration
@SpringBootApplication(exclude = SeataAutoConfiguration.class)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,16 @@
package com.youyi.seataconsumer;

import com.github.dockerjava.api.model.ExposedPort;
import com.github.dockerjava.api.model.HostConfig;
import com.github.dockerjava.api.model.Ports;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.Bean;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.containers.MySQLContainer;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;

@SuppressWarnings({"SqlDialectInspection", "SqlNoDataSourceInspection"})
public class ConsumerControllerTests extends AbstractTests {

/**
Expand All @@ -39,11 +32,11 @@ public class ConsumerControllerTests extends AbstractTests {
* datasource3307: id(1), money(300.0)
*/
@Test
void testConsumerController() throws Exception {
Assertions.assertThrows(ArithmeticException.class, () -> consumerController.consume(1L));
Assertions.assertEquals(100.0, getMoney(dataSource3306()));
void testConsumerController() {
assertThrows(ArithmeticException.class, () -> consumerController.consume(1L));
assertEquals(100.0, getMoney(dataSource3306()));
// the below assertion will fail
Assertions.assertEquals(100.0, getMoney(dataSource3307()));
assertEquals(100.0, getMoney(dataSource3307()));
}

private double getMoney(DataSource datasource) {
Expand All @@ -52,7 +45,8 @@ private double getMoney(DataSource datasource) {
ResultSet resultSet = ps.executeQuery()) {
resultSet.next();
return resultSet.getDouble("money");
} catch (Exception ignored) {}
} catch (Exception ignored) {
}
return 0.0;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,4 @@ static CommonsExecWebServerFactoryBean providerBean() {
.mainClass("org.springframework.boot.loader.launch.JarLauncher")
.classpath(cp -> cp.files("../seata-provider/build/libs/seata-provider-shardingsphere-sb-0.0.1-SNAPSHOT.jar"));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@ CREATE TABLE IF NOT EXISTS `undo_log`
`log_modified` DATETIME(6) NOT NULL COMMENT 'modify datetime',
UNIQUE KEY `ux_undo_log` (`xid`, `branch_id`)
) ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = utf8mb4 COMMENT ='AT transaction mode undo table';
ALTER TABLE `undo_log` ADD INDEX `ix_log_created` (`log_created`);
ALTER TABLE `undo_log` ADD INDEX `ix_log_created` (`log_created`);
14 changes: 10 additions & 4 deletions springboot-example/seata-provider/build.gradle
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
plugins {
id 'java'
id 'org.springframework.boot' version '3.3.0'
id 'org.springframework.boot' version '3.3.1'
id 'io.spring.dependency-management' version '1.1.5'
}

Expand Down Expand Up @@ -28,15 +28,21 @@ dependencies {
compileOnly 'org.projectlombok:lombok'
runtimeOnly 'com.mysql:mysql-connector-j'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
implementation('org.apache.shardingsphere:shardingsphere-jdbc:5.5.0') {
exclude group: "org.apache.shardingsphere", module: "shardingsphere-test-util"
}
implementation 'org.apache.shardingsphere:shardingsphere-transaction-base-seata-at:5.5.0'
implementation ('io.seata:seata-spring-boot-starter:2.0.0') {
implementation('io.seata:seata-spring-boot-starter:2.0.0') {
exclude group: 'org.antlr', module: 'antlr4-runtime'
}
implementation ('com.baomidou:mybatis-plus-boot-starter:3.5.6') {
implementation('com.baomidou:mybatis-plus-boot-starter:3.5.6') {
exclude group: 'org.mybatis', module: 'mybatis-spring'
}
implementation 'org.mybatis:mybatis-spring:3.0.3'
}
}

tasks.named('test') {
useJUnitPlatform()
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,12 @@

import io.seata.common.util.StringUtils;
import io.seata.core.context.RootContext;
import io.seata.core.exception.TransactionException;
import io.seata.core.model.BranchType;
import io.seata.integration.http.JakartaTransactionPropagationInterceptor;
import io.seata.integration.http.TransactionPropagationInterceptor;
import io.seata.tm.api.GlobalTransactionContext;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.shardingsphere.transaction.base.seata.at.SeataTransactionHolder;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.interceptor.TransactionInterceptor;
import org.springframework.lang.NonNull;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
Expand All @@ -22,7 +20,7 @@ public void addInterceptors(InterceptorRegistry registry) {
}

static class ShardingSphereInterceptor implements HandlerInterceptor {
public boolean preHandle(jakarta.servlet.http.HttpServletRequest request, jakarta.servlet.http.HttpServletResponse response, Object handler) throws TransactionException {
public boolean preHandle(@NonNull HttpServletRequest request, @NonNull HttpServletResponse response, @NonNull Object handler) {
String xid = RootContext.getXID();
if (xid == null) {
xid = request.getHeader(RootContext.KEY_XID);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
package com.youyi.seataprovider;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ProviderController {
@Autowired
AccountMapper accountMapper;
final AccountMapper accountMapper;

public ProviderController(AccountMapper accountMapper) {
this.accountMapper = accountMapper;
}

@GetMapping("provide")
@Transactional
Expand Down