# Copyright 2019 PingCAP, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

include Makefile.common


.DEFAULT_GOAL := default

# Adapted from https://www.thapaliya.com/en/writings/well-documented-makefiles/
.PHONY: help
help: ## Display this help and any documented user-facing targets. Other undocumented targets may be present in the Makefile.
help:
	@awk 'BEGIN {FS = ": ##"; printf "Usage:\n make <target>\n\nTargets:\n"} /^[a-zA-Z0-9_\.\-\/%]+: ##/ { printf " %-45s %s\n", $$1, $$2 }' $(MAKEFILE_LIST)

default: server buildsucc ## Default target: build TiDB server

.PHONY: server-admin-check
server-admin-check: server_check buildsucc ## Build TiDB server with admin checks

.PHONY: buildsucc
buildsucc:
	@echo Build TiDB Server successfully!

.PHONY: all
all: dev server benchkv ## Build all targets: dev tools, server, and benchkv

.PHONY: dev
dev: ## Run the full development workflow including all tests and checks
dev: checklist check integrationtest gogenerate br_unit_test test_part_parser_dev ut check-file-perm ## Run full development workflow including all tests and checks
	@>&2 echo "Great, all tests passed."

# Install the check tools.
.PHONY: check-setup
check-setup: ## Install development and checking tools
check-setup:tools/bin/revive

.PHONY: precheck
precheck: ## Run pre-commit checks
precheck: fmt bazel_prepare

.PHONY: check
check: ## Run comprehensive code quality checks
check: check-bazel-prepare parser_yacc check-parallel lint tidy testSuite errdoc license bazel_check_abi

.PHONY: fmt
fmt: ## Format Go code using gofmt
	@echo "gofmt (simplify)"
	@gofmt -s -l -w -r 'interface{} -> any' $(FILES) 2>&1 | $(FAIL_ON_STDOUT)

# On macOS, CGO is required for gosigar package to generate export data properly
ifeq ($(GOOS),darwin)
CGO_ENABLED_FOR_LINT := 1
else
CGO_ENABLED_FOR_LINT := 0
endif

.PHONY: check-static
check-static: ## Run static code analysis checks
check-static: tools/bin/golangci-lint
	GO111MODULE=on CGO_ENABLED=$(CGO_ENABLED_FOR_LINT) tools/bin/golangci-lint run -v $$($(PACKAGE_DIRECTORIES)) --config .golangci.yml

.PHONY: check-file-perm
check-file-perm:
	@echo "check file permission"
	./tools/check/check-file-perm.sh

.PHONY: gogenerate
gogenerate:
	@echo "go generate ./..."
	./tools/check/check-gogenerate.sh

.PHONY: errdoc
errdoc:tools/bin/errdoc-gen
	@echo "generator errors.toml"
	./tools/check/check-errdoc.sh

.PHONY: lint
lint:tools/bin/revive
	@echo "linting"
	@tools/bin/revive -formatter friendly -config tools/check/revive.toml \
	-exclude pkg/util/hack/... -exclude ./pkg/util/hack/...  $(FILES_TIDB_TESTS)
	@tools/bin/revive -formatter friendly -config tools/check/revive.toml ./lightning/...
	go run tools/dashboard-linter/main.go pkg/metrics/grafana/overview.json
	go run tools/dashboard-linter/main.go pkg/metrics/grafana/performance_overview.json
	go run tools/dashboard-linter/main.go pkg/metrics/grafana/tidb.json
	go run tools/dashboard-linter/main.go pkg/metrics/grafana/tidb_resource_control.json
	go run tools/dashboard-linter/main.go pkg/metrics/grafana/tidb_runtime.json
	go run tools/dashboard-linter/main.go pkg/metrics/grafana/tidb_summary.json
	go run tools/dashboard-linter/main.go pkg/metrics/grafana/tidb_summary.json
	go run tools/dashboard-linter/main.go pkg/metrics/nextgengrafana/overview.json
	go run tools/dashboard-linter/main.go pkg/metrics/nextgengrafana/overview_with_keyspace_name.json
	go run tools/dashboard-linter/main.go pkg/metrics/nextgengrafana/performance_overview.json
	go run tools/dashboard-linter/main.go pkg/metrics/nextgengrafana/performance_overview_with_keyspace_name.json
	go run tools/dashboard-linter/main.go pkg/metrics/nextgengrafana/tidb_resource_control_with_keyspace_name.json
	go run tools/dashboard-linter/main.go pkg/metrics/nextgengrafana/tidb_runtime_with_keyspace_name.json
	go run tools/dashboard-linter/main.go pkg/metrics/nextgengrafana/tidb_summary_with_keyspace_name.json
	go run tools/dashboard-linter/main.go pkg/metrics/nextgengrafana/tidb_with_keyspace_name.json
	go run tools/dashboard-linter/main.go pkg/metrics/nextgengrafana/tidb_worker.json

.PHONY: license
license:
	bazel $(BAZEL_GLOBAL_CONFIG) run $(BAZEL_CMD_CONFIG) \
		--run_under="cd $(CURDIR) && " \
		 @com_github_apache_skywalking_eyes//cmd/license-eye:license-eye --run_under="cd $(CURDIR) && "  -- -c ./.github/licenserc.yml  header check

.PHONY: tidy
tidy:
	@echo "go mod tidy"
	./tools/check/check-tidy.sh

.PHONY: testSuite
testSuite:
	@echo "testSuite"
	./tools/check/check_testSuite.sh

.PHONY: check-parallel
check-parallel:
# Make sure no tests are run in parallel to prevent possible unstable tests.
# See https://github.com/pingcap/tidb/pull/30692.
	@! find . -name "*_test.go" -not -path "./vendor/*" -print0 | \
		xargs -0 grep -F -n "t.Parallel()" || \
		! echo "Error: all the go tests should be run in serial."

CLEAN_UT_BINARY := find . -name '*.test.bin'| xargs rm -f

.PHONY: clean
clean: ## Clean build artifacts
clean: failpoint-disable ## Clean build artifacts and test binaries
	$(GO) clean -i ./...
	rm -rf $(TEST_COVERAGE_DIR)
	@$(CLEAN_UT_BINARY)

# Split tests for CI to run `make test` in parallel.
.PHONY: test
test: ## Run all tests (split into parts for parallel execution)
test: test_part_1 test_part_2
	@>&2 echo "Great, all tests passed."

.PHONY: test_part_1
test_part_1: checklist integrationtest ## Run test part 1: checklist and integration tests

.PHONY: test_part_2
test_part_2: test_part_parser ut gogenerate br_unit_test dumpling_unit_test ## Run test part 2: parser tests, unit tests, BR and dumpling tests

.PHONY: test_part_parser
test_part_parser: parser_yacc test_part_parser_dev

.PHONY: test_part_parser_dev
test_part_parser_dev: parser_fmt parser_unit_test

.PHONY: parser
parser:
	@cd pkg/parser && make parser

.PHONY: parser_ast_visitor
parser_ast_visitor: ## Regenerate in-place AST visitor methods
	@cd pkg/parser && $(GO) run ./ast/visitor_codegen/cmd -source-dir ast -output ast/visitor_inplace_generated.go

.PHONY: parser_yacc
parser_yacc:
	@cd pkg/parser && mv parser.go parser.go.committed && make parser && diff -u parser.go.committed parser.go && rm parser.go.committed

.PHONY: parser_fmt
parser_fmt:
	@cd pkg/parser && make fmt

.PHONY: parser_unit_test
parser_unit_test:
	@cd pkg/parser && make test

.PHONY: test_part_br
test_part_br: br_unit_test br_integration_test

.PHONY: test_part_dumpling
test_part_dumpling: dumpling_unit_test dumpling_integration_test

.PHONY: integrationtest
integrationtest: ## Run integration tests with coverage
integrationtest: server_check
	@mkdir -p $(TEST_COVERAGE_DIR)
	@cd tests/integrationtest && GOCOVERDIR=../../$(TEST_COVERAGE_DIR) ./run-tests.sh -s ../../bin/tidb-server
	@$(GO) tool covdata textfmt -i=$(TEST_COVERAGE_DIR) -o=coverage.dat

.PHONY: ddltest
ddltest:
	@cd cmd/ddltest && $(GO) test --tags=deadllock,intest -o ../../bin/ddltest -c

.PHONY: ut
ut: tools/bin/ut tools/bin/xprog failpoint-enable ## Run unit tests
	@echo "Debug: Running ut with X=$(X)"
	tools/bin/ut $(X) || { $(FAILPOINT_DISABLE); $(CLEAN_UT_BINARY); exit 1; }
	@$(FAILPOINT_DISABLE)
	@$(CLEAN_UT_BINARY)

.PHONY: ut-long
ut-long: tools/bin/ut tools/bin/xprog failpoint-enable
	tools/bin/ut --long --race || { $(FAILPOINT_DISABLE); $(CLEAN_UT_BINARY); exit 1; }
	@$(FAILPOINT_DISABLE)
	@$(CLEAN_UT_BINARY)

.PHONY: gotest_in_verify_ci
gotest_in_verify_ci: tools/bin/xprog tools/bin/ut failpoint-enable
	@echo "Running gotest_in_verify_ci"
	@mkdir -p $(TEST_COVERAGE_DIR)
	tools/bin/ut --junitfile "$(TEST_COVERAGE_DIR)/tidb-junit-report.xml" --coverprofile "$(TEST_COVERAGE_DIR)/tidb_cov.unit_test.out" --except unstable.txt || { $(FAILPOINT_DISABLE); $(CLEAN_UT_BINARY); exit 1; }
	@$(FAILPOINT_DISABLE)
	@$(CLEAN_UT_BINARY)

.PHONY: gotest_unstable_in_verify_ci
gotest_unstable_in_verify_ci: tools/bin/xprog tools/bin/ut failpoint-enable
	@echo "Running gotest_unstable_in_verify_ci"
	@mkdir -p $(TEST_COVERAGE_DIR)
	tools/bin/ut --junitfile "$(TEST_COVERAGE_DIR)/tidb-junit-report.xml" --coverprofile "$(TEST_COVERAGE_DIR)/tidb_cov.unit_test.out" --only unstable.txt || { $(FAILPOINT_DISABLE); $(CLEAN_UT_BINARY); exit 1; }
	@$(FAILPOINT_DISABLE)
	@$(CLEAN_UT_BINARY)

.PHONY: race
race: failpoint-enable
	@mkdir -p $(TEST_COVERAGE_DIR)
	tools/bin/ut --race --junitfile "$(TEST_COVERAGE_DIR)/tidb-junit-report.xml" --coverprofile "$(TEST_COVERAGE_DIR)/tidb_cov.unit_test" --except unstable.txt || { $(FAILPOINT_DISABLE); $(CLEAN_UT_BINARY); exit 1; }
	@$(FAILPOINT_DISABLE)
	@$(CLEAN_UT_BINARY)

.PHONY: server
ifeq ($(GOCOVER), )
    COVER_FLAG :=
else
    COVER_FLAG := -cover -covermode='atomic'
endif

ifeq ($(TARGET), "")
    SERVER_OUT := bin/tidb-server
else
    SERVER_OUT := $(TARGET)
endif

SERVER_BUILD_CMD := \
	CGO_ENABLED=1 $(GOBUILD) $(RACE_FLAG) $(COVER_FLAG) \
	-ldflags '$(LDFLAGS) $(CHECK_FLAG)' -o '$(SERVER_OUT)' ./cmd/tidb-server

server: ## Build TiDB server binary
	$(SERVER_BUILD_CMD)

.PHONY: server_debug
server_debug: ## Build TiDB server binary with debug symbols
ifeq ($(TARGET), "")
	CGO_ENABLED=1 $(GOBUILD) -gcflags="all=-N -l" $(RACE_FLAG) -ldflags '$(LDFLAGS) $(CHECK_FLAG)' -o bin/tidb-server-debug ./cmd/tidb-server
else
	CGO_ENABLED=1 $(GOBUILD) -gcflags="all=-N -l" $(RACE_FLAG) -ldflags '$(LDFLAGS) $(CHECK_FLAG)' -o '$(TARGET)' ./cmd/tidb-server
endif

.PHONY: server_failpoint
server_failpoint: failpoint-enable ## Build TiDB server binary with failpoints enabled
	$(SERVER_BUILD_CMD) || { $(FAILPOINT_DISABLE); exit 1; }
	@$(FAILPOINT_DISABLE)

.PHONY: init-submodule
init-submodule:
	git submodule init && git submodule update --force

.PHONY: enterprise-prepare
enterprise-prepare:
	cd pkg/extension/enterprise/generate && $(GO) generate -run genfile main.go

.PHONY: enterprise-clear
enterprise-clear:
	cd pkg/extension/enterprise/generate && $(GO) generate -run clear main.go

.PHONY: enterprise-docker
enterprise-docker: init-submodule enterprise-prepare
	docker build -t "$(DOCKERPREFIX)tidb:latest" --build-arg 'GOPROXY=$(shell go env GOPROXY),' -f Dockerfile.enterprise .

.PHONY: enterprise-server-build
enterprise-server-build: TIDB_EDITION=Enterprise
enterprise-server-build:
ifeq ($(TARGET), "")
	CGO_ENABLED=1 $(GOBUILD_NO_TAGS) -tags=$(BUILD_TAGS),enterprise $(RACE_FLAG) -ldflags '$(LDFLAGS) $(CHECK_FLAG) $(EXTENSION_FLAG)' -o bin/tidb-server cmd/tidb-server/main.go
else
	CGO_ENABLED=1 $(GOBUILD_NO_TAGS) -tags=$(BUILD_TAGS),enterprise $(RACE_FLAG) -ldflags '$(LDFLAGS) $(CHECK_FLAG) $(EXTENSION_FLAG)' -o '$(TARGET)' cmd/tidb-server/main.go
endif

.PHONY: enterprise-server
enterprise-server: ## Build TiDB server with enterprise features
	$(MAKE) init-submodule
	$(MAKE) enterprise-prepare
	$(MAKE) enterprise-server-build

.PHONY: server_check
server_check:
ifeq ($(TARGET), "")
	$(GOBUILD_NO_TAGS) -cover $(RACE_FLAG) -ldflags '$(CHECK_LDFLAGS)' --tags=$(CHECK_BUILD_TAGS) -o bin/tidb-server ./cmd/tidb-server
else
	$(GOBUILD_NO_TAGS) -cover $(RACE_FLAG) -ldflags '$(CHECK_LDFLAGS)' --tags=$(CHECK_BUILD_TAGS) -o '$(TARGET)' ./cmd/tidb-server
endif

.PHONY: linux
linux: ## Build TiDB server for Linux
ifeq ($(TARGET), "")
	GOOS=linux $(GOBUILD) $(RACE_FLAG) -ldflags '$(LDFLAGS) $(CHECK_FLAG)' -o bin/tidb-server-linux ./cmd/tidb-server
else
	GOOS=linux $(GOBUILD) $(RACE_FLAG) -ldflags '$(LDFLAGS) $(CHECK_FLAG)' -o '$(TARGET)' ./cmd/tidb-server
endif

.PHONY: server_coverage
server_coverage:
ifeq ($(TARGET), "")
	$(GOBUILDCOVERAGE) $(RACE_FLAG) -ldflags '$(LDFLAGS) $(COVERAGE_SERVER_LDFLAGS) $(CHECK_FLAG)' -o ../bin/tidb-server-coverage
else
	$(GOBUILDCOVERAGE) $(RACE_FLAG) -ldflags '$(LDFLAGS) $(COVERAGE_SERVER_LDFLAGS) $(CHECK_FLAG)' -o '$(TARGET)'
endif

.PHONY: benchkv
benchkv: ## Build benchkv benchmark tool
	$(GOBUILD) -ldflags '$(LDFLAGS)' -o bin/benchkv cmd/benchkv/main.go

.PHONY: benchraw
benchraw: ## Build benchraw benchmark tool
	$(GOBUILD) -ldflags '$(LDFLAGS)' -o bin/benchraw cmd/benchraw/main.go

.PHONY: benchdb
benchdb: ## Build benchdb benchmark tool
	$(GOBUILD) -ldflags '$(LDFLAGS)' -o bin/benchdb cmd/benchdb/main.go

.PHONY: importer
importer: ## Build importer tool
	$(GOBUILD) -ldflags '$(LDFLAGS)' -o bin/importer ./cmd/importer

.PHONY: checklist
checklist:
	cat checklist.md

.PHONY: failpoint-enable
failpoint-enable: tools/bin/failpoint-ctl
# Converting gofail failpoints...
	@$(FAILPOINT_ENABLE)

.PHONY: failpoint-disable
failpoint-disable: tools/bin/failpoint-ctl
# Restoring gofail failpoints...
	@$(FAILPOINT_DISABLE)

.PHONY: bazel-failpoint-enable
bazel-failpoint-enable:
	BAZEL_GLOBAL_CONFIG="$(BAZEL_GLOBAL_CONFIG)" BAZEL_CMD_CONFIG="$(BAZEL_CMD_CONFIG)" ./tools/check/failpoint-state.sh enable bazel

.PHONY: bazel-failpoint-disable
bazel-failpoint-disable:
	BAZEL_GLOBAL_CONFIG="$(BAZEL_GLOBAL_CONFIG)" BAZEL_CMD_CONFIG="$(BAZEL_CMD_CONFIG)" ./tools/check/failpoint-state.sh disable bazel

.PHONY: tools/bin/ut
tools/bin/ut: tools/check/ut.go tools/check/longtests.go
	cd tools/check; \
	$(GO) build -o ../bin/ut ut.go longtests.go

.PHONY: tools/bin/xprog
tools/bin/xprog: tools/check/xprog/xprog.go
	cd tools/check/xprog; \
	$(GO) build -o ../../bin/xprog xprog.go

.PHONY: tools/bin/revive
tools/bin/revive:
	GOBIN=$(shell pwd)/tools/bin $(GO) install github.com/mgechev/revive@v1.2.1

.PHONY: tools/bin/failpoint-ctl
tools/bin/failpoint-ctl:
	$(eval FP_GITHASH := 9b3b6e3)
	$(eval FP_PKG := github.com/pingcap/failpoint/failpoint-ctl)
	$(eval FP_BIN := $(CURDIR)/tools/bin/failpoint-ctl)
	@if [ ! -x "$(FP_BIN)" ] || [ "$$($(GO) version -m $(FP_BIN) 2>/dev/null | grep -o '$(FP_GITHASH)' || echo unknown)" != "$(FP_GITHASH)" ]; then \
		echo "Installing $(FP_PKG)@$(FP_GITHASH)"; \
		GOBIN=$$(pwd)/tools/bin $(GO) install $(FP_PKG)@$(FP_GITHASH) || { echo "failed to install $(FP_PKG)@$(FP_GITHASH)"; exit 1; }; \
	else \
		echo "Using existing $(FP_PKG)@$(FP_GITHASH)"; \
	fi

.PHONY: tools/bin/errdoc-gen
tools/bin/errdoc-gen:
	GOBIN=$(shell pwd)/tools/bin $(GO) install github.com/pingcap/errors/errdoc-gen@518f63d

.PHONY: tools/bin/golangci-lint
tools/bin/golangci-lint:
	$(eval GOLANGCI_LINT_VERSION := $(shell grep 'github.com/golangci/golangci-lint/v2' go.mod | awk '{print $$2}'))
	GOBIN=$(shell pwd)/tools/bin $(GO) install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@$(GOLANGCI_LINT_VERSION)

.PHONY: tools/bin/gotestsum
tools/bin/gotestsum:
	GOBIN=$(shell pwd)/tools/bin $(GO) install gotest.tools/gotestsum@v1.8.1

# mockgen@v0.2.0 is incompatible with v0.3.0, so install it always.
.PHONY: mockgen
mockgen:
	GOBIN=$(shell pwd)/tools/bin $(GO) install github.com/lance6716/mock/mockgen@v0.4.0-patch

# Usage:
#
# 	$ make vectorized-bench VB_FILE=Time VB_FUNC=builtinCurrentDateSig
.PHONY: vectorized-bench
vectorized-bench:
	cd ./expression && \
		go test -v -timeout=0 -benchmem \
			-bench=BenchmarkVectorizedBuiltin$(VB_FILE)Func \
			-run=BenchmarkVectorizedBuiltin$(VB_FILE)Func \
			-args "$(VB_FUNC)"

.PHONY: testpkg
testpkg: failpoint-enable
ifeq ("$(pkg)", "")
	@echo "Require pkg parameter"
else
	@echo "Running unit test for github.com/pingcap/tidb/$(pkg)"
	@export log_level=fatal; export TZ='Asia/Shanghai'; \
	$(GOTEST) -tags 'intest' -v -ldflags '$(TEST_LDFLAGS)' -cover github.com/pingcap/tidb/$(pkg) || { $(FAILPOINT_DISABLE); exit 1; }
endif
	@$(FAILPOINT_DISABLE)

# Collect the daily benchmark data.
# Usage:
#	make bench-daily TO=/path/to/file.json
.PHONY: bench-daily
bench-daily:
	go test github.com/pingcap/tidb/pkg/distsql -run TestBenchDaily -bench Ignore --outfile bench_daily.json
	go test github.com/pingcap/tidb/pkg/executor -run TestBenchDaily -bench Ignore --outfile bench_daily.json
	go test github.com/pingcap/tidb/pkg/executor/test/splittest -run TestBenchDaily -bench Ignore --outfile bench_daily.json
	go test github.com/pingcap/tidb/pkg/expression -run TestBenchDaily -bench Ignore --outfile bench_daily.json
	go test github.com/pingcap/tidb/pkg/planner/core/casetest/plancache -run TestBenchDaily -bench Ignore --outfile bench_daily.json
	go test github.com/pingcap/tidb/pkg/planner/core/tests/partition -run TestBenchDaily -bench Ignore --outfile bench_daily.json
	go test github.com/pingcap/tidb/pkg/planner/core/casetest/tpcds -run TestBenchDaily -bench Ignore --outfile bench_daily.json
	go test github.com/pingcap/tidb/pkg/planner/core/casetest/tpch -run TestBenchDaily -bench Ignore --outfile bench_daily.json
	go test github.com/pingcap/tidb/pkg/session -run TestBenchDaily -bench Ignore --outfile bench_daily.json
	go test github.com/pingcap/tidb/pkg/statistics -run TestBenchDaily -bench Ignore --outfile bench_daily.json
	go test github.com/pingcap/tidb/pkg/table/tables -run TestBenchDaily -bench Ignore --outfile bench_daily.json
	go test github.com/pingcap/tidb/pkg/tablecodec -run TestBenchDaily -bench Ignore --outfile bench_daily.json
	go test github.com/pingcap/tidb/pkg/util/codec -run TestBenchDaily -bench Ignore --outfile bench_daily.json
	go test github.com/pingcap/tidb/pkg/util/ranger -run TestBenchDaily -bench Ignore --outfile bench_daily.json
	go test github.com/pingcap/tidb/pkg/util/rowcodec -run TestBenchDaily -bench Ignore --outfile bench_daily.json
	go test github.com/pingcap/tidb/pkg/util/benchdaily -run TestBenchDaily -bench Ignore \
		-date `git log -n1 --date=unix --pretty=format:%cd` \
		-commit `git log -n1 --pretty=format:%h` \
		-outfile $(TO)

.PHONY: build_tools
build_tools: build_br build_lightning build_lightning-ctl ## Build all BR and Lightning tools

.PHONY: build_br
build_br: ## Build BR (backup and restore) tool 
ifeq ($(shell echo $(GOOS) | tr A-Z a-z),darwin)
	@echo "Detected macOS ($(ARCH)), enabling CGO"
	CGO_ENABLED=1 $(GOBUILD) $(RACE_FLAG) -ldflags '$(LDFLAGS) $(CHECK_FLAG)' -o $(BR_BIN) ./br/cmd/br
else
	@echo "Detected non-macOS ($(ARCH)), disabling CGO"
	CGO_ENABLED=0 $(GOBUILD) $(RACE_FLAG) -ldflags '$(LDFLAGS) $(CHECK_FLAG)' -o $(BR_BIN) ./br/cmd/br
endif

.PHONY: build_lightning
build_lightning: ## Build TiDB Lightning data import tool
ifeq ("$(GOOS)", "freebsd")
	@echo "Building lightning for FreeBSD, assuming crossbuild, disabling CGO"
	CGO_ENABLED=0 $(GOBUILD_NO_TAGS) -tags codes $(RACE_FLAG) -ldflags '$(LDFLAGS) $(CHECK_FLAG)' -o $(LIGHTNING_BIN) ./lightning/cmd/tidb-lightning
else
	CGO_ENABLED=1 $(GOBUILD_NO_TAGS) -tags codes $(RACE_FLAG) -ldflags '$(LDFLAGS) $(CHECK_FLAG)' -o $(LIGHTNING_BIN) ./lightning/cmd/tidb-lightning
endif

.PHONY: build_lightning-ctl
build_lightning-ctl: ## Build TiDB Lightning control tool
	@echo "Building lightning-ctl for FreeBSD, assuming crossbuild, disabling CGO"
ifeq ("$(GOOS)", "freebsd")
	CGO_ENABLED=0 $(GOBUILD) $(RACE_FLAG) -ldflags '$(LDFLAGS) $(CHECK_FLAG)' -o $(LIGHTNING_CTL_BIN) ./lightning/cmd/tidb-lightning-ctl
else
	CGO_ENABLED=1 $(GOBUILD) $(RACE_FLAG) -ldflags '$(LDFLAGS) $(CHECK_FLAG)' -o $(LIGHTNING_CTL_BIN) ./lightning/cmd/tidb-lightning-ctl
endif

.PHONY: build_for_lightning_integration_test
build_for_lightning_integration_test:
	@make failpoint-enable
	($(GOTEST) -c -cover -covermode=count \
		-coverpkg=github.com/pingcap/tidb/lightning/...,github.com/pingcap/tidb/pkg/lightning/... \
		-o $(LIGHTNING_BIN).test \
		github.com/pingcap/tidb/lightning/cmd/tidb-lightning && \
	$(GOTEST) -c -cover -covermode=count \
		-coverpkg=github.com/pingcap/tidb/lightning/...,github.com/pingcap/tidb/pkg/lightning/... \
		-o $(LIGHTNING_CTL_BIN).test \
		github.com/pingcap/tidb/lightning/cmd/tidb-lightning-ctl && \
	$(GOBUILD) $(RACE_FLAG) -o bin/fake-oauth tools/fake-oauth/main.go && \
	$(GOBUILD) $(RACE_FLAG) -o bin/parquet_gen tools/gen-parquet/main.go \
	) || (make failpoint-disable && exit 1)
	@make failpoint-disable

.PHONY: lightning_integration_test
lightning_integration_test: build_lightning build_for_lightning_integration_test
	lightning/tests/run.sh

.PHONY: lightning_integration_test_debug
lightning_integration_test_debug:
	lightning/tests/run.sh --no-tiflash

.PHONY: build_for_br_integration_test
build_for_br_integration_test:
	@make failpoint-enable
	($(GOTEST) -c -cover -covermode=count \
		-coverpkg=github.com/pingcap/tidb/br/... \
		-o $(BR_BIN).test \
		github.com/pingcap/tidb/br/cmd/br && \
	$(GOBUILD) $(RACE_FLAG) -o bin/locker br/tests/br_key_locked/*.go && \
	$(GOBUILD) $(RACE_FLAG) -o bin/gc br/tests/br_z_gc_safepoint/*.go && \
	$(GOBUILD) $(RACE_FLAG) -o bin/fake-oauth tools/fake-oauth/main.go && \
	$(GOBUILD) $(RACE_FLAG) -o bin/rawkv br/tests/br_rawkv/*.go && \
	$(GOBUILD) $(RACE_FLAG) -o bin/txnkv br/tests/br_txn/*.go && \
	$(GOBUILD) $(RACE_FLAG) -o bin/utils br/tests/utils.go \
	) || (make failpoint-disable && exit 1)
	@make failpoint-disable

.PHONY: br_unit_test
br_unit_test: export ARGS=$$($(BR_PACKAGES))
br_unit_test: ## Run BR (backup and restore) unit tests
	@make failpoint-enable
	@export TZ='Asia/Shanghai';
	$(GOTEST) --tags=deadlock,intest $(RACE_FLAG) -ldflags '$(LDFLAGS)' $(ARGS) -coverprofile=coverage.txt || ( make failpoint-disable && exit 1 )
	@make failpoint-disable

.PHONY: br_unit_test_in_verify_ci
br_unit_test_in_verify_ci: export ARGS=$$($(BR_PACKAGES))
br_unit_test_in_verify_ci: tools/bin/gotestsum
	@make failpoint-enable
	@export TZ='Asia/Shanghai';
	@mkdir -p $(TEST_COVERAGE_DIR)
	CGO_ENABLED=1 tools/bin/gotestsum --junitfile "$(TEST_COVERAGE_DIR)/br-junit-report.xml" -- --tags=deadlock,intest $(RACE_FLAG) -ldflags '$(LDFLAGS)' \
	$(ARGS) -coverprofile="$(TEST_COVERAGE_DIR)/br_cov.unit_test.out" || ( make failpoint-disable && exit 1 )
	@make failpoint-disable

.PHONY: br_integration_test
br_integration_test: br_bins build_br build_for_br_integration_test
	@cd br && tests/run.sh

.PHONY: br_integration_test_debug
br_integration_test_debug:
	@cd br && tests/run.sh --no-tiflash

.PHONY: br_compatibility_test_prepare
br_compatibility_test_prepare:
	@cd br && tests/run_compatible.sh prepare

.PHONY: br_compatibility_test
br_compatibility_test:
	@cd br && tests/run_compatible.sh run

# mock interface for lightning and IMPORT INTO
.PHONY: mock_import
mock_import: mockgen
	tools/bin/mockgen -package mock github.com/pingcap/tidb/pkg/lightning/backend Backend,EngineWriter,TargetInfoGetter > br/pkg/mock/backend.go
	tools/bin/mockgen -package mock github.com/pingcap/tidb/pkg/lightning/common ChunkFlushStatus > br/pkg/mock/common.go
	tools/bin/mockgen -package mock github.com/pingcap/tidb/pkg/lightning/backend/encode Encoder,EncodingBuilder,Rows,Row > br/pkg/mock/encode.go
	tools/bin/mockgen -package mocklocal github.com/pingcap/tidb/pkg/ingestor/ingestctrl DiskUsage,TiKVModeSwitcher,StoreHelper > br/pkg/mock/mocklocal/local.go
	tools/bin/mockgen -package mock github.com/pingcap/tidb/br/pkg/utils TaskRegister > br/pkg/mock/task_register.go
	tools/bin/mockgen -package mock github.com/pingcap/tidb/pkg/dxf/framework/taskexecutor TaskTable,TaskExecutor,Extension > pkg/dxf/framework/mock/task_executor_mock.go
	tools/bin/mockgen -package mock github.com/pingcap/tidb/pkg/dxf/framework/scheduler Scheduler,Cleaner,ExpiredFileCleaner,TaskManager > pkg/dxf/framework/mock/scheduler_mock.go
	tools/bin/mockgen -destination pkg/dxf/framework/scheduler/mock/scheduler_mock.go -package mock github.com/pingcap/tidb/pkg/dxf/framework/scheduler Extension
	tools/bin/mockgen -embed -package mockexecute github.com/pingcap/tidb/pkg/dxf/framework/taskexecutor/execute StepExecutor > pkg/dxf/framework/mock/execute/execute_mock.go
	tools/bin/mockgen -package mock github.com/pingcap/tidb/pkg/dxf/importinto MiniTaskExecutor > pkg/dxf/importinto/mock/import_mock.go
	tools/bin/mockgen -package mock github.com/pingcap/tidb/pkg/dxf/framework/planner LogicalPlan,PipelineSpec > pkg/dxf/framework/mock/plan_mock.go
	tools/bin/mockgen -package mock github.com/pingcap/tidb/pkg/dxf/framework/storage Manager > pkg/dxf/framework/mock/storage_manager_mock.go
	tools/bin/mockgen -package mock github.com/pingcap/tidb/pkg/ingestor/ingestcli Client,WriteClient > pkg/ingestor/ingestcli/mock/client_mock.go
	tools/bin/mockgen -package mock github.com/pingcap/tidb/pkg/importsdk FileScanner,JobManager,SQLGenerator,SDK > pkg/importsdk/mock/sdk_mock.go
	tools/bin/mockgen -package mock github.com/pingcap/tidb/lightning/pkg/importinto CheckpointManager,JobSubmitter,JobMonitor,JobOrchestrator,ProgressUpdater > lightning/pkg/importinto/mock/import_mock.go

.PHONY: gen_mock
gen_mock: mockgen
	tools/bin/mockgen -package mock github.com/pingcap/tidb/pkg/util/sqlexec RestrictedSQLExecutor > pkg/util/sqlexec/mock/restricted_sql_executor_mock.go
	tools/bin/mockgen -package mockobjstore github.com/pingcap/tidb/pkg/objstore Storage > pkg/objstore/mockobjstore/objstore_mock.go
	tools/bin/mockgen -package mock github.com/pingcap/tidb/pkg/objstore/s3store S3API > pkg/objstore/s3store/mock/s3api_mock.go
	tools/bin/mockgen -package mock github.com/pingcap/tidb/pkg/objstore/ossstore API > pkg/objstore/ossstore/mock/api_mock.go
	tools/bin/mockgen -package mock github.com/aliyun/credentials-go/credentials/providers CredentialsProvider > pkg/objstore/ossstore/mock/provider_mock.go
	tools/bin/mockgen -package mock github.com/pingcap/tidb/pkg/objstore/s3like PrefixClient > pkg/objstore/s3like/mock/client_mock.go
	tools/bin/mockgen -package mock github.com/pingcap/tidb/pkg/ddl SchemaLoader > pkg/ddl/mock/schema_loader_mock.go
	tools/bin/mockgen -package mock github.com/pingcap/tidb/pkg/ddl/systable Manager > pkg/ddl/mock/systable_manager_mock.go
	tools/bin/mockgen -package mock github.com/pingcap/tidb/pkg/domain/sqlsvrapi Server > pkg/domain/sqlsvrapi/mock/server_mock.go
	tools/bin/mockgen -package mock github.com/pingcap/tidb/pkg/domain/sqlsvrapi Runtime > pkg/domain/sqlsvrapi/mock/runtime_mock.go
	tools/bin/mockgen -package mock github.com/pingcap/tidb/pkg/domain/sqlsvrapi KSRuntimeHandle > pkg/domain/sqlsvrapi/mock/ksruntime_mock.go

# There is no FreeBSD environment for GitHub actions. So cross-compile on Linux
# but that doesn't work with CGO_ENABLED=1, so disable cgo. The reason to have
# cgo enabled on regular builds is performance.
ifeq ("$(GOOS)", "freebsd")
        GOBUILD  = CGO_ENABLED=0 GO111MODULE=on go build -trimpath -ldflags '$(LDFLAGS)'
endif

# TODO: adjust bins when br integraion tests reformat.
.PHONY: br_bins
br_bins:
	@which bin/tidb-server
	@which bin/tikv-server
	@which bin/pd-server
	@which bin/pd-ctl
	@which bin/go-ycsb
	@which bin/minio
	@which bin/tiflash
	@which bin/libtiflash_proxy.so
	@which bin/cdc
	@which bin/fake-gcs-server
	@which bin/tikv-importer
	if [ ! -d bin/flash_cluster_manager ]; then echo "flash_cluster_manager not exist"; exit 1; fi

%_generated.go: %.rl
	ragel -Z -G2 -o tmp_parser.go $<
	@echo '// Code generated by ragel DO NOT EDIT.' | cat - tmp_parser.go | sed 's|//line |//.... |g' > $@
	@rm tmp_parser.go

.PHONY: data_parsers
data_parsers: pkg/lightning/mydump/parser_generated.go
	PATH="$(GOPATH)/bin":"$(PATH)":"$(TOOLS)" protoc -I. -I"$(GOMODCACHE)" lightning/pkg/checkpoints/checkpointspb/file_checkpoints.proto --gogofaster_out=.

.PHONY: build_dumpling
build_dumpling: ## Build Dumpling data export tool
	$(DUMPLING_GOBUILD) $(RACE_FLAG) -tags codes -o $(DUMPLING_BIN) dumpling/cmd/dumpling/main.go

.PHONY: dumpling_unit_test
dumpling_unit_test: export DUMPLING_ARGS=$$($(DUMPLING_PACKAGES))
dumpling_unit_test: failpoint-enable ## Run Dumpling (data export) unit tests
	$(DUMPLING_GOTEST) $(RACE_FLAG) -coverprofile=coverage.txt -covermode=atomic $(DUMPLING_ARGS) || ( make failpoint-disable && exit 1 )
	@make failpoint-disable

.PHONY: dumpling_unit_test_in_verify_ci
dumpling_unit_test_in_verify_ci: export DUMPLING_ARGS=$$($(DUMPLING_PACKAGES))
dumpling_unit_test_in_verify_ci: failpoint-enable tools/bin/gotestsum
	@mkdir -p $(TEST_COVERAGE_DIR)
	CGO_ENABLED=1 tools/bin/gotestsum --junitfile "$(TEST_COVERAGE_DIR)/dumpling-junit-report.xml" -- $(DUMPLING_ARGS) \
	$(RACE_FLAG) -coverprofile="$(TEST_COVERAGE_DIR)/dumpling_cov.unit_test.out" || ( make failpoint-disable && exit 1 )
	@make failpoint-disable

.PHONY: dumpling_integration_test
dumpling_integration_test: dumpling_bins failpoint-enable
	@make build_dumpling
	@make failpoint-disable
	./dumpling/tests/run.sh $(CASE)

.PHONY: dumpling_bins
dumpling_bins:
	@which bin/tidb-server
	@which bin/minio
	@which bin/mc
	@which bin/tidb-lightning
	@which bin/sync_diff_inspector

.PHONY: generate_grafana_scripts
generate_grafana_scripts:
	@cd pkg/metrics/grafana && \
	  mv tidb_summary.json tidb_summary.json.committed && \
	  mv tidb_resource_control.json tidb_resource_control.json.committed && \
	  ./generate_json.sh && \
	  diff -u tidb_summary.json.committed tidb_summary.json && \
	  diff -u tidb_resource_control.json.committed tidb_resource_control.json && \
	  rm tidb_summary.json.committed && \
	  rm tidb_resource_control.json.committed


.PHONY: bazel_ci_prepare
bazel_ci_prepare:
	bazel $(BAZEL_GLOBAL_CONFIG) run $(BAZEL_CMD_CONFIG) //:gazelle
	bazel $(BAZEL_GLOBAL_CONFIG) run $(BAZEL_CMD_CONFIG) //:gazelle -- update-repos -from_file=go.mod -to_macro DEPS.bzl%go_deps  -build_file_proto_mode=disable -prune
	bazel $(BAZEL_GLOBAL_CONFIG) run $(BAZEL_CMD_CONFIG)  //cmd/mirror:mirror > tmp.txt
	mv tmp.txt DEPS.bzl
	bazel $(BAZEL_GLOBAL_CONFIG) run $(BAZEL_CMD_CONFIG)  \
		--run_under="cd $(CURDIR) && " \
		 //tools/tazel:tazel

.PHONY: bazel_ci_simple_prepare
bazel_ci_simple_prepare:
	bazel $(BAZEL_GLOBAL_CONFIG) run $(BAZEL_CMD_CONFIG) //:gazelle
	bazel $(BAZEL_GLOBAL_CONFIG) run $(BAZEL_CMD_CONFIG)  \
		--run_under="cd $(CURDIR) && " \
		 //tools/tazel:tazel

.PHONY: bazel_prepare
bazel_prepare: ## Update and generate BUILD.bazel files. Please run this before commit.
	bazel $(BAZEL_GLOBAL_CONFIG) run $(BAZEL_CMD_CONFIG) //:gazelle
	bazel $(BAZEL_GLOBAL_CONFIG) run $(BAZEL_CMD_CONFIG) //:gazelle -- update-repos -from_file=go.mod -to_macro DEPS.bzl%go_deps  -build_file_proto_mode=disable -prune
	bazel $(BAZEL_GLOBAL_CONFIG) run \
		--run_under="cd $(CURDIR) && " \
		 //tools/tazel:tazel
	$(eval $@TMP_OUT := $(shell mktemp -d -t tidbbzl.XXXXXX))
	bazel $(BAZEL_GLOBAL_CONFIG) run $(BAZEL_CMD_CONFIG) //cmd/mirror > $($@TMP_OUT)/tmp.txt
	cp $($@TMP_OUT)/tmp.txt DEPS.bzl
	rm -rf $($@TMP_OUT)

.PHONY: bazel_ci_prepare_rbe
bazel_ci_prepare_rbe:
	bazel run //:gazelle
	bazel run //:gazelle -- update-repos -from_file=go.mod -to_macro DEPS.bzl%go_deps  -build_file_proto_mode=disable -prune
	bazel run --//build:with_rbe_flag=true \
		--run_under="cd $(CURDIR) && " \
		 //tools/tazel:tazel

.PHONY: check-bazel-prepare
check-bazel-prepare:
	@echo "make bazel_prepare"
	./tools/check/check-bazel-prepare.sh

.PHONY: bazel_test
bazel_test: bazel-failpoint-enable bazel_prepare ## Run all tests using Bazel
	bazel $(BAZEL_GLOBAL_CONFIG) test $(BAZEL_CMD_CONFIG) --build_tests_only --test_keep_going=false \
		--define gotags=$(UNIT_TEST_TAGS) \
		-- //... -//cmd/... -//tests/graceshutdown/... \
		-//tests/globalkilltest/... -//tests/readonlytest/... -//tests/realtikvtest/...

BAZEL_BEP_BACKEND ?= grpcs://beplessproxy.channel9.ai
BAZEL_BEP_RESULTS_URL ?= https://bepless.hawkingrei.com/
BAZEL_BEP_BASE_FLAGS = \
	--bes_backend=$(BAZEL_BEP_BACKEND) \
	--bes_results_url=$(BAZEL_BEP_RESULTS_URL) \
	--experimental_remote_build_event_upload=all

.PHONY: bazel_ci_test
bazel_ci_test: bazel-failpoint-enable bazel_ci_simple_prepare
	bazel $(BAZEL_GLOBAL_CONFIG) --nohome_rc test $(BAZEL_CMD_CONFIG) $(BAZEL_INSTRUMENTATION_FILTER) $(BAZEL_BEP_BASE_FLAGS) $$(./build/print-bazel-bep-flags.sh) --jobs=HOST_CPUS*0.9 --build_tests_only --test_keep_going=false \
		--define gotags=$(UNIT_TEST_TAGS) \
		-- //... -//cmd/... -//tests/graceshutdown/... \
		-//tests/globalkilltest/... -//tests/readonlytest/... -//tests/realtikvtest/...

.PHONY: bazel_ci_test_ddlargsv1
bazel_ci_test_ddlargsv1: bazel-failpoint-enable bazel_ci_simple_prepare
	bazel $(BAZEL_GLOBAL_CONFIG) test $(BAZEL_CMD_CONFIG) $(BAZEL_INSTRUMENTATION_FILTER) $(BAZEL_BEP_BASE_FLAGS) $$(./build/print-bazel-bep-flags.sh) --build_tests_only --test_keep_going=false \
		--define gotags=$(UNIT_TEST_TAGS),ddlargsv1 \
		-- //... -//cmd/... -//tests/graceshutdown/... \
		-//tests/globalkilltest/... -//tests/readonlytest/... -//tests/realtikvtest/...

.PHONY: bazel_coverage_test
bazel_coverage_test: bazel-failpoint-enable bazel_ci_simple_prepare
	bazel $(BAZEL_GLOBAL_CONFIG) coverage $(BAZEL_CMD_CONFIG) $(BAZEL_INSTRUMENTATION_FILTER) --build_tests_only --test_keep_going=false \
		--combined_report=lcov \
		--define gotags=$(UNIT_TEST_TAGS) \
		-- //... -//cmd/... -//tests/graceshutdown/... \
		-//tests/globalkilltest/... -//tests/readonlytest/... -//tests/realtikvtest/...

.PHONY: bazel_coverage_test_ddlargsv1
bazel_coverage_test_ddlargsv1: bazel-failpoint-enable bazel_ci_simple_prepare
	bazel $(BAZEL_GLOBAL_CONFIG) coverage $(BAZEL_CMD_CONFIG) $(BAZEL_INSTRUMENTATION_FILTER) --build_tests_only --test_keep_going=false \
		--combined_report=lcov \
		--define gotags=$(UNIT_TEST_TAGS),ddlargsv1 \
		-- //... -//cmd/... -//tests/graceshutdown/... \
		-//tests/globalkilltest/... -//tests/readonlytest/... -//tests/realtikvtest/...

.PHONY: bazel_bin
bazel_bin: ## Build importer/tidb binary files with Bazel build system
	mkdir -p bin; \
	NEXT_GEN=$(NEXT_GEN) bazel $(BAZEL_GLOBAL_CONFIG) build $(BAZEL_CMD_CONFIG) \
		//cmd/importer:importer //cmd/tidb-server:tidb-server --stamp --workspace_status_command=./build/print-workspace-status.sh --action_env=NEXT_GEN --define gotags=$(BUILD_TAGS) --norun_validations ;\
 	cp -f ${TIDB_SERVER_PATH} ./bin/ ; \
 	cp -f ${IMPORTER_PATH} ./bin/ ;

.PHONY: bazel_build
bazel_build: ## Build TiDB using Bazel build system
	mkdir -p bin
	bazel $(BAZEL_GLOBAL_CONFIG) build $(BAZEL_CMD_CONFIG) \
		//... --//build:with_nogo_flag=$(NOGO_FLAG)
	NEXT_GEN=$(NEXT_GEN) bazel $(BAZEL_GLOBAL_CONFIG) build $(BAZEL_CMD_CONFIG) \
		//cmd/importer:importer //cmd/tidb-server:tidb-server //cmd/tidb-server:tidb-server-check --stamp --workspace_status_command=./build/print-workspace-status.sh --action_env=NEXT_GEN --define gotags=$(BUILD_TAGS) --//build:with_nogo_flag=$(NOGO_FLAG) ;\
	cp -f ${TIDB_SERVER_PATH} ./bin/ ;\
	cp -f ${IMPORTER_PATH} ./bin/ ; \
	cp -f ${TIDB_SERVER_CHECK_PATH} ./bin/ ; \
	NEXT_GEN=$(NEXT_GEN) bazel $(BAZEL_GLOBAL_CONFIG) build $(BAZEL_CMD_CONFIG) \
		//cmd/tidb-server:tidb-server --stamp --workspace_status_command=./build/print-enterprise-workspace-status.sh --action_env=NEXT_GEN --define gotags=$(BUILD_TAGS),enterprise; \
	cp -f ${TIDB_SERVER_PATH} ./bin/ ;\
	./bin/tidb-server -V

.PHONY: bazel_fail_build
bazel_fail_build:  failpoint-enable bazel_ci_prepare
	bazel $(BAZEL_GLOBAL_CONFIG) build $(BAZEL_CMD_CONFIG) \
		//...

.PHONY: bazel_clean
bazel_clean:
	bazel $(BAZEL_GLOBAL_CONFIG) clean

.PHONY: bazel_junit
bazel_junit:
	bazel_collect
	@mkdir -p $(TEST_COVERAGE_DIR)
	mv ./junit.xml `$(TEST_COVERAGE_DIR)/junit.xml`

.PHONY: bazel_golangcilinter
bazel_golangcilinter:
	bazel $(BAZEL_GLOBAL_CONFIG) run $(BAZEL_CMD_CONFIG) \
		--run_under="cd $(CURDIR) && " \
		@com_github_golangci_golangci_lint//cmd/golangci-lint:golangci-lint \
	-- run  $$($(PACKAGE_DIRECTORIES)) --config ./.golangci.yaml

.PHONY: bazel_brietest
bazel_brietest: failpoint-enable bazel_ci_simple_prepare
	bazel $(BAZEL_GLOBAL_CONFIG) test $(BAZEL_CMD_CONFIG) --test_arg=-with-real-tikv --define gotags=$(REAL_TIKV_TEST_TAGS) --jobs=1 \
	--test_env=BRIETEST_TMPDIR --sandbox_writable_path=$${BRIETEST_TMPDIR:-$(CURDIR)} \
		-- //tests/realtikvtest/brietest/...

.PHONY: bazel_pessimistictest
bazel_pessimistictest: failpoint-enable bazel_ci_simple_prepare
	bazel $(BAZEL_GLOBAL_CONFIG) test $(BAZEL_CMD_CONFIG) --test_arg=-with-real-tikv --define gotags=$(REAL_TIKV_TEST_TAGS) --jobs=1 \
		-- //tests/realtikvtest/pessimistictest/...

.PHONY: bazel_sessiontest
bazel_sessiontest: failpoint-enable bazel_ci_simple_prepare
	bazel $(BAZEL_GLOBAL_CONFIG) test $(BAZEL_CMD_CONFIG) --test_arg=-with-real-tikv --define gotags=$(REAL_TIKV_TEST_TAGS) --jobs=1 \
		-- //tests/realtikvtest/sessiontest/...

.PHONY: startertest
startertest: failpoint-enable bazel_ci_simple_prepare
	# Starter mode needs an external tidb-server process, so this wrapper
	# intentionally invokes the starter shell runner instead of bazel test.
	STARTER_KEYSPACE_NAME=startertest STARTER_RUN_EXIT_WAIT_TEST=1 tests/realtikvtest/scripts/next-gen/run-starter-tests-with-server.sh --under-cluster startertest 40m -count=1

.PHONY: bazel_statisticstest
bazel_statisticstest: failpoint-enable bazel_ci_simple_prepare
	bazel $(BAZEL_GLOBAL_CONFIG) test $(BAZEL_CMD_CONFIG) --test_arg=-with-real-tikv --define gotags=$(REAL_TIKV_TEST_TAGS) --jobs=1 \
		-- //tests/realtikvtest/statisticstest/...

.PHONY: bazel_txntest
bazel_txntest: failpoint-enable bazel_ci_simple_prepare
	bazel $(BAZEL_GLOBAL_CONFIG) test $(BAZEL_CMD_CONFIG) --test_arg=-with-real-tikv --define gotags=$(REAL_TIKV_TEST_TAGS) --jobs=1 \
		-- //tests/realtikvtest/txntest/...

.PHONY: bazel_pushdowntest
bazel_pushdowntest: failpoint-enable bazel_ci_simple_prepare
	bazel $(BAZEL_GLOBAL_CONFIG) test $(BAZEL_CMD_CONFIG) --test_output=all --test_arg=-with-real-tikv --define gotags=$(REAL_TIKV_TEST_TAGS) --jobs=1 \
		-- //tests/realtikvtest/pushdowntest/...

.PHONY: bazel_addindextest
bazel_addindextest: failpoint-enable bazel_ci_simple_prepare
	bazel $(BAZEL_GLOBAL_CONFIG) test $(BAZEL_CMD_CONFIG) --test_output=all --test_arg=-with-real-tikv --define gotags=$(REAL_TIKV_TEST_TAGS) --jobs=1 \
		-- //tests/realtikvtest/addindextest/...

.PHONY: bazel_addindextest1
bazel_addindextest1: failpoint-enable bazel_ci_simple_prepare
	bazel $(BAZEL_GLOBAL_CONFIG) test $(BAZEL_CMD_CONFIG) --test_output=all --test_arg=-with-real-tikv --define gotags=$(REAL_TIKV_TEST_TAGS) --jobs=1 \
		-- //tests/realtikvtest/addindextest1/...

.PHONY: bazel_addindextest2
bazel_addindextest2: failpoint-enable bazel_ci_simple_prepare
	bazel $(BAZEL_GLOBAL_CONFIG) test $(BAZEL_CMD_CONFIG) --test_output=all --test_arg=-with-real-tikv --define gotags=$(REAL_TIKV_TEST_TAGS) --jobs=1 \
		-- //tests/realtikvtest/addindextest2/...

.PHONY: bazel_addindextest3
bazel_addindextest3: failpoint-enable bazel_ci_simple_prepare
	bazel $(BAZEL_GLOBAL_CONFIG) test $(BAZEL_CMD_CONFIG) --test_output=all --test_arg=-with-real-tikv --define gotags=$(REAL_TIKV_TEST_TAGS) --jobs=1 \
		-- //tests/realtikvtest/addindextest3/...

.PHONY: bazel_addindextest4
bazel_addindextest4: failpoint-enable bazel_ci_simple_prepare
	bazel $(BAZEL_GLOBAL_CONFIG) test $(BAZEL_CMD_CONFIG) --test_output=all --test_arg=-with-real-tikv --define gotags=$(REAL_TIKV_TEST_TAGS) --jobs=1 \
		-- //tests/realtikvtest/addindextest4/...

# on timeout, bazel won't print log sometimes, so we use --test_output=all to print log always
.PHONY: bazel_importintotest
bazel_importintotest: failpoint-enable bazel_ci_simple_prepare
	bazel $(BAZEL_GLOBAL_CONFIG) test $(BAZEL_CMD_CONFIG) --test_output=all --test_arg=-with-real-tikv --define gotags=$(REAL_TIKV_TEST_TAGS) --jobs=1 \
		-- //tests/realtikvtest/importintotest/...

# on timeout, bazel won't print log sometimes, so we use --test_output=all to print log always
.PHONY: bazel_importintotest2
bazel_importintotest2: failpoint-enable bazel_ci_simple_prepare
	bazel $(BAZEL_GLOBAL_CONFIG) test $(BAZEL_CMD_CONFIG) --test_output=all --test_arg=-with-real-tikv --define gotags=$(REAL_TIKV_TEST_TAGS) --jobs=1 \
		-- //tests/realtikvtest/importintotest2/...

# on timeout, bazel won't print log sometimes, so we use --test_output=all to print log always
.PHONY: bazel_importintotest3
bazel_importintotest3: failpoint-enable bazel_ci_simple_prepare
	bazel $(BAZEL_GLOBAL_CONFIG) test $(BAZEL_CMD_CONFIG) --test_output=all --test_arg=-with-real-tikv --define gotags=$(REAL_TIKV_TEST_TAGS) --jobs=1 \
		-- //tests/realtikvtest/importintotest3/...

# on timeout, bazel won't print log sometimes, so we use --test_output=all to print log always
.PHONY: bazel_importintotest4
bazel_importintotest4: failpoint-enable bazel_ci_simple_prepare
	bazel $(BAZEL_GLOBAL_CONFIG) test $(BAZEL_CMD_CONFIG) --test_output=all --test_arg=-with-real-tikv --define gotags=$(REAL_TIKV_TEST_TAGS) --jobs=1 \
		-- //tests/realtikvtest/importintotest4/...

# on timeout, bazel won't print log sometimes, so we use --test_output=all to print log always
.PHONY: bazel_pipelineddmltest
bazel_pipelineddmltest: failpoint-enable bazel_ci_simple_prepare
	bazel $(BAZEL_GLOBAL_CONFIG) test $(BAZEL_CMD_CONFIG) --test_output=all --test_arg=-with-real-tikv --define gotags=$(REAL_TIKV_TEST_TAGS) --jobs=1 \
		-- //tests/realtikvtest/pipelineddmltest/...

# on timeout, bazel won't print log sometimes, so we use --test_output=all to print log always
.PHONY: bazel_flashbacktest
bazel_flashbacktest: failpoint-enable bazel_ci_simple_prepare
	bazel $(BAZEL_GLOBAL_CONFIG) test $(BAZEL_CMD_CONFIG) --test_output=all --test_arg=-with-real-tikv --define gotags=$(REAL_TIKV_TEST_TAGS) --jobs=1 \
		-- //tests/realtikvtest/flashbacktest/...

# on timeout, bazel won't print log sometimes, so we use --test_output=all to print log always
.PHONY: bazel_ddltest
bazel_ddltest: failpoint-enable bazel_ci_simple_prepare
	bazel $(BAZEL_GLOBAL_CONFIG) test $(BAZEL_CMD_CONFIG) --test_output=all --test_arg=-with-real-tikv --define gotags=$(REAL_TIKV_TEST_TAGS) --jobs=1 \
		-- //tests/realtikvtest/ddltest/...

.PHONY: bazel_lint
bazel_lint: bazel_prepare
	bazel build $(BAZEL_CMD_CONFIG) //... --//build:with_nogo_flag=$(NOGO_FLAG)

.PHONY: bazel_lint_changed
bazel_lint_changed: bazel_prepare
	@PKGS="$$(build/get_changed_bazel_pkgs.sh)"; \
	echo "$$PKGS"; \
	if [ -z "$$PKGS" ]; then \
		echo "No changed bazel packages detected, skip bazel_lint_changed."; \
		exit 0; \
	fi; \
	bazel build $(BAZEL_CMD_CONFIG) $$PKGS --//build:with_nogo_flag=$(NOGO_FLAG)

.PHONY: docker
docker: ## Build TiDB Docker image
	docker build -t "$(DOCKERPREFIX)tidb:latest" --build-arg 'GOPROXY=$(shell go env GOPROXY),' -f Dockerfile .

.PHONY: docker-test
docker-test:
	docker buildx build --platform linux/amd64,linux/arm64 --push -t "$(DOCKERPREFIX)tidb:latest" --build-arg 'GOPROXY=$(shell go env GOPROXY),' -f Dockerfile .

.PHONY: bazel_mirror
bazel_mirror:
	$(eval $@TMP_OUT := $(shell mktemp -d -t tidbbzl.XXXXXX))
	bazel $(BAZEL_GLOBAL_CONFIG) run $(BAZEL_CMD_CONFIG) --norun_validations //cmd/mirror:mirror > $($@TMP_OUT)/tmp.txt
	cp $($@TMP_OUT)/tmp.txt DEPS.bzl
	rm -rf $($@TMP_OUT)

.PHONY: bazel_sync
bazel_sync:
	bazel $(BAZEL_GLOBAL_CONFIG) sync $(BAZEL_SYNC_CONFIG)

.PHONY: bazel_mirror_upload
bazel_mirror_upload:
	@echo "bazel_mirror_upload is deprecated; Go modules are resolved through GOPROXY. Run 'make bazel_mirror' to regenerate DEPS.bzl."

.PHONY: bazel_check_abi
bazel_check_abi:
	@echo "check ABI compatibility"
	./tools/check/bazel-check-abi.sh