Skip to content

Commit

Permalink
add ci
Browse files Browse the repository at this point in the history
Signed-off-by: husharp <[email protected]>
  • Loading branch information
HuSharp committed Apr 3, 2024
1 parent 5e36053 commit f666fdc
Show file tree
Hide file tree
Showing 14 changed files with 388 additions and 169 deletions.
20 changes: 15 additions & 5 deletions .github/workflows/pd-tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,19 @@ jobs:
strategy:
fail-fast: true
matrix:
worker_id: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
include:
- worker_id: 1
name: 'Unit Test'
- worker_id: 2
name: 'Tools Test'
- worker_id: 3
name: 'Client Integration Test'
- worker_id: 4
name: 'TSO Integration Test'
- worker_id: 5
name: 'MicroService Integration Test'
outputs:
job-total: 13
job-total: 5
steps:
- uses: actions/setup-go@v3
with:
Expand All @@ -43,11 +53,11 @@ jobs:
**/.tools
**/.dashboard_download_cache
key: ${{ runner.os }}-go-${{ matrix.worker_id }}-${{ hashFiles('**/go.sum') }}
- name: Make Test
- name: ${{ matrix.name }}
env:
WORKER_ID: ${{ matrix.worker_id }}
WORKER_COUNT: 13
JOB_COUNT: 9 # 10 is tools test, 11, 12, 13 are for other integrations jobs
WORKER_COUNT: 5
JOB_COUNT: 5
run: |
make ci-test-job JOB_COUNT=$(($JOB_COUNT)) JOB_INDEX=$WORKER_ID
mv covprofile covprofile_$WORKER_ID
Expand Down
9 changes: 5 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ regions-dump:
stores-dump:
cd tools && CGO_ENABLED=0 go build -gcflags '$(GCFLAGS)' -ldflags '$(LDFLAGS)' -o $(BUILD_BIN_PATH)/stores-dump stores-dump/main.go
pd-ut: pd-xprog
cd tools && GOEXPERIMENT=$(BUILD_GOEXPERIMENT) CGO_ENABLED=$(BUILD_TOOL_CGO_ENABLED) go build -gcflags '$(GCFLAGS)' -ldflags '$(LDFLAGS)' -o $(BUILD_BIN_PATH)/pd-ut pd-ut/ut.go
cd tools && GOEXPERIMENT=$(BUILD_GOEXPERIMENT) CGO_ENABLED=$(BUILD_TOOL_CGO_ENABLED) go build -gcflags '$(GCFLAGS)' -ldflags '$(LDFLAGS)' -o $(BUILD_BIN_PATH)/pd-ut pd-ut/ut.go pd-ut/coverProfile.go
pd-xprog:
cd tools && GOEXPERIMENT=$(BUILD_GOEXPERIMENT) CGO_ENABLED=$(BUILD_TOOL_CGO_ENABLED) go build -tags xprog -gcflags '$(GCFLAGS)' -ldflags '$(LDFLAGS)' -o $(BUILD_BIN_PATH)/xprog pd-ut/xprog.go

Expand Down Expand Up @@ -245,18 +245,19 @@ SUBMODULES := $(filter $(shell find . -iname "go.mod" -exec dirname {} \;),\
test: install-tools
# testing all pkgs...
@$(FAILPOINT_ENABLE)
CGO_ENABLED=1 go test -tags tso_function_test,deadlock -timeout 20m -race -cover $(TEST_PKGS) || { $(FAILPOINT_DISABLE); exit 1; }
CGO_ENABLED=1 go test -tags tso_function_test,deadlock -timeout 20m -race -cover $(TEST_PKGS) -coverprofile=all || { $(FAILPOINT_DISABLE); exit 1; }
@$(FAILPOINT_DISABLE)

basic-test: install-tools
# testing basic pkgs...
@$(FAILPOINT_ENABLE)
go test $(BASIC_TEST_PKGS) || { $(FAILPOINT_DISABLE); exit 1; }
CGO_ENABLED=1 go test -timeout 20m -race -cover $(BASIC_TEST_PKGS) -coverprofile=basic || { $(FAILPOINT_DISABLE); exit 1; }
@$(FAILPOINT_DISABLE)

ci-test-job: install-tools dashboard-ui
ci-test-job: install-tools dashboard-ui pd-ut
@$(FAILPOINT_ENABLE)
./scripts/ci-subtask.sh $(JOB_COUNT) $(JOB_INDEX) || { $(FAILPOINT_DISABLE); exit 1; }
@$(CLEAN_UT_BINARY)
@$(FAILPOINT_DISABLE)

TSO_INTEGRATION_TEST_PKGS := $(PD_PKG)/tests/server/tso
Expand Down
22 changes: 16 additions & 6 deletions client/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,30 @@
# See the License for the specific language governing permissions and
# limitations under the License.

ROOT_PATH := ..
GO_TOOLS_BIN_PATH := $(shell pwd)/../.tools/bin
PATH := $(GO_TOOLS_BIN_PATH):$(PATH)
SHELL := env PATH='$(PATH)' GOBIN='$(GO_TOOLS_BIN_PATH)' $(shell which bash)

default: static tidy test

test:
CGO_ENABLE=1 go test ./... -race -cover
test: failpoint-enable
CGO_ENABLE=1 go test ./... -race -cover || { $(MAKE) failpoint-disable && exit 1; }
$(MAKE) failpoint-disable

basic-test:
CGO_ENABLE=1 go test ./...
basic-test: failpoint-enable
CGO_ENABLE=1 go test ./... || { $(MAKE) failpoint-disable && exit 1; }
$(MAKE) failpoint-disable

ci-test-job:
CGO_ENABLED=1 go test ./... -race -covermode=atomic -coverprofile=covprofile -coverpkg=../... github.com/tikv/pd/client
ci-test-job: failpoint-enable
CGO_ENABLED=1 go test ./... -v -tags deadlock -race -cover -covermode=atomic -coverprofile=covprofile -coverpkg=../... || { $(MAKE) failpoint-disable && exit 1; }
$(MAKE) failpoint-disable

failpoint-enable:
cd $(ROOT_PATH) && $(MAKE) failpoint-enable

failpoint-disable:
cd $(ROOT_PATH) && $(MAKE) failpoint-disable

install-tools:
cd .. && $(MAKE) install-tools
Expand Down
2 changes: 1 addition & 1 deletion client/testutil/tempurl.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ func Alloc() string {
}

func tryAllocTestURL() string {
l, err := net.Listen("tcp", "127.0.0.1:0")
l, err := net.Listen("tcp", "127.0.0.1:")
if err != nil {
log.Fatal("listen failed", zap.Error(err))
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/utils/tempurl/tempurl.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ func Alloc() string {
}

func tryAllocTestURL() string {
l, err := net.Listen("tcp", "127.0.0.1:0")
l, err := net.Listen("tcp", "127.0.0.1:")
if err != nil {
log.Fatal("listen failed", errs.ZapError(err))
}
Expand Down
53 changes: 9 additions & 44 deletions scripts/ci-subtask.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,62 +4,27 @@

ROOT_PATH=../../

if [[ $2 -gt 9 ]]; then
# run tools tests
if [[ $2 -eq 10 ]]; then
cd ./tools && make ci-test-job && cd .. && cat ./covprofile >> covprofile || exit 1
if [[ $2 -gt 1 ]]; then
# run tools tests in task 2
if [[ $2 -eq 2 ]]; then
cd ./tools && make ci-test-job && cat covprofile >> ../covprofile && cd .. || exit 1
exit
fi

# Currently, we only have 3 integration tests, so we can hardcode the task index.
integrations_dir=./tests/integrations
integrations_tasks=($(find "$integrations_dir" -mindepth 1 -maxdepth 1 -type d))
for t in "${integrations_tasks[@]}"; do
if [[ "$t" = "$integrations_dir/client" && $2 -eq 11 ]]; then
cd ./client && make ci-test-job && cd .. && cat ./covprofile >> covprofile || exit 1
if [[ "$t" = "$integrations_dir/client" && $2 -eq 3 ]]; then
cd ./client && make ci-test-job && cat covprofile >> ../covprofile && cd .. || exit 1
cd $integrations_dir && make ci-test-job test_name=client && cat ./client/covprofile >> "$ROOT_PATH/covprofile" || exit 1
elif [[ "$t" = "$integrations_dir/tso" && $2 -eq 12 ]]; then
elif [[ "$t" = "$integrations_dir/tso" && $2 -eq 4 ]]; then
cd $integrations_dir && make ci-test-job test_name=tso && cat ./tso/covprofile >> "$ROOT_PATH/covprofile" || exit 1
elif [[ "$t" = "$integrations_dir/mcs" && $2 -eq 13 ]]; then
elif [[ "$t" = "$integrations_dir/mcs" && $2 -eq 5 ]]; then
cd $integrations_dir && make ci-test-job test_name=mcs && cat ./mcs/covprofile >> "$ROOT_PATH/covprofile" || exit 1
fi
done
else
# Get package test list.
packages=($(go list ./...))
dirs=($(find . -iname "*_test.go" -exec dirname {} \; | sort -u | sed -e "s/^\./github.com\/tikv\/pd/"))
tasks=($(comm -12 <(printf "%s\n" "${packages[@]}") <(printf "%s\n" "${dirs[@]}")))

weight() {
[[ $1 == "github.com/tikv/pd/server/api" ]] && return 30
[[ $1 == "github.com/tikv/pd/pkg/schedule" ]] && return 30
[[ $1 == "github.com/tikv/pd/pkg/core" ]] && return 30
[[ $1 == "github.com/tikv/pd/tests/server/api" ]] && return 30
[[ $1 =~ "pd/tests" ]] && return 5
return 1
}

# Create an associative array to store the weight of each task.
declare -A task_weights
for t in ${tasks[@]}; do
weight $t
task_weights[$t]=$?
done

# Sort tasks by weight in descending order.
tasks=($(printf "%s\n" "${tasks[@]}" | sort -rn))

scores=($(seq "$1" | xargs -I{} echo 0))

res=()
for t in ${tasks[@]}; do
min_i=0
for i in ${!scores[@]}; do
[[ ${scores[i]} -lt ${scores[$min_i]} ]] && min_i=$i
done
scores[$min_i]=$((${scores[$min_i]} + ${task_weights[$t]}))
[[ $(($min_i + 1)) -eq $2 ]] && res+=($t)
done

CGO_ENABLED=1 go test -timeout=15m -tags deadlock -race -covermode=atomic -coverprofile=covprofile -coverpkg=./... ${res[@]}
./bin/pd-ut run --race --coverprofile covprofile
fi
162 changes: 101 additions & 61 deletions tests/server/api/api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -755,9 +755,9 @@ func TestRemovingProgress(t *testing.T) {

// no store removing
output := sendRequest(re, leader.GetAddr()+"/pd/api/v1/stores/progress?action=removing", http.MethodGet, http.StatusNotFound)
re.Contains((string(output)), "no progress found for the action")
re.Contains(string(output), "no progress found for the action")
output = sendRequest(re, leader.GetAddr()+"/pd/api/v1/stores/progress?id=2", http.MethodGet, http.StatusNotFound)
re.Contains((string(output)), "no progress found for the given store ID")
re.Contains(string(output), "no progress found for the given store ID")

// remove store 1 and store 2
_ = sendRequest(re, leader.GetAddr()+"/pd/api/v1/store/1", http.MethodDelete, http.StatusOK)
Expand All @@ -776,32 +776,52 @@ func TestRemovingProgress(t *testing.T) {
tests.MustPutRegion(re, cluster, 1000, 1, []byte("a"), []byte("b"), core.SetApproximateSize(20))
tests.MustPutRegion(re, cluster, 1001, 2, []byte("c"), []byte("d"), core.SetApproximateSize(10))

// is not prepared
time.Sleep(2 * time.Second)
output = sendRequest(re, leader.GetAddr()+"/pd/api/v1/stores/progress?action=removing", http.MethodGet, http.StatusOK)
re.NoError(json.Unmarshal(output, &p))
re.Equal("removing", p.Action)
re.Equal(0.0, p.Progress)
re.Equal(0.0, p.CurrentSpeed)
re.Equal(math.MaxFloat64, p.LeftSeconds)
testutil.Eventually(re, func() bool {
if leader.GetRaftCluster().IsPrepared() {
// wait for cluster started
url := leader.GetAddr() + "/pd/api/v1/stores/progress?action=removing"
req, _ := http.NewRequest(http.MethodGet, url, http.NoBody)
resp, err := dialClient.Do(req)
re.NoError(err)
defer resp.Body.Close()
return resp.StatusCode == http.StatusOK
}
// is not prepared
output = sendRequest(re, leader.GetAddr()+"/pd/api/v1/stores/progress?action=removing", http.MethodGet, http.StatusOK)
re.NoError(json.Unmarshal(output, &p))
re.Equal("removing", p.Action)
re.Equal(0.0, p.Progress)
re.Equal(0.0, p.CurrentSpeed)
re.Equal(math.MaxFloat64, p.LeftSeconds)
return false
})

leader.GetRaftCluster().SetPrepared()
time.Sleep(2 * time.Second)
output = sendRequest(re, leader.GetAddr()+"/pd/api/v1/stores/progress?action=removing", http.MethodGet, http.StatusOK)
re.NoError(json.Unmarshal(output, &p))
re.Equal("removing", p.Action)
// store 1: (60-20)/(60+50) ~= 0.36
// store 2: (30-10)/(30+40) ~= 0.28
// average progress ~= (0.36+0.28)/2 = 0.32
re.Equal("0.32", fmt.Sprintf("%.2f", p.Progress))
// store 1: 40/10s = 4
// store 2: 20/10s = 2
// average speed = (2+4)/2 = 33
re.Equal(3.0, p.CurrentSpeed)
// store 1: (20+50)/4 = 17.5s
// store 2: (10+40)/2 = 25s
// average time = (17.5+25)/2 = 21.25s
re.Equal(21.25, p.LeftSeconds)
testutil.Eventually(re, func() bool {
output = sendRequest(re, leader.GetAddr()+"/pd/api/v1/stores/progress?action=removing", http.MethodGet, http.StatusOK)
re.NoError(json.Unmarshal(output, &p))
if p.Action != "removing" {
return false
}
// store 1: (60-20)/(60+50) ~= 0.36
// store 2: (30-10)/(30+40) ~= 0.28
// average progress ~= (0.36+0.28)/2 = 0.32
if fmt.Sprintf("%.2f", p.Progress) != "0.32" {
return false
}
// store 1: 40/10s = 4
// store 2: 20/10s = 2
// average speed = (2+4)/2 = 33
if p.CurrentSpeed != 3.0 {
return false
}
// store 1: (20+50)/4 = 17.5s
// store 2: (10+40)/2 = 25s
// average time = (17.5+25)/2 = 21.25s
if p.LeftSeconds != 21.25 {
return false
}
return true
})

output = sendRequest(re, leader.GetAddr()+"/pd/api/v1/stores/progress?id=2", http.MethodGet, http.StatusOK)
re.NoError(json.Unmarshal(output, &p))
Expand Down Expand Up @@ -929,47 +949,67 @@ func TestPreparingProgress(t *testing.T) {
}
// no store preparing
output := sendRequest(re, leader.GetAddr()+"/pd/api/v1/stores/progress?action=preparing", http.MethodGet, http.StatusNotFound)
re.Contains((string(output)), "no progress found for the action")
re.Contains(string(output), "no progress found for the action")
output = sendRequest(re, leader.GetAddr()+"/pd/api/v1/stores/progress?id=4", http.MethodGet, http.StatusNotFound)
re.Contains((string(output)), "no progress found for the given store ID")

// is not prepared
time.Sleep(2 * time.Second)
output = sendRequest(re, leader.GetAddr()+"/pd/api/v1/stores/progress?action=preparing", http.MethodGet, http.StatusNotFound)
re.Contains((string(output)), "no progress found for the action")
output = sendRequest(re, leader.GetAddr()+"/pd/api/v1/stores/progress?id=4", http.MethodGet, http.StatusNotFound)
re.Contains((string(output)), "no progress found for the given store ID")
re.Contains(string(output), "no progress found for the given store ID")

testutil.Eventually(re, func() bool {
if leader.GetRaftCluster().IsPrepared() {
// wait for cluster started
url := leader.GetAddr() + "/pd/api/v1/stores/progress?action=preparing"
req, _ := http.NewRequest(http.MethodGet, url, http.NoBody)
resp, err := dialClient.Do(req)
re.NoError(err)
defer resp.Body.Close()
return resp.StatusCode == http.StatusOK
}
// is not prepared
output = sendRequest(re, leader.GetAddr()+"/pd/api/v1/stores/progress?action=preparing", http.MethodGet, http.StatusNotFound)
re.Contains(string(output), "no progress found for the action")
output = sendRequest(re, leader.GetAddr()+"/pd/api/v1/stores/progress?id=4", http.MethodGet, http.StatusNotFound)
re.Contains(string(output), "no progress found for the given store ID")
return false
})

// size is not changed.
leader.GetRaftCluster().SetPrepared()
time.Sleep(2 * time.Second)
output = sendRequest(re, leader.GetAddr()+"/pd/api/v1/stores/progress?action=preparing", http.MethodGet, http.StatusOK)
var p api.Progress
re.NoError(json.Unmarshal(output, &p))
re.Equal("preparing", p.Action)
re.Equal(0.0, p.Progress)
re.Equal(0.0, p.CurrentSpeed)
re.Equal(math.MaxFloat64, p.LeftSeconds)
testutil.Eventually(re, func() bool {
output = sendRequest(re, leader.GetAddr()+"/pd/api/v1/stores/progress?action=preparing", http.MethodGet, http.StatusOK)
re.NoError(json.Unmarshal(output, &p))
if p.Action != "preparing" || p.Progress != 0.0 || p.CurrentSpeed != 0.0 || p.LeftSeconds != math.MaxFloat64 {
return false
}
return true
})

// update size
tests.MustPutRegion(re, cluster, 1000, 4, []byte(fmt.Sprintf("%20d", 1000)), []byte(fmt.Sprintf("%20d", 1001)), core.SetApproximateSize(10))
tests.MustPutRegion(re, cluster, 1001, 5, []byte(fmt.Sprintf("%20d", 1001)), []byte(fmt.Sprintf("%20d", 1002)), core.SetApproximateSize(40))
time.Sleep(2 * time.Second)
output = sendRequest(re, leader.GetAddr()+"/pd/api/v1/stores/progress?action=preparing", http.MethodGet, http.StatusOK)
re.NoError(json.Unmarshal(output, &p))
re.Equal("preparing", p.Action)
// store 4: 10/(210*0.9) ~= 0.05
// store 5: 40/(210*0.9) ~= 0.21
// average progress ~= (0.05+0.21)/2 = 0.13
re.Equal("0.13", fmt.Sprintf("%.2f", p.Progress))
// store 4: 10/10s = 1
// store 5: 40/10s = 4
// average speed = (1+4)/2 = 2.5
re.Equal(2.5, p.CurrentSpeed)
// store 4: 179/1 ~= 179
// store 5: 149/4 ~= 37.25
// average time ~= (179+37.25)/2 = 108.125
re.Equal(108.125, p.LeftSeconds)
testutil.Eventually(re, func() bool {
output := sendRequest(re, leader.GetAddr()+"/pd/api/v1/stores/progress?action=preparing", http.MethodGet, http.StatusOK)
re.NoError(json.Unmarshal(output, &p))
if p.Action != "preparing" {
return false
}
// store 4: 10/(210*0.9) ~= 0.05
// store 5: 40/(210*0.9) ~= 0.21
// average progress ~= (0.05+0.21)/2 = 0.13
if fmt.Sprintf("%.2f", p.Progress) != "0.13" {
return false
}
// store 4: 10/10s = 1
// store 5: 40/10s = 4
// average speed = (1+4)/2 = 2.5
if p.CurrentSpeed != 2.5 {
return false
}
// store 4: 179/1 ~= 179
// store 5: 149/4 ~= 37.25
// average time ~= (179+37.25)/2 = 108.125
if p.LeftSeconds != 108.125 {
return false
}
return true
})

output = sendRequest(re, leader.GetAddr()+"/pd/api/v1/stores/progress?id=4", http.MethodGet, http.StatusOK)
re.NoError(json.Unmarshal(output, &p))
Expand Down
Loading

0 comments on commit f666fdc

Please sign in to comment.