http://jira.mfd.msk:8088/browse/CLS-758 ControlServiceTest added, testcontainers added to pom.xml

This commit is contained in:
Ivan Nikolaev-Axenov 2024-10-04 17:45:28 +03:00
parent b484ba18b1
commit c86a82ae18
6 changed files with 256 additions and 8 deletions

View file

@ -18,6 +18,7 @@
<properties>
<opencsv.version>5.5.2</opencsv.version>
<logstash-logback-encoder.version>7.0.1</logstash-logback-encoder.version>
<testcontainers.version>1.20.2</testcontainers.version>
</properties>
<dependencies>
@ -83,6 +84,18 @@
<artifactId>test-clearing</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers</artifactId>
<version>${testcontainers.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>postgresql</artifactId>
<version>${testcontainers.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>

View file

@ -58,6 +58,9 @@ public class ResultContainer {
this.quantityDifference = quantityDifference;
}
public ResultContainer() {
}
public Long getSessionId() {
return sessionId;
}

View file

@ -4,6 +4,7 @@ import com.opencsv.bean.StatefulBeanToCsv;
import com.opencsv.bean.StatefulBeanToCsvBuilder;
import com.opencsv.exceptions.CsvDataTypeMismatchException;
import com.opencsv.exceptions.CsvRequiredFieldEmptyException;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
@ -33,7 +34,7 @@ public class ControlService {
resultDirectory = Path.of(settings.getResultDirectory());
}
public void generalControl(SessionType sessionType) {
public File generalControl(SessionType sessionType) {
log.info("Starting general control with session type {}", sessionType);
ResultContainer resultContainer = switch (sessionType) {
@ -48,34 +49,41 @@ public class ControlService {
if (resultContainer.getQuantityDifference() != 0) {
resultContainer.setSessionType(sessionType);
writeToCsvFile(resultContainer);
return writeToCsvFile(resultContainer);
}
return null;
}
public void internalControl(Long sessionId) {
public File internalControl(Long sessionId) {
log.info("Starting internal control with session id {}", sessionId);
ResultContainer resultContainer = controlRepository.getInternalCountDiff(sessionId);
if (resultContainer.getQuantityDifference() != 0) {
resultContainer.setSessionId(sessionId);
writeToCsvFile(resultContainer);
return writeToCsvFile(resultContainer);
}
return null;
}
public void internalControlFinl(Long sessionId) {
public File internalControlFinl(Long sessionId) {
log.info("Starting internal control FINL with session id {}", sessionId);
ResultContainer resultContainer = controlRepository.getFinlInternalCountDiff(sessionId);
if (resultContainer.getQuantityDifference() != 0) {
resultContainer.setSessionId(sessionId);
writeToCsvFile(resultContainer);
return writeToCsvFile(resultContainer);
}
return null;
}
private void writeToCsvFile(ResultContainer resultContainer) {
try (Writer writer = new FileWriter(resultDirectory.resolve("result-" + Instant.now().getEpochSecond() + ".csv").toFile())) {
private File writeToCsvFile(ResultContainer resultContainer) {
File resultFile = resultDirectory.resolve("result-" + Instant.now().toEpochMilli() + ".csv").toFile();
try (Writer writer = new FileWriter(resultFile)) {
CustomMappingStrategy<ResultContainer> mappingStrategy = new CustomMappingStrategy<>();
mappingStrategy.setType(ResultContainer.class);
@ -86,5 +94,6 @@ public class ControlService {
} catch (CsvRequiredFieldEmptyException | CsvDataTypeMismatchException | IOException e) {
log.error(e.getMessage(), e);
}
return resultFile;
}
}

View file

@ -0,0 +1,52 @@
package ru.spcex.clearing.control.config;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import java.beans.PropertyVetoException;
import javax.sql.DataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.testcontainers.containers.PostgreSQLContainer;
import ru.spcex.clearing.control.config.settings.ControlServiceSettings;
@Configuration
public class TestDataSourceConfiguration {
private final ControlServiceSettings settings;
public TestDataSourceConfiguration(ControlServiceSettings settings) {
this.settings = settings;
}
@Bean
public DataSource getDataSource() {
PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>(PostgreSQLContainer.IMAGE);
postgres.start();
ComboPooledDataSource cpds = new ComboPooledDataSource();
try {
cpds.setDriverClass(postgres.getDriverClassName());
cpds.setJdbcUrl(postgres.getJdbcUrl());
cpds.setUser(postgres.getUsername());
cpds.setPassword(postgres.getPassword());
cpds.setMaxPoolSize(100);
cpds.setMinPoolSize(50);
cpds.setAcquireIncrement(5);
} catch (PropertyVetoException e) {
throw new RuntimeException(e);
}
return cpds;
}
@Bean
public JdbcTemplate getJdbcTemplate() {
return new JdbcTemplate(getDataSource());
}
@Bean
public NamedParameterJdbcTemplate getNamedParameterJdbcTemplate() {
return new NamedParameterJdbcTemplate(getDataSource());
}
}

View file

@ -0,0 +1,171 @@
package ru.spcex.clearing.control.service;
import static org.assertj.core.api.Assertions.assertThat;
import com.opencsv.CSVReader;
import com.opencsv.exceptions.CsvException;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.util.List;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.jdbc.core.JdbcTemplate;
import ru.spcex.clearing.control.config.TestDataSourceConfiguration;
import ru.spcex.clearing.control.config.settings.ControlServiceSettings;
import ru.spcex.clearing.control.mapper.ResultContainerMapper;
import ru.spcex.clearing.control.model.ResultContainer;
import ru.spcex.clearing.control.repository.ControlRepository;
import ru.spcex.platform.enumeration.SessionType;
@SpringBootTest(classes = {
TestDataSourceConfiguration.class,
ControlService.class,
ControlRepository.class,
ResultContainerMapper.class,
ControlServiceSettings.class
}, properties = {
"control-service.result-directory=src/test/resources"
})
@EnableConfigurationProperties
class ControlServiceTest {
@Autowired
private ControlService controlService;
@Autowired
private JdbcTemplate jdbcTemplate;
@BeforeEach
void setUp() {
jdbcTemplate.execute("DROP TABLE IF EXISTS s_trades");
jdbcTemplate.execute("DROP TABLE IF EXISTS execution_deposit");
jdbcTemplate.execute("DROP TABLE IF EXISTS execution_fond");
jdbcTemplate.execute("DROP TABLE IF EXISTS execution_currency");
jdbcTemplate.execute("DROP TABLE IF EXISTS payment_instruction");
jdbcTemplate.execute("DROP TABLE IF EXISTS s_df03");
jdbcTemplate.execute("create table s_trades(id bigint not null primary key, created_at timestamp, updated_at timestamp, trade_num bigint, operation varchar(40), class_code varchar(255), trade_date date, sec_code varchar(255), accruedint numeric(72, 18), accruedint2 numeric(72, 18), lower_discount numeric(72, 18), order_num bigint, price numeric(72, 18), price2 numeric(72, 18), repo_rate numeric(72, 18), repo_value numeric(72, 18), repo2_value numeric(72, 18), start_discount numeric(72, 18), ts_commission numeric(72, 18), upper_discount numeric(72, 18), value numeric(72, 18), yield numeric(72, 18), qty numeric(72, 18), qty_pcs numeric(72, 18), trade_date_time timestamp, repo_term bigint, clearing_commission numeric(72, 18), exchange_commission numeric(72, 18), tech_center_commission numeric(72, 18), account varchar(50), broker_ref varchar(34), client_code varchar(255), settle_code varchar(50), user_id varchar(32), exchange_code varchar(64), firm_id varchar(255), firm_name varchar(255), cp_firm_id varchar(255), cp_firm_name varchar(255), class_name varchar(255), sec_name varchar(255), settle_date date, settle_currency varchar(4), trade_currency varchar(4), trade_time_ms bigint, bank_acc_id varchar(12), section varchar(4));");
jdbcTemplate.execute("create table execution_deposit(exchange_execution_id bigint,exchange_execution_time timestamp,trading_date date,trading_clearing_registry_id bigint,party_trading_clearing_registry varchar(20),market varchar(8),price numeric(72, 18),lots numeric(72, 2),quantity numeric(72, 2),first_leg_amount numeric(72, 2),second_leg_amount numeric(72, 2),interest_amount numeric(72, 2),side varchar(4),settlement_currency varchar(4),company_id bigint,duration bigint,first_leg_settlement_date date,second_leg_settlement_date date,first_leg_settlement_code varchar(12),second_leg_settlement_code varchar(12),security_full_name varchar(255),security_symbol varchar(255),security_code varchar(255),security_id bigint,contract varchar(255),counter_party_id bigint,counter_party_trading_clearing_registry_id bigint,counter_party_trading_clearing_registry varchar(20),coverage_status varchar(4),session_id bigint,id bigint not null primary key, created_at timestamp, updated_at timestamp, clearing_date date);");
jdbcTemplate.execute("create table execution_fond(id bigint not null primary key, created_at timestamp, updated_at timestamp, clearing_date date, exchange_execution_id bigint, side varchar(4), market varchar(4), trading_date date, security_symbol varchar(255), security_id bigint, interest_amount numeric(72, 2), exchange_order_id bigint, price numeric(72, 18), settlement_amount numeric(72, 2), lots numeric(72, 2), quantity numeric(72, 2), exchange_execution_time timestamp, duration bigint, trading_clearing_registry_id bigint, party_trading_clearing_registry varchar(20), comment varchar(255), client_code_id bigint, settlement_code varchar(12), company_id bigint, counter_party_id bigint, counter_party_trading_clearing_registry_id bigint, counter_party_trading_clearing_registry varchar(20), security_full_name varchar(255), settlement_date date, settlement_currency varchar(4), exchange_execution_microseconds timestamp, coverage_status varchar(4), session_id bigint);");
jdbcTemplate.execute("create table execution_currency( exchange_execution_id bigint, exchange_execution_time timestamp, exchange_execution_microseconds timestamp, trading_date date, settlement_date date, settlement_code varchar(12), security_id bigint, security_symbol varchar(255), security_name varchar(255), company_id bigint, party_trading_clearing_registry_id bigint, party_trading_clearing_registry varchar(20), counter_party_id bigint, counter_party_trading_clearing_registry_id bigint, counter_party_trading_clearing_registry varchar(20), market varchar(4), price numeric(72, 18), lots numeric(72, 2), settlement_amount numeric(72, 2), quantity numeric(72, 2), side varchar(4), currency_code varchar(4), settlement_organization varchar(255), coverage_status varchar(4), session_id bigint, clearing_date date, id bigint not null primary key, created_at timestamp, updated_at timestamp);");
jdbcTemplate.execute("create table payment_instruction( sender_id bigint, addressee_id bigint, payee_bic varchar(255), adressee_bic varchar(255), payee_bank_name varchar(255), addressee_bank_name varchar(255), payment_date timestamp, payment_purpose varchar(255), settlement_date date, credit_leg_amount numeric(72, 18), debit_leg_amount numeric(72, 18), credit_leg_account_id bigint, credit_cs_account varchar(255), credit_leg_account varchar(50), debit_leg_account_id bigint, debit_cs_account varchar(255), debit_leg_account varchar(50), credit_leg_direction varchar(4), debit_leg_direction varchar(4), credit_leg_currency_code varchar(4), debit_leg_currency_code varchar(4), credit_leg_security_id bigint, debit_leg_security_id bigint, transaction_status varchar(4), document_number varchar(255), id bigint not null primary key, created_at timestamp, updated_at timestamp, clearing_date date, session_id bigint);");
jdbcTemplate.execute("create table s_df03( id bigint not null primary key, seg_type varchar(1), doc_type varchar(4), docnm_ref varchar(16), docnmprev varchar(16), c_acc_deb varchar(35), sbanknam1 varchar(35), sbanknam2 varchar(35), sbanknam3 varchar(35), sbanknam4 varchar(35), sbanknam5 varchar(35), c_acc_cred varchar(35), rbanknam1 varchar(35), rbanknam2 varchar(35), rbanknam3 varchar(35), rbanknam4 varchar(35), rbanknam5 varchar(35), pay_date varchar(8), pay_val varchar(12), sum_deb varchar(22), specif_1 varchar(255), imp_result varchar(3), file_name varchar(255), generation_time timestamp, generation_id bigint, payment_instruction_id bigint);");
jdbcTemplate.execute("insert into s_trades (id, created_at, section) values (1, NOW(), 'FINL'), (2, NOW(), 'FOND'), (3, NOW(), 'CURR');");
jdbcTemplate.execute("insert into execution_deposit (id, created_at) values (1, NOW()), (2, NOW());");
jdbcTemplate.execute("insert into execution_fond (id, created_at) values (1, NOW()), (2, NOW());");
jdbcTemplate.execute("insert into execution_currency (id, created_at) values (1, NOW()), (2, NOW());");
jdbcTemplate.execute("insert into payment_instruction (id, created_at, session_id) values (1, NOW(), 1), (2, NOW(), 1);");
jdbcTemplate.execute("insert into s_df03 (id, generation_time, payment_instruction_id) values (1, NOW(), 1), (2, NOW(), 1);");
}
@Test
void generalControl_shouldReturnFINLCSVFile() {
ResultContainer resultContainer = new ResultContainer(null, SessionType.FINL, "s_trades", 3L, "execution_deposit", 2L, 1L);
File resultFile = controlService.generalControl(SessionType.FINL);
assertThat(resultFile).isNotNull();
ResultContainer actual;
try (Reader reader = new FileReader(resultFile);
CSVReader csvReader = new CSVReader(reader)) {
actual = parseResultContainer(csvReader.readAll());
} catch (IOException | CsvException e) {
throw new RuntimeException(e);
}
resultFile.delete();
assertThat(actual).isEqualTo(resultContainer);
}
@Test
void generalControl_shouldReturnIPOBCSVFile() {
ResultContainer resultContainer = new ResultContainer(null, SessionType.IPOB, "s_trades", 1L, "execution_fond", 2L, -1L);
File resultFile = controlService.generalControl(SessionType.IPOB);
assertThat(resultFile).isNotNull();
ResultContainer actual;
try (Reader reader = new FileReader(resultFile);
CSVReader csvReader = new CSVReader(reader)) {
actual = parseResultContainer(csvReader.readAll());
} catch (IOException | CsvException e) {
throw new RuntimeException(e);
}
resultFile.delete();
assertThat(actual).isEqualTo(resultContainer);
}
@Test
void generalControl_shouldReturnCURRCSVFile() {
ResultContainer resultContainer = new ResultContainer(null, SessionType.CURR, "s_trades", 1L, "execution_currency", 2L, -1L);
File resultFile = controlService.generalControl(SessionType.CURR);
assertThat(resultFile).isNotNull();
ResultContainer actual;
try (Reader reader = new FileReader(resultFile);
CSVReader csvReader = new CSVReader(reader)) {
actual = parseResultContainer(csvReader.readAll());
} catch (IOException | CsvException e) {
throw new RuntimeException(e);
}
resultFile.delete();
assertThat(actual).isEqualTo(resultContainer);
}
@Test
void internalControl_shouldReturnInternalControlCSVFile() {
ResultContainer resultContainer = new ResultContainer(1L, null, null, 1L, null, 2L, 3L);
File resultFile = controlService.internalControl(1L);
assertThat(resultFile).isNotNull();
ResultContainer actual;
try (Reader reader = new FileReader(resultFile);
CSVReader csvReader = new CSVReader(reader)) {
actual = parseResultContainer(csvReader.readAll());
} catch (IOException | CsvException e) {
throw new RuntimeException(e);
}
resultFile.delete();
assertThat(actual).isEqualTo(resultContainer);
}
@Test
void internalControlFinl_shouldReturnInternalControlCSVFile() {
ResultContainer resultContainer = new ResultContainer(1L, null, "payment_instruction", 2L, "s_df03", 3L, -1L);
File resultFile = controlService.internalControlFinl(1L);
assertThat(resultFile).isNotNull();
ResultContainer actual;
try (Reader reader = new FileReader(resultFile);
CSVReader csvReader = new CSVReader(reader)) {
actual = parseResultContainer(csvReader.readAll());
} catch (IOException | CsvException e) {
throw new RuntimeException(e);
}
resultFile.delete();
assertThat(actual).isEqualTo(resultContainer);
}
private ResultContainer parseResultContainer(List<String[]> rows) {
ResultContainer actual = new ResultContainer();
actual.setSessionId(rows.get(1)[0].isBlank() ? null : Long.valueOf(rows.get(1)[0]));
actual.setSessionType(rows.get(1)[1].isBlank() ? null : SessionType.valueOf(rows.get(1)[1]));
actual.setFirstTableTitle(rows.get(1)[2].isBlank() ? null : rows.get(1)[2]);
actual.setFirstTableRecordQuantity(rows.get(1)[3].isBlank() ? null : Long.valueOf(rows.get(1)[3]));
actual.setSecondTableRecordTitle(rows.get(1)[4].isBlank() ? null : rows.get(1)[4]);
actual.setSecondTableRecordQuantity(rows.get(1)[5].isBlank() ? null : Long.valueOf(rows.get(1)[5]));
actual.setQuantityDifference(rows.get(1)[6].isBlank() ? null : Long.valueOf(rows.get(1)[6]));
return actual;
}
}