-
Notifications
You must be signed in to change notification settings - Fork 307
CI: Add basic integration test #12577
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
Changes from all commits
deb1e8f
3500c85
aba7f40
c340eaa
0e1c542
d154664
53d6577
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,300 @@ | ||
| name: Basic Integration Tests | ||
|
|
||
| on: | ||
| workflow_dispatch: | ||
| pull_request: | ||
| paths: | ||
| - 'dm/**' | ||
| - 'cmd/dm*/*' | ||
|
Comment on lines
+7
to
+8
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. maybe it should be triggered when go.mod file is changed.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could we widen the
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I thought I've update the paths. |
||
| - 'pkg/**' | ||
| - 'go.mod' | ||
| - 'go.sum' | ||
| - '.github/workflows/dm_integration_basic.yaml' | ||
|
|
||
| jobs: | ||
| mysql-integration: | ||
| strategy: | ||
| fail-fast: false | ||
| matrix: | ||
| mysql_version: | ||
| # MySQL 5.7 doens't enable binlogs by default and there are no easy options for enabling it. | ||
| # - '5.7' | ||
| - '8.0' | ||
| - '8.4' | ||
| - '9.7' | ||
| runs-on: ubuntu-latest | ||
| services: | ||
| mysql: | ||
| image: container-registry.oracle.com/mysql/community-server:${{ matrix.mysql_version }} | ||
| env: | ||
| MYSQL_ALLOW_EMPTY_PASSWORD: yes | ||
| MYSQL_ROOT_HOST: "%" | ||
| MYSQL_DATABASE: test | ||
| ports: | ||
| - 3306:3306 | ||
| options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3 | ||
| tidb: | ||
| image: 'pingcap/tidb:v8.5.6' | ||
| ports: | ||
| - 4000:4000 | ||
| env: | ||
| DM_MASTER_ADDR: "127.0.0.1:8261" | ||
| DM_WORKER_ADDR: "127.0.0.1:8262" | ||
| steps: | ||
| # Some steps may fail on some versions, but the end result should be the same. | ||
| # That's why we set continue-on-error and run this in multiple commands. | ||
| - name: Try to enable GTID | ||
| continue-on-error: true | ||
| run: | | ||
| mysql -h 127.0.0.1 -u root -e "SET GLOBAL ENFORCE_GTID_CONSISTENCY=ON" | ||
| mysql -h 127.0.0.1 -u root -e "SET GLOBAL gtid_mode=OFF_PERMISSIVE" | ||
| mysql -h 127.0.0.1 -u root -e "SET GLOBAL gtid_mode=ON_PERMISSIVE" | ||
| mysql -h 127.0.0.1 -u root -e "SET GLOBAL gtid_mode=ON" | ||
| - name: Check out code | ||
| uses: actions/checkout@v6 | ||
| - name: Set up Go | ||
| uses: actions/setup-go@v6 | ||
| with: | ||
| go-version-file: 'go.mod' | ||
| - name: Build DM binary | ||
| run: make dm | ||
| - name: Show versions | ||
| shell: bash -xe {0} | ||
| run: | | ||
| ./bin/dm-master -V | ||
| ./bin/dm-worker -V | ||
| ./bin/dmctl -V | ||
| mysql -h 127.0.0.1 -u root -BNe "SELECT VERSION()" | ||
| mysql -h 127.0.0.1 -P 4000 -u root -BNe "SELECT VERSION()" | ||
| - name: Run DM | ||
| run: | | ||
| ./bin/dm-master -master-addr ${DM_MASTER_ADDR} -log-file dm_master.log -log-format json & | ||
| ./bin/dm-worker -join ${DM_MASTER_ADDR} -worker-addr ${DM_WORKER_ADDR} -log-file dm_worker.log -log-format json & | ||
|
dveeden marked this conversation as resolved.
|
||
| - name: Wait for DM readiness | ||
| run: | | ||
| for i in $(seq 1 30); do | ||
| if curl -sf http://${DM_MASTER_ADDR}/status > /dev/null 2>&1; then | ||
| echo "dm-master is ready after ${i}s" | ||
| break | ||
| fi | ||
| echo "waiting for dm-master... (${i}/30)" | ||
| sleep 1 | ||
| done | ||
| for i in $(seq 1 30); do | ||
| if curl -sf http://${DM_WORKER_ADDR}/status > /dev/null 2>&1; then | ||
| echo "dm-worker is ready after ${i}s" | ||
| exit 0 | ||
| fi | ||
| echo "waiting for dm-worker... (${i}/30)" | ||
| sleep 1 | ||
| done | ||
| echo "timed out waiting for DM readiness" | ||
| exit 1 | ||
| - name: Show DM status | ||
| shell: bash -xe {0} | ||
| run: | | ||
| ./bin/dmctl list-member | ||
| ./bin/dmctl query-status | ||
| - name: Setup source | ||
| run: ./bin/dmctl operate-source create dm/tests/integration_basic/source-mysql.yaml | tee dm_setup_source.log | ||
| - name: Start task | ||
| run: ./bin/dmctl start-task dm/tests/integration_basic/task-mysql.yaml | tee dm_setup_task.log | ||
|
|
||
| # Here we check that dm_setup_task.log contains a line with `"result": true`. | ||
| # Unfortunately dm_setup_task.log doesn't contain valid JSON so we can't use jq here. | ||
| # https://github.com/pingcap/tiflow/issues/11736 | ||
| - name: Check task result | ||
| run: | | ||
| grep '"result": true' dm_setup_task.log | ||
|
|
||
| - name: Check status | ||
| run: | | ||
| ./bin/dmctl operate-source show | ||
| ./bin/dmctl query-status | ||
| ./bin/dmctl query-status mysql-to-tidb | ||
| - name: Run input | ||
| run: mysql -h 127.0.0.1 -u root -v < dm/tests/integration_basic/setup.sql | ||
| - name: Check status | ||
| run: | | ||
| ./bin/dmctl operate-source show | ||
| ./bin/dmctl query-status | ||
| ./bin/dmctl query-status mysql-to-tidb | ||
| - name: install mysql-tester | ||
| run: | | ||
| go install github.com/pingcap/mysql-tester/src@f2d90ea9522d30c9a8e8d70cc31c7f016ca2801f | ||
| mv ~/go/bin/src ~/go/bin/mysql-tester | ||
| - name: check logs | ||
| continue-on-error: true | ||
| run: | | ||
| jq 'select(.level == "DPANIC") | .message + ": " + .error' dm_worker.log | ||
| jq 'select(.level == "ERROR") | .message + ": " + .error' dm_worker.log | ||
| # - name: record validation test | ||
| # working-directory: ./dm/tests/integration_basic | ||
| # run: ~/go/bin/mysql-tester -record basic | ||
| # - name: show results | ||
| # working-directory: ./dm/tests/integration_basic | ||
| # run: cat r/basic.result | ||
| - name: run validation tests | ||
| working-directory: ./dm/tests/integration_basic | ||
| run: ~/go/bin/mysql-tester | ||
| - name: Check status | ||
| run: | | ||
| ./bin/dmctl operate-source show | ||
| ./bin/dmctl query-status | ||
| ./bin/dmctl query-status mysql-to-tidb | ||
| - name: upload artifacts | ||
| uses: actions/upload-artifact@v7 | ||
| with: | ||
| name: dm-logs-mysql-${{ matrix.mysql_version }} | ||
| path: dm*log | ||
|
|
||
| mariadb-integration: | ||
| strategy: | ||
| fail-fast: false | ||
| matrix: | ||
| mariadb_version: | ||
| - '10.11' | ||
| - '11.4' | ||
| - '11.8' | ||
| - '12.3-rc' | ||
| runs-on: ubuntu-latest | ||
| services: | ||
| tidb: | ||
| image: 'pingcap/tidb:v8.5.5' | ||
| ports: | ||
| - 4000:4000 | ||
| env: | ||
| DM_MASTER_ADDR: "127.0.0.1:8261" | ||
| DM_WORKER_ADDR: "127.0.0.1:8262" | ||
| steps: | ||
| # Enabling binlogs with a services container is hard, so use docker directly. | ||
| # Note that FLUSH PRIVILEGES is done to make sure there is at least one GTID | ||
| # as otherwise the GTID format isn't detected correctly and this error happens: | ||
| # "message":"failed to update GTID set","GTID":"0-1-6", | ||
| # "error":"invalid GTID format, must UUID:interval[:interval]" | ||
| # https://github.com/pingcap/tiflow/issues/12423 | ||
| - name: Run MariaDB | ||
| run: | | ||
| docker run \ | ||
| -d \ | ||
| --name mariadb \ | ||
| -e MARIADB_ALLOW_EMPTY_ROOT_PASSWORD=1 \ | ||
| -p 3306:3306 \ | ||
| mariadb:${{ matrix.mariadb_version }} \ | ||
| --log-bin=mariadb-bin \ | ||
| --log-bin-compress=OFF \ | ||
| --binlog-format=ROW \ | ||
| --binlog-annotate-row-events=OFF \ | ||
| --loose-binlog-legacy-event-pos=ON | ||
| until mysqladmin -h 127.0.0.1 -u root ping; do sleep 1; done | ||
| mysql -h 127.0.0.1 -u root -e "reset master" | ||
| mysql -h 127.0.0.1 -u root -e "flush privileges" | ||
| - name: Check out code | ||
| uses: actions/checkout@v6 | ||
| - name: Set up Go | ||
| uses: actions/setup-go@v6 | ||
| with: | ||
| go-version-file: 'go.mod' | ||
| - name: Build DM binary | ||
| run: make dm | ||
| - name: Show versions | ||
| shell: bash -xe {0} | ||
| run: | | ||
| ./bin/dm-master -V | ||
| ./bin/dm-worker -V | ||
| ./bin/dmctl -V | ||
| mysql -h 127.0.0.1 -u root -BNe "SELECT VERSION()" | ||
| mysql -h 127.0.0.1 -P 4000 -u root -BNe "SELECT VERSION()" | ||
| - name: Run DM | ||
| run: | | ||
| ./bin/dm-master -master-addr ${DM_MASTER_ADDR} -log-file dm_master.log -log-format json & | ||
| ./bin/dm-worker -join ${DM_MASTER_ADDR} -worker-addr ${DM_WORKER_ADDR} -log-file dm_worker.log -log-format json & | ||
| - name: Wait for DM readiness | ||
| run: | | ||
| for i in $(seq 1 30); do | ||
| if curl -sf http://${DM_MASTER_ADDR}/status > /dev/null 2>&1; then | ||
| echo "dm-master is ready after ${i}s" | ||
| break | ||
| fi | ||
| echo "waiting for dm-master... (${i}/30)" | ||
| sleep 1 | ||
| done | ||
| for i in $(seq 1 30); do | ||
| if curl -sf http://${DM_WORKER_ADDR}/status > /dev/null 2>&1; then | ||
| echo "dm-worker is ready after ${i}s" | ||
| exit 0 | ||
| fi | ||
| echo "waiting for dm-worker... (${i}/30)" | ||
| sleep 1 | ||
| done | ||
| echo "timed out waiting for DM readiness" | ||
| exit 1 | ||
| - name: Show DM status | ||
| shell: bash -xe {0} | ||
| run: | | ||
| ./bin/dmctl list-member | ||
| ./bin/dmctl query-status | ||
| - name: Setup source | ||
| run: ./bin/dmctl operate-source create dm/tests/integration_basic/source-mariadb.yaml | tee dm_setup_source.log | ||
| - name: Start task | ||
| run: ./bin/dmctl start-task dm/tests/integration_basic/task-mariadb.yaml | tee dm_setup_task.log | ||
|
|
||
| # Here we check that dm_setup_task.log contains a line with `"result": true`. | ||
| # Unfortunately dm_setup_task.log doesn't contain valid JSON so we can't use jq here. | ||
| # https://github.com/pingcap/tiflow/issues/11736 | ||
| - name: Check task result | ||
| run: | | ||
| grep '"result": true' dm_setup_task.log | ||
|
|
||
| - name: Check status | ||
| run: | | ||
| ./bin/dmctl operate-source show | ||
| ./bin/dmctl query-status | ||
| ./bin/dmctl query-status mariadb-to-tidb | ||
| - name: Run input | ||
| run: mysql -h 127.0.0.1 -u root -v < dm/tests/integration_basic/setup.sql | ||
| - name: Check status | ||
| run: | | ||
| ./bin/dmctl operate-source show | ||
| ./bin/dmctl query-status | ||
| ./bin/dmctl query-status mariadb-to-tidb | ||
| - name: install mysql-tester | ||
| run: | | ||
| go install github.com/pingcap/mysql-tester/src@f2d90ea9522d30c9a8e8d70cc31c7f016ca2801f | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can we manager the version in go.mod file?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, we could do this by using the tool functionality, see also: https://go.dev/doc/go1.24#tools Do you think this is better? diff --git a/go.mod b/go.mod
index aceb438e4..bba975342 100644
--- a/go.mod
+++ b/go.mod
@@ -180,6 +180,7 @@ require (
github.com/cncf/xds/go v0.0.0-20251022180443-0feb69152e9f // indirect
github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce // indirect
github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect
+ github.com/defined2014/mysql v0.0.0-20231121061906-fcfacaa39f49 // indirect
github.com/envoyproxy/go-control-plane/envoy v1.35.0 // indirect
github.com/envoyproxy/protoc-gen-validate v1.2.1 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
@@ -216,13 +217,14 @@ require (
github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 // indirect
github.com/perimeterx/marshmallow v1.1.5 // indirect
github.com/pingcap/metering_sdk v0.0.0-20251110022152-dac449ac5389 // indirect
+ github.com/pingcap/mysql-tester v0.0.0-20260121034350-f2d90ea9522d // indirect
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect
github.com/qri-io/jsonpointer v0.1.1 // indirect
github.com/qri-io/jsonschema v0.2.1 // indirect
github.com/robfig/cron/v3 v3.0.1 // indirect
github.com/segmentio/asm v1.2.0 // indirect
github.com/segmentio/fasthash v1.0.3 // indirect
- github.com/sergi/go-diff v1.3.1 // indirect
+ github.com/sergi/go-diff v1.4.0 // indirect
github.com/spf13/afero v1.15.0 // indirect
github.com/spiffe/go-spiffe/v2 v2.6.0 // indirect
github.com/tidwall/btree v1.7.0 // indirect
@@ -462,3 +464,5 @@ replace golang.org/x/text => golang.org/x/text v0.28.0
// tls10server=1
godebug tlsrsakex=1
+
+tool github.com/pingcap/mysql-tester/srcAnd then: cd dm/tests/integration_basic
go tool github.com/pingcap/mysql-tester/src |
||
| mv ~/go/bin/src ~/go/bin/mysql-tester | ||
| # - name: record validation test | ||
| # working-directory: ./dm/tests/integration_basic | ||
| # run: ~/go/bin/mysql-tester -record basic | ||
| # - name: show results | ||
| # working-directory: ./dm/tests/integration_basic | ||
| # run: cat r/basic.result | ||
| - name: debug | ||
| run: | | ||
| sleep 30 | ||
| mysql -h 127.0.0.1 -u root -e "DESCRIBE test_basic.t1" | ||
| mysql -h 127.0.0.1 -u root -e "SELECT * FROM test_basic.t1" | ||
| mysql -h 127.0.0.1 -u root -P 4000 -e "DESCRIBE test_basic.t1" | ||
| mysql -h 127.0.0.1 -u root -P 4000 -e "SELECT * FROM test_basic.t1" | ||
| mysql -h 127.0.0.1 -u root -e "SHOW BINARY LOGS" | ||
| mysql -h 127.0.0.1 -u root -e "SHOW BINLOG EVENTS" | ||
| - name: check logs | ||
| continue-on-error: true | ||
| run: | | ||
| jq 'select(.level == "DPANIC") | .message + ": " + .error' dm_worker.log | ||
| jq 'select(.level == "ERROR") | .message + ": " + .error' dm_worker.log | ||
| - name: run validation tests | ||
| working-directory: ./dm/tests/integration_basic | ||
| run: | | ||
| ~/go/bin/mysql-tester | ||
| - name: Check status | ||
| if: ${{ always() }} | ||
| run: | | ||
| ./bin/dmctl operate-source show | ||
| ./bin/dmctl query-status | ||
| ./bin/dmctl query-status mariadb-to-tidb | tee dm_task_status.log | ||
| - name: upload artifacts | ||
| if: ${{ always() }} | ||
| uses: actions/upload-artifact@v7 | ||
| with: | ||
| name: dm-logs-mariadb-${{ matrix.mariadb_version }} | ||
| path: dm*log | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| select * from test_basic.t1 order by id; | ||
| id name | ||
| 1 test 1 | ||
| 2 test 2 updated |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| CREATE SCHEMA test_basic COLLATE utf8mb4_general_ci; | ||
| USE test_basic; | ||
|
|
||
| CREATE TABLE t1 ( | ||
| id int PRIMARY KEY, | ||
| name varchar(255) NOT NULL | ||
| ); | ||
|
|
||
| INSERT INTO t1 VALUES (1, 'test 1'); | ||
| INSERT INTO t1 VALUES (2, 'test 2'), (3, 'test 3'); | ||
| UPDATE t1 SET name='test 2 updated' WHERE id=2; | ||
| DELETE FROM t1 WHERE id=3; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| source-id: "mariadb-source-01" | ||
| enable-gtid: false | ||
| enable-relay: false | ||
|
|
||
| from: | ||
| host: "127.0.0.1" | ||
| user: "root" | ||
| port: 3306 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| source-id: "mysql-source-01" | ||
| enable-gtid: true | ||
| enable-relay: false | ||
|
|
||
| from: | ||
| host: "127.0.0.1" | ||
| user: "root" | ||
| port: 3306 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| select * from test_basic.t1 order by id; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| --- | ||
| name: "mariadb-to-tidb" | ||
| task-mode: all | ||
|
|
||
| target-database: | ||
| host: "127.0.0.1" | ||
| port: 4000 | ||
| user: "root" | ||
|
|
||
| mysql-instances: | ||
| - source-id: "mariadb-source-01" | ||
| filter-rules: ["test"] | ||
|
|
||
| filters: | ||
| test: | ||
| schema-pattern: "test*" | ||
| table-pattern: "*" | ||
| events: ["all"] | ||
| action: Do |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| --- | ||
| name: "mysql-to-tidb" | ||
| task-mode: all | ||
|
|
||
| target-database: | ||
| host: "127.0.0.1" | ||
| port: 4000 | ||
| user: "root" | ||
|
|
||
| mysql-instances: | ||
| - source-id: "mysql-source-01" | ||
| filter-rules: ["test"] | ||
|
|
||
| filters: | ||
| test: | ||
| schema-pattern: "test*" | ||
| table-pattern: "*" | ||
| events: ["all"] | ||
| action: Do |
Uh oh!
There was an error while loading. Please reload this page.