Skip to content

Commit f17f9cc

Browse files
[release-22.0] Generate race unit tests (#19078) (#19295)
Signed-off-by: Mohamed Hamza <mhamza@fastmail.com> Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> Co-authored-by: Mohamed Hamza <mhamza@fastmail.com>
1 parent 8c204b9 commit f17f9cc

8 files changed

Lines changed: 89 additions & 101 deletions

File tree

.github/workflows/unit_race.yml

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
name: unit_race
1+
# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows"
2+
3+
name: Unit Test (Race)
24
on:
35
push:
46
branches:
@@ -8,7 +10,7 @@ on:
810
pull_request:
911
branches: '**'
1012
concurrency:
11-
group: format('{0}-{1}', ${{ github.ref }}, 'unit_race')
13+
group: format('{0}-{1}', ${{ github.ref }}, 'Unit Test (Race)')
1214
cancel-in-progress: true
1315

1416
permissions: read-all
@@ -19,10 +21,10 @@ env:
1921
GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}"
2022

2123
jobs:
22-
23-
build:
24+
test:
2425
name: Unit Test (Race)
2526
runs-on: gh-hosted-runners-16cores-1-24.04
27+
2628
steps:
2729
- name: Skip CI
2830
run: |
@@ -75,22 +77,20 @@ jobs:
7577
uses: ./.github/actions/setup-mysql
7678
with:
7779
flavor: mysql-8.0
78-
80+
7981
- name: Get dependencies
8082
if: steps.changes.outputs.unit_tests == 'true'
8183
run: |
8284
export DEBIAN_FRONTEND="noninteractive"
83-
sudo apt-get -qq update
85+
sudo apt-get install -y make unzip g++ curl git wget ant openjdk-11-jdk
8486
85-
sudo apt-get -qq install -y make unzip g++ curl git wget ant openjdk-11-jdk
86-
8787
mkdir -p dist bin
8888
curl --max-time 10 --retry 3 --retry-max-time 45 -s -L https://github.com/coreos/etcd/releases/download/v3.5.25/etcd-v3.5.25-linux-amd64.tar.gz | tar -zxC dist
8989
mv dist/etcd-v3.5.25-linux-amd64/{etcd,etcdctl} bin/
9090
9191
go mod download
9292
go install golang.org/x/tools/cmd/goimports@latest
93-
93+
9494
# install JUnit report formatter
9595
go install github.com/vitessio/go-junit-report@HEAD
9696
@@ -111,15 +111,20 @@ jobs:
111111
# Tell Launchable about the build you are producing and testing
112112
launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source .
113113
114-
- name: unit_race
114+
- name: Run test
115115
if: steps.changes.outputs.unit_tests == 'true'
116116
timeout-minutes: 45
117117
run: |
118+
set -exo pipefail
118119
# We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file
119120
# which musn't be more than 107 characters long.
120121
export VTDATAROOT="/tmp/"
122+
121123
export NOVTADMINBUILD=1
122124
export VTEVALENGINETEST="0"
125+
# We sometimes need to alter the behavior based on the platform we're
126+
# testing, e.g. MySQL 5.7 vs 8.0.
127+
export CI_DB_PLATFORM="mysql80"
123128
124129
make unit_test_race | tee -a output.txt | go-junit-report -set-exit-code > report.xml
125130
@@ -134,7 +139,7 @@ jobs:
134139
run: |
135140
# print test output
136141
cat output.txt
137-
142+
138143
- name: Test Summary
139144
if: steps.changes.outputs.unit_tests == 'true' && !cancelled()
140145
uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4

.github/workflows/unit_race_evalengine.yml

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
name: unit_race_evalengine
1+
# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows"
2+
3+
name: Unit Test (Evalengine_Race)
24
on:
35
push:
46
branches:
@@ -8,7 +10,7 @@ on:
810
pull_request:
911
branches: '**'
1012
concurrency:
11-
group: format('{0}-{1}', ${{ github.ref }}, 'unit_race_evalengine')
13+
group: format('{0}-{1}', ${{ github.ref }}, 'Unit Test (Evalengine_Race)')
1214
cancel-in-progress: true
1315

1416
permissions: read-all
@@ -19,10 +21,10 @@ env:
1921
GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}"
2022

2123
jobs:
22-
23-
build:
24+
test:
2425
name: Unit Test (Evalengine_Race)
2526
runs-on: gh-hosted-runners-16cores-1-24.04
27+
2628
steps:
2729
- name: Skip CI
2830
run: |
@@ -75,22 +77,20 @@ jobs:
7577
uses: ./.github/actions/setup-mysql
7678
with:
7779
flavor: mysql-8.0
78-
80+
7981
- name: Get dependencies
8082
if: steps.changes.outputs.unit_tests == 'true'
8183
run: |
8284
export DEBIAN_FRONTEND="noninteractive"
83-
sudo apt-get -qq update
85+
sudo apt-get install -y make unzip g++ curl git wget ant openjdk-11-jdk
8486
85-
sudo apt-get -qq install -y make unzip g++ curl git wget ant openjdk-11-jdk
86-
8787
mkdir -p dist bin
8888
curl --max-time 10 --retry 3 --retry-max-time 45 -s -L https://github.com/coreos/etcd/releases/download/v3.5.25/etcd-v3.5.25-linux-amd64.tar.gz | tar -zxC dist
8989
mv dist/etcd-v3.5.25-linux-amd64/{etcd,etcdctl} bin/
9090
9191
go mod download
9292
go install golang.org/x/tools/cmd/goimports@latest
93-
93+
9494
# install JUnit report formatter
9595
go install github.com/vitessio/go-junit-report@HEAD
9696
@@ -111,15 +111,20 @@ jobs:
111111
# Tell Launchable about the build you are producing and testing
112112
launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source .
113113
114-
- name: unit_race_evalengine
114+
- name: Run test
115115
if: steps.changes.outputs.unit_tests == 'true'
116116
timeout-minutes: 45
117117
run: |
118+
set -exo pipefail
118119
# We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file
119120
# which musn't be more than 107 characters long.
120121
export VTDATAROOT="/tmp/"
122+
121123
export NOVTADMINBUILD=1
122124
export VTEVALENGINETEST="1"
125+
# We sometimes need to alter the behavior based on the platform we're
126+
# testing, e.g. MySQL 5.7 vs 8.0.
127+
export CI_DB_PLATFORM="mysql80"
123128
124129
make unit_test_race | tee -a output.txt | go-junit-report -set-exit-code > report.xml
125130

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ unit_test_cover: build dependency_check demo
228228
go tool $(VT_GO_PARALLEL) cover -html=coverage.out
229229

230230
unit_test_race: build dependency_check
231-
tools/unit_test_race.sh
231+
RACE=1 tools/unit_test_runner.sh
232232

233233
e2e_test_race: build
234234
tools/e2e_test_race.sh

go/vt/vtctl/workflow/utils_test.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515
"github.com/stretchr/testify/require"
1616
clientv3 "go.etcd.io/etcd/client/v3"
1717

18+
"vitess.io/vitess/go/race"
1819
"vitess.io/vitess/go/sqltypes"
1920
"vitess.io/vitess/go/testfiles"
2021
"vitess.io/vitess/go/vt/log"
@@ -119,10 +120,10 @@ func TestUpdateKeyspaceRoutingRule(t *testing.T) {
119120
// TestConcurrentKeyspaceRoutingRulesUpdates runs multiple keyspace routing rules updates concurrently to test
120121
// the locking mechanism.
121122
func TestConcurrentKeyspaceRoutingRulesUpdates(t *testing.T) {
122-
if os.Getenv("GOCOVERDIR") != "" {
123-
// While running this test in CI along with all other tests in for code coverage this test hangs very often.
124-
// Possibly due to some resource constraints, since this test is one of the last.
125-
// However just running this package by itself with code coverage works fine in CI.
123+
if os.Getenv("GOCOVERDIR") != "" || race.Enabled {
124+
// While running this test in CI along with all other tests in for code coverage or race enabled,
125+
// this test hangs very often. Possibly due to some resource constraints, since this test is one
126+
// of the last. However just running this package by itself with code coverage works fine in CI.
126127
t.Logf("Skipping TestConcurrentKeyspaceRoutingRulesUpdates test in code coverage mode")
127128
t.Skip()
128129
}

test/ci_workflow_gen.go

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,9 @@ const (
3838

3939
type mysqlVersions []mysqlVersion
4040

41-
var (
42-
defaultMySQLVersions = []mysqlVersion{defaultMySQLVersion}
43-
)
41+
var defaultMySQLVersions = []mysqlVersion{defaultMySQLVersion}
4442

45-
var (
46-
unitTestDatabases = []mysqlVersion{mysql57, mysql80, mysql84}
47-
)
43+
var unitTestDatabases = []mysqlVersion{mysql57, mysql80, mysql84}
4844

4945
const (
5046
oracleCloudRunner = "oracle-16cpu-64gb-x86-64"
@@ -180,6 +176,7 @@ var (
180176

181177
type unitTest struct {
182178
Name, RunsOn, Platform, FileName, GoPrivate, Evalengine string
179+
Race bool
183180
}
184181

185182
type clusterTest struct {
@@ -374,6 +371,24 @@ func generateUnitTestWorkflows() {
374371
}
375372
}
376373
}
374+
375+
// Generate unit tests with race detection
376+
for _, evalengine := range []string{"1", "0"} {
377+
raceTest := &unitTest{
378+
Name: fmt.Sprintf("Unit Test (%sRace)", evalengineToRaceNamePrefix(evalengine)),
379+
RunsOn: cores16RunnerName,
380+
Platform: string(mysql80),
381+
GoPrivate: goPrivate,
382+
Evalengine: evalengine,
383+
Race: true,
384+
}
385+
raceTest.FileName = fmt.Sprintf("unit_race%s.yml", evalengineToFileSuffix(evalengine))
386+
path := fmt.Sprintf("%s/%s", workflowConfigDir, raceTest.FileName)
387+
err := writeFileFromTemplate(unitTestTemplate, path, raceTest)
388+
if err != nil {
389+
log.Print(err)
390+
}
391+
}
377392
}
378393

379394
func evalengineToString(evalengine string) string {
@@ -383,6 +398,27 @@ func evalengineToString(evalengine string) string {
383398
return ""
384399
}
385400

401+
func evalengineToNameSuffix(evalengine string) string {
402+
if evalengine == "1" {
403+
return " evalengine"
404+
}
405+
return ""
406+
}
407+
408+
func evalengineToRaceNamePrefix(evalengine string) string {
409+
if evalengine == "1" {
410+
return "Evalengine_"
411+
}
412+
return ""
413+
}
414+
415+
func evalengineToFileSuffix(evalengine string) string {
416+
if evalengine == "1" {
417+
return "_evalengine"
418+
}
419+
return ""
420+
}
421+
386422
func writeFileFromTemplate(templateFile, filePath string, test any) error {
387423
tpl := template.New(path.Base(templateFile))
388424
tpl.Funcs(template.FuncMap{

test/templates/unit_test.tpl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ jobs:
126126
127127
- name: Run test
128128
if: steps.changes.outputs.unit_tests == 'true'
129-
timeout-minutes: 30
129+
timeout-minutes: {{if .Race}}45{{else}}30{{end}}
130130
run: |
131131
set -exo pipefail
132132
# We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file
@@ -139,7 +139,7 @@ jobs:
139139
# testing, e.g. MySQL 5.7 vs 8.0.
140140
export CI_DB_PLATFORM="{{.Platform}}"
141141
142-
make unit_test | tee -a output.txt | go-junit-report -set-exit-code > report.xml
142+
make {{if .Race}}unit_test_race{{else}}unit_test{{end}} | tee -a output.txt | go-junit-report -set-exit-code > report.xml
143143
144144
- name: Record test results in launchable if PR is not a draft
145145
if: github.event_name == 'pull_request' && github.event.pull_request.draft == 'false' && steps.changes.outputs.unit_tests == 'true' && github.base_ref == 'main' && !cancelled()

tools/unit_test_race.sh

Lines changed: 0 additions & 65 deletions
This file was deleted.

tools/unit_test_runner.sh

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,12 @@ if [[ -z $VT_GO_PARALLEL && -n $VT_GO_PARALLEL_VALUE ]]; then
3636
VT_GO_PARALLEL="-p $VT_GO_PARALLEL_VALUE"
3737
fi
3838

39+
# Enable race detector if RACE=1
40+
RACE_FLAG=""
41+
if [[ "$RACE" == "1" ]]; then
42+
RACE_FLAG="-race"
43+
fi
44+
3945
# Mac makes long temp directories for os.TempDir(). MySQL can't connect to
4046
# sockets in those directories. Tell Golang to use /tmp/vttest_XXXXXX instead.
4147
kernel="$(uname -s)"
@@ -68,7 +74,7 @@ all_except_flaky_tests=$(echo "$packages_with_tests" | grep -vE ".+ .+_flaky_tes
6874
flaky_tests=$(echo "$packages_with_tests" | grep -E ".+ .+_flaky_test\.go" | cut -d" " -f1)
6975

7076
# Run non-flaky tests.
71-
echo "$all_except_flaky_tests" | xargs go test $VT_GO_PARALLEL -v -count=1
77+
go test $VT_GO_PARALLEL $RACE_FLAG -v -count=1 $all_except_flaky_tests
7278
if [ $? -ne 0 ]; then
7379
echo "ERROR: Go unit tests failed. See above for errors."
7480
echo
@@ -84,7 +90,7 @@ for pkg in $flaky_tests; do
8490
max_attempts=3
8591
attempt=1
8692
# Set a timeout because some tests may deadlock when they flake.
87-
until go test -timeout 5m $VT_GO_PARALLEL $pkg -v -count=1; do
93+
until go test -timeout 5m $VT_GO_PARALLEL $RACE_FLAG $pkg -v -count=1; do
8894
echo "FAILED (try $attempt/$max_attempts) in $pkg (return code $?). See above for errors."
8995
if [ $((++attempt)) -gt $max_attempts ]; then
9096
echo "ERROR: Flaky Go unit tests in package $pkg failed too often (after $max_attempts retries). Please reduce the flakiness."

0 commit comments

Comments
 (0)