Skip to content

Commit 8d142c3

Browse files
author
maxim-lixakov
committed
[DOP-19903] - add integration MySQL tests & CI
1 parent 7816b4c commit 8d142c3

File tree

14 files changed

+578
-5
lines changed

14 files changed

+578
-5
lines changed

.env.docker

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,14 @@ TEST_MSSQL_USER=syncmaster
9191
TEST_MSSQL_PASSWORD=7ellowEl7akey
9292
TEST_MSSQL_DB=syncmaster
9393

94+
TEST_MYSQL_HOST_FOR_CONFTEST=test-mysql
95+
TEST_MYSQL_PORT_FOR_CONFTEST=3306
96+
TEST_MYSQL_HOST_FOR_WORKER=test-mysql
97+
TEST_MYSQL_PORT_FOR_WORKER=3306
98+
TEST_MYSQL_USER=syncmaster
99+
TEST_MYSQL_PASSWORD=ohbuz9Eochaj9saibooK3thooGa5aesh
100+
TEST_MYSQL_DB=syncmaster
101+
94102
TEST_HIVE_CLUSTER=test-hive
95103
TEST_HIVE_USER=syncmaster
96104
TEST_HIVE_PASSWORD=changeme

.env.local

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,14 @@ export TEST_MSSQL_USER=syncmaster
7878
export TEST_MSSQL_PASSWORD=7ellowEl7akey
7979
export TEST_MSSQL_DB=syncmaster
8080

81+
export TEST_MYSQL_HOST_FOR_CONFTEST=localhost
82+
export TEST_MYSQL_PORT_FOR_CONFTEST=3306
83+
export TEST_MYSQL_HOST_FOR_WORKER=test-mysql
84+
export TEST_MYSQL_PORT_FOR_WORKER=3306
85+
export TEST_MYSQL_USER=syncmaster
86+
export TEST_MYSQL_PASSWORD=ohbuz9Eochaj9saibooK3thooGa5aesh
87+
export TEST_MYSQL_DB=syncmaster
88+
8189
export TEST_HIVE_CLUSTER=test-hive
8290
export TEST_HIVE_USER=syncmaster
8391
export TEST_HIVE_PASSWORD=changeme

.github/workflows/mysql-tests.yml

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
name: MySQL Tests
2+
on:
3+
workflow_call:
4+
5+
env:
6+
DEFAULT_PYTHON: '3.12'
7+
8+
jobs:
9+
tests:
10+
name: Run MySQL tests
11+
runs-on: ubuntu-latest
12+
13+
steps:
14+
- name: Checkout code
15+
uses: actions/checkout@v4
16+
17+
- name: Set up QEMU
18+
uses: docker/setup-qemu-action@v3
19+
20+
- name: Set up Docker Buildx
21+
uses: docker/setup-buildx-action@v3
22+
23+
- name: Cache jars
24+
uses: actions/cache@v4
25+
with:
26+
path: ./cached_jars
27+
key: ${{ runner.os }}-python-${{ env.DEFAULT_PYTHON }}-test-mysql
28+
restore-keys: |
29+
${{ runner.os }}-python-${{ env.DEFAULT_PYTHON }}-test-mysql
30+
${{ runner.os }}-python-
31+
- name: Build Worker Image
32+
uses: docker/build-push-action@v6
33+
with:
34+
context: .
35+
tags: mtsrus/syncmaster-worker:${{ github.sha }}
36+
target: test
37+
file: docker/Dockerfile.worker
38+
load: true
39+
cache-from: mtsrus/syncmaster-worker:develop
40+
41+
- name: Docker compose up
42+
run: |
43+
docker compose -f docker-compose.test.yml --profile all down -v --remove-orphans
44+
docker compose -f docker-compose.test.yml --profile mysql up -d --wait --wait-timeout 200
45+
env:
46+
WORKER_IMAGE_TAG: ${{ github.sha }}
47+
48+
- name: Run MySQL Tests
49+
run: |
50+
docker compose -f ./docker-compose.test.yml --profile mysql exec -T worker coverage run -m pytest -vvv -s -m "worker and mysql"
51+
- name: Dump worker logs on failure
52+
if: failure()
53+
uses: jwalton/gh-docker-logs@v2
54+
with:
55+
images: mtsrus/syncmaster-worker
56+
dest: ./logs
57+
58+
# This is important, as coverage is exported after receiving SIGTERM
59+
- name: Shutdown
60+
if: always()
61+
run: |
62+
docker compose -f docker-compose.test.yml --profile all down -v --remove-orphans
63+
- name: Upload worker logs
64+
uses: actions/upload-artifact@v4
65+
if: failure()
66+
with:
67+
name: worker-logs-mysql
68+
path: logs/*
69+
70+
- name: Upload coverage results
71+
uses: actions/upload-artifact@v4
72+
with:
73+
name: coverage-mysql
74+
path: reports/*
75+
# https://github.com/actions/upload-artifact/issues/602
76+
include-hidden-files: true

.github/workflows/tests.yml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ jobs:
2424
name: Clickhouse tests
2525
uses: ./.github/workflows/clickhouse-tests.yml
2626

27+
mysql_tests:
28+
name: MySQL tests
29+
uses: ./.github/workflows/mysql-tests.yml
30+
2731
mssql_tests:
2832
name: MSSQL tests
2933
uses: ./.github/workflows/mssql-tests.yml
@@ -52,7 +56,7 @@ jobs:
5256
name: Tests done
5357
runs-on: ubuntu-latest
5458

55-
needs: [oracle_tests, clickhouse_tests, mssql_tests, hive_tests, hdfs_tests, s3_tests, unit_tests]
59+
needs: [oracle_tests, clickhouse_tests, mssql_tests, mysql_tests, hive_tests, hdfs_tests, s3_tests, unit_tests]
5660
steps:
5761
- name: Checkout code
5862
uses: actions/checkout@v4

Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,10 @@ test-integration-clickhouse: test-db ##@Test Run integration tests for Clickh
9393
docker compose -f docker-compose.test.yml --profile clickhouse up -d --wait $(DOCKER_COMPOSE_ARGS)
9494
${POETRY} run pytest ./tests/test_integration -m clickhouse $(PYTEST_ARGS)
9595

96+
test-integration-mysql: test-db ##@Test Run integration tests for MySQL
97+
docker compose -f docker-compose.test.yml --profile mysql up -d --wait $(DOCKER_COMPOSE_ARGS)
98+
${POETRY} run pytest ./tests/test_integration -m mysql $(PYTEST_ARGS)
99+
96100
test-integration-mssql: test-db ##@Test Run integration tests for MSSQL
97101
docker compose -f docker-compose.test.yml --profile mssql up -d --wait $(DOCKER_COMPOSE_ARGS)
98102
${POETRY} run pytest ./tests/test_integration -m mssql $(PYTEST_ARGS)

docker-compose.test.yml

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ services:
9696
condition: service_healthy
9797
rabbitmq:
9898
condition: service_healthy
99-
profiles: [worker, scheduler, s3, oracle, hdfs, hive, clickhouse, mssql, all]
99+
profiles: [worker, scheduler, s3, oracle, hdfs, hive, clickhouse, mysql, mssql, all]
100100

101101
test-postgres:
102102
image: postgres
@@ -110,7 +110,7 @@ services:
110110
interval: 30s
111111
timeout: 5s
112112
retries: 3
113-
profiles: [s3, oracle, clickhouse, mssql, hdfs, hive, all]
113+
profiles: [s3, oracle, clickhouse, mysql, mssql, hdfs, hive, all]
114114

115115
test-s3:
116116
image: bitnami/minio:latest
@@ -167,6 +167,20 @@ services:
167167
platform: linux/amd64
168168
profiles: [mssql, all]
169169

170+
test-mysql:
171+
image: mysql
172+
restart: unless-stopped
173+
environment:
174+
MYSQL_ROOT_PASSWORD: ohbuz9Eochaj9saibooK3thooGa5aesh
175+
MYSQL_DATABASE: syncmaster
176+
MYSQL_USER: syncmaster
177+
MYSQL_PASSWORD: ohbuz9Eochaj9saibooK3thooGa5aesh
178+
ports:
179+
- 3306:3306
180+
platform: linux/amd64
181+
profiles: [mysql, all]
182+
183+
170184
metastore-hive:
171185
image: postgres
172186
restart: unless-stopped

syncmaster/dto/connections.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,17 @@ class MSSQLConnectionDTO(ConnectionDTO):
4242
type: ClassVar[str] = "mssql"
4343

4444

45+
@dataclass
46+
class MySQLConnectionDTO(ConnectionDTO):
47+
host: str
48+
port: int
49+
user: str
50+
password: str
51+
database_name: str
52+
additional_params: dict
53+
type: ClassVar[str] = "mysql"
54+
55+
4556
@dataclass
4657
class OracleConnectionDTO(ConnectionDTO):
4758
host: str

syncmaster/dto/transfers.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,11 @@ class MSSQLTransferDTO(DBTransferDTO):
6161
type: ClassVar[str] = "mssql"
6262

6363

64+
@dataclass
65+
class MySQLTransferDTO(DBTransferDTO):
66+
type: ClassVar[str] = "mysql"
67+
68+
6469
@dataclass
6570
class HiveTransferDTO(DBTransferDTO):
6671
type: ClassVar[str] = "hive"

syncmaster/worker/controller.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
HDFSConnectionDTO,
1010
HiveConnectionDTO,
1111
MSSQLConnectionDTO,
12+
MySQLConnectionDTO,
1213
OracleConnectionDTO,
1314
PostgresConnectionDTO,
1415
S3ConnectionDTO,
@@ -18,6 +19,7 @@
1819
HDFSTransferDTO,
1920
HiveTransferDTO,
2021
MSSQLTransferDTO,
22+
MySQLTransferDTO,
2123
OracleTransferDTO,
2224
PostgresTransferDTO,
2325
S3TransferDTO,
@@ -27,6 +29,7 @@
2729
from syncmaster.worker.handlers.db.clickhouse import ClickhouseHandler
2830
from syncmaster.worker.handlers.db.hive import HiveHandler
2931
from syncmaster.worker.handlers.db.mssql import MSSQLHandler
32+
from syncmaster.worker.handlers.db.mysql import MySQLHandler
3033
from syncmaster.worker.handlers.db.oracle import OracleHandler
3134
from syncmaster.worker.handlers.db.postgres import PostgresHandler
3235
from syncmaster.worker.handlers.file.hdfs import HDFSHandler
@@ -57,6 +60,11 @@
5760
MSSQLConnectionDTO,
5861
MSSQLTransferDTO,
5962
),
63+
"mysql": (
64+
MySQLHandler,
65+
MySQLConnectionDTO,
66+
MySQLTransferDTO,
67+
),
6068
"postgres": (
6169
PostgresHandler,
6270
PostgresConnectionDTO,
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# SPDX-FileCopyrightText: 2023-2024 MTS PJSC
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
from __future__ import annotations
5+
6+
from typing import TYPE_CHECKING
7+
8+
from onetl.connection import MySQL
9+
10+
from syncmaster.dto.connections import MySQLConnectionDTO
11+
from syncmaster.dto.transfers import MySQLTransferDTO
12+
from syncmaster.worker.handlers.db.base import DBHandler
13+
14+
if TYPE_CHECKING:
15+
from pyspark.sql import SparkSession
16+
from pyspark.sql.dataframe import DataFrame
17+
18+
19+
class MySQLHandler(DBHandler):
20+
connection: MySQL
21+
connection_dto: MySQLConnectionDTO
22+
transfer_dto: MySQLTransferDTO
23+
24+
def connect(self, spark: SparkSession):
25+
self.connection = MySQL(
26+
host=self.connection_dto.host,
27+
port=self.connection_dto.port,
28+
user=self.connection_dto.user,
29+
password=self.connection_dto.password,
30+
database=self.connection_dto.database_name,
31+
spark=spark,
32+
).check()
33+
34+
def normalize_column_names(self, df: DataFrame) -> DataFrame:
35+
for column_name in df.columns:
36+
df = df.withColumnRenamed(column_name, column_name.lower())
37+
return df

0 commit comments

Comments
 (0)