Skip to content

Commit 8eda602

Browse files
Add semi-sync plugin test in main (#16372)
Signed-off-by: Manan Gupta <manan@planetscale.com>
1 parent 2e009e3 commit 8eda602

File tree

2 files changed

+266
-0
lines changed

2 files changed

+266
-0
lines changed
Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
name: Semi Sync Upgrade Downgrade Testing
2+
on:
3+
push:
4+
pull_request:
5+
6+
concurrency:
7+
group: format('{0}-{1}', ${{ github.ref }}, 'Semi Sync Upgrade Downgrade Testing')
8+
cancel-in-progress: true
9+
10+
permissions: read-all
11+
12+
jobs:
13+
upgrade_downgrade_test_e2e:
14+
timeout-minutes: 60
15+
name: Run Semi Sync Upgrade Downgrade Test
16+
runs-on: gh-hosted-runners-16cores-1
17+
18+
steps:
19+
- name: Skip CI
20+
run: |
21+
if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then
22+
echo "skipping CI due to the 'Skip CI' label"
23+
exit 1
24+
fi
25+
26+
- name: Check if workflow needs to be skipped
27+
id: skip-workflow
28+
run: |
29+
skip='false'
30+
if [[ "${{github.event.pull_request}}" == "" ]] && [[ "${{github.ref}}" != "refs/heads/main" ]] && [[ ! "${{github.ref}}" =~ ^refs/heads/release-[0-9]+\.[0-9]$ ]] && [[ ! "${{github.ref}}" =~ "refs/tags/.*" ]]; then
31+
skip='true'
32+
fi
33+
echo Skip ${skip}
34+
echo "skip-workflow=${skip}" >> $GITHUB_OUTPUT
35+
36+
- name: Check out commit's code
37+
if: steps.skip-workflow.outputs.skip-workflow == 'false'
38+
uses: actions/checkout@v4
39+
with:
40+
fetch-depth: 0
41+
42+
- name: Set output with latest release branch
43+
if: steps.skip-workflow.outputs.skip-workflow == 'false'
44+
id: output-previous-release-ref
45+
run: |
46+
previous_release_ref=$(./tools/get_previous_release.sh ${{github.base_ref}} ${{github.ref}})
47+
echo $previous_release_ref
48+
echo "previous_release_ref=${previous_release_ref}" >> $GITHUB_OUTPUT
49+
50+
- name: Check for changes in relevant files
51+
if: steps.skip-workflow.outputs.skip-workflow == 'false'
52+
uses: dorny/paths-filter@v3.0.1
53+
id: changes
54+
with:
55+
token: ''
56+
filters: |
57+
end_to_end:
58+
- 'go/**'
59+
- 'go/**/*.go'
60+
- 'test.go'
61+
- 'Makefile'
62+
- 'build.env'
63+
- 'go.sum'
64+
- 'go.mod'
65+
- 'proto/*.proto'
66+
- 'tools/**'
67+
- 'config/**'
68+
- 'bootstrap.sh'
69+
- '.github/workflows/upgrade_downgrade_test_semi_sync.yml'
70+
71+
- name: Set up Go
72+
if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true'
73+
uses: actions/setup-go@v5
74+
with:
75+
go-version: 1.22.5
76+
77+
- name: Set up python
78+
if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true'
79+
uses: actions/setup-python@v5
80+
81+
- name: Tune the OS
82+
if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true'
83+
run: |
84+
sudo sysctl -w net.ipv4.ip_local_port_range="22768 65535"
85+
86+
- name: Get base dependencies
87+
if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true'
88+
run: |
89+
sudo apt-get update
90+
sudo apt-get install -y mysql-server mysql-client make unzip g++ etcd curl git wget eatmydata
91+
sudo service mysql stop
92+
sudo service etcd stop
93+
sudo ln -s /etc/apparmor.d/usr.sbin.mysqld /etc/apparmor.d/disable/
94+
sudo apparmor_parser -R /etc/apparmor.d/usr.sbin.mysqld
95+
go mod download
96+
97+
# install JUnit report formatter
98+
go install github.com/vitessio/go-junit-report@HEAD
99+
100+
wget https://repo.percona.com/apt/percona-release_latest.$(lsb_release -sc)_all.deb
101+
sudo apt-get install -y gnupg2
102+
sudo dpkg -i percona-release_latest.$(lsb_release -sc)_all.deb
103+
sudo percona-release enable-only tools
104+
sudo apt-get update
105+
sudo apt-get install -y percona-xtrabackup-80
106+
107+
# Checkout to the last release of Vitess
108+
- name: Check out other version's code (${{ steps.output-previous-release-ref.outputs.previous_release_ref }})
109+
if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true'
110+
uses: actions/checkout@v4
111+
with:
112+
ref: ${{ steps.output-previous-release-ref.outputs.previous_release_ref }}
113+
114+
- name: Get dependencies for the last release
115+
if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true'
116+
run: |
117+
go mod download
118+
119+
- name: Building last release's binaries
120+
if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true'
121+
timeout-minutes: 10
122+
run: |
123+
source build.env
124+
NOVTADMINBUILD=1 make build
125+
mkdir -p /tmp/vitess-build-other/
126+
cp -R bin /tmp/vitess-build-other/
127+
rm -Rf bin/*
128+
129+
# Checkout to this build's commit
130+
- name: Check out commit's code
131+
if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true'
132+
uses: actions/checkout@v4
133+
134+
- name: Get dependencies for this commit
135+
if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true'
136+
run: |
137+
go mod download
138+
139+
- name: Building the binaries for this commit
140+
if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true'
141+
timeout-minutes: 10
142+
run: |
143+
source build.env
144+
NOVTADMINBUILD=1 make build
145+
mkdir -p /tmp/vitess-build-current/
146+
cp -R bin /tmp/vitess-build-current/
147+
148+
# Copy last releases vttablet
149+
- name: Copy last release's VTTablet
150+
if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true'
151+
run: |
152+
source build.env
153+
154+
cp /tmp/vitess-build-other/bin/vttablet $PWD/bin/vttabletold
155+
vttabletold --version
156+
157+
- name: Run semi sync tests
158+
if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true'
159+
run: |
160+
rm -rf /tmp/vtdataroot
161+
mkdir -p /tmp/vtdataroot
162+
set -x
163+
source build.env
164+
go test -v -count=1 -run="" ./go/test/endtoend/reparent/semisync -alsologtostderr
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
/*
2+
Copyright 2024 The Vitess Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package semisync
18+
19+
import (
20+
"context"
21+
"testing"
22+
23+
"github.com/stretchr/testify/require"
24+
25+
"vitess.io/vitess/go/mysql"
26+
"vitess.io/vitess/go/test/endtoend/cluster"
27+
"vitess.io/vitess/go/test/endtoend/reparent/utils"
28+
)
29+
30+
func TestSemiSyncUpgradeDowngrade(t *testing.T) {
31+
ver, err := cluster.GetMajorVersion("vtgate")
32+
require.NoError(t, err)
33+
if ver != 21 {
34+
t.Skip("We only want to run this test for v21 release")
35+
}
36+
defer cluster.PanicHandler(t)
37+
clusterInstance := utils.SetupReparentCluster(t, "semi_sync")
38+
defer utils.TeardownCluster(clusterInstance)
39+
tablets := clusterInstance.Keyspaces[0].Shards[0].Vttablets
40+
41+
// Verify that replication is running as intended.
42+
utils.ConfirmReplication(t, tablets[0], []*cluster.Vttablet{tablets[1], tablets[2], tablets[3]})
43+
44+
replica := tablets[1]
45+
// Verify we are using the correct vttablet version.
46+
verifyVttabletVersion(t, replica, 21)
47+
// Check the plugin loaded in vttablet.
48+
require.EqualValues(t, mysql.SemiSyncTypeSource, semiSyncExtensionLoaded(t, replica))
49+
50+
t.Run("Downgrade to previous release", func(t *testing.T) {
51+
// change vttablet binary and downgrade it.
52+
changeVttabletBinary(t, replica, "vttabletold")
53+
// Verify we are using the older vttablet version.
54+
verifyVttabletVersion(t, replica, 20)
55+
// Verify that replication is running as intended.
56+
utils.ConfirmReplication(t, tablets[0], []*cluster.Vttablet{tablets[1], tablets[2], tablets[3]})
57+
// Check the plugin loaded in vttablet.
58+
require.EqualValues(t, mysql.SemiSyncTypeSource, semiSyncExtensionLoaded(t, replica))
59+
})
60+
61+
t.Run("Upgrade to current release", func(t *testing.T) {
62+
// change vttablet binary and downgrade it.
63+
changeVttabletBinary(t, replica, "vttablet")
64+
// Verify we are using the older vttablet version.
65+
verifyVttabletVersion(t, replica, 21)
66+
// Verify that replication is running as intended.
67+
utils.ConfirmReplication(t, tablets[0], []*cluster.Vttablet{tablets[1], tablets[2], tablets[3]})
68+
// Check the plugin loaded in vttablet.
69+
require.EqualValues(t, mysql.SemiSyncTypeSource, semiSyncExtensionLoaded(t, replica))
70+
})
71+
}
72+
73+
// semiSyncExtensionLoaded checks if the semisync extension has been loaded.
74+
// It should work for both MariaDB and MySQL.
75+
func semiSyncExtensionLoaded(t *testing.T, replica *cluster.Vttablet) mysql.SemiSyncType {
76+
qr := utils.RunSQL(context.Background(), t, `SHOW VARIABLES LIKE 'rpl_semi_sync_%_enabled'`, replica)
77+
for _, row := range qr.Rows {
78+
if row[0].ToString() == "rpl_semi_sync_source_enabled" {
79+
return mysql.SemiSyncTypeSource
80+
}
81+
if row[0].ToString() == "rpl_semi_sync_master_enabled" {
82+
return mysql.SemiSyncTypeMaster
83+
}
84+
}
85+
return mysql.SemiSyncTypeOff
86+
}
87+
88+
func changeVttabletBinary(t *testing.T, replica *cluster.Vttablet, binary string) {
89+
t.Helper()
90+
err := replica.VttabletProcess.TearDown()
91+
require.NoError(t, err)
92+
replica.VttabletProcess.Binary = binary
93+
err = replica.VttabletProcess.Setup()
94+
require.NoError(t, err)
95+
}
96+
97+
func verifyVttabletVersion(t *testing.T, replica *cluster.Vttablet, version int) {
98+
t.Helper()
99+
verGot, err := cluster.GetMajorVersion(replica.VttabletProcess.Binary)
100+
require.NoError(t, err)
101+
require.EqualValues(t, version, verGot)
102+
}

0 commit comments

Comments
 (0)