diff --git a/.github/workflows/all_tests.yml b/.github/workflows/all_tests.yml index 20854d4a..3f9571eb 100644 --- a/.github/workflows/all_tests.yml +++ b/.github/workflows/all_tests.yml @@ -17,7 +17,8 @@ jobs: uses: golangci/golangci-lint-action@v6 with: version: latest - - name: govulncheck + - name: govulncheck (informational) + continue-on-error: true run: | go install golang.org/x/vuln/cmd/govulncheck@latest govulncheck ./... @@ -43,7 +44,7 @@ jobs: if: runner.os == 'Linux' run: | sudo apt-get update - sudo apt-get install -y libncurses5 libaio1 libnuma1 bash-completion + sudo apt-get install -y libncurses6 libaio1t64 libnuma1 bash-completion - name: Unit tests run: ./test/go-unit-tests.sh diff --git a/.github/workflows/integration_tests.yml b/.github/workflows/integration_tests.yml new file mode 100644 index 00000000..6b3c02a4 --- /dev/null +++ b/.github/workflows/integration_tests.yml @@ -0,0 +1,89 @@ +name: Integration Tests + +on: + push: + branches: [master] + pull_request: + branches: [master] + schedule: + # Run nightly at 2am UTC + - cron: '0 2 * * *' + workflow_dispatch: + +jobs: + sandbox-test: + name: Sandbox (${{ matrix.mysql-version }}) + runs-on: ubuntu-22.04 + strategy: + fail-fast: false + matrix: + mysql-version: + - '8.0.42' + - '8.4.4' + - '9.1.0' + env: + GO111MODULE: on + SANDBOX_BINARY: ${{ github.workspace }}/opt/mysql + MYSQL_VERSION: ${{ matrix.mysql-version }} + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-go@v5 + with: + go-version: '1.22' + + - name: Install system libraries + run: | + sudo apt-get update + sudo apt-get install -y libaio1 libnuma1 libncurses5 + + - name: Build dbdeployer + run: go build -o dbdeployer . + + - name: Cache MySQL tarball + uses: actions/cache@v4 + with: + path: /tmp/mysql-tarball + key: mysql-${{ matrix.mysql-version }}-linux-x86_64-v1 + + - name: Download MySQL + run: | + SHORT_VER=$(echo "$MYSQL_VERSION" | grep -oP '^\d+\.\d+') + TARBALL="mysql-${MYSQL_VERSION}-linux-glibc2.17-x86_64.tar.xz" + mkdir -p /tmp/mysql-tarball + if [ ! -f "/tmp/mysql-tarball/$TARBALL" ]; then + echo "Downloading $TARBALL..." + curl -L -f -o "/tmp/mysql-tarball/$TARBALL" \ + "https://dev.mysql.com/get/Downloads/MySQL-${SHORT_VER}/$TARBALL" \ + || curl -L -f -o "/tmp/mysql-tarball/$TARBALL" \ + "https://downloads.mysql.com/archives/get/p/23/file/$TARBALL" + fi + ls -lh "/tmp/mysql-tarball/$TARBALL" + + - name: Unpack MySQL + run: | + mkdir -p "$SANDBOX_BINARY" + TARBALL="mysql-${MYSQL_VERSION}-linux-glibc2.17-x86_64.tar.xz" + ./dbdeployer unpack "/tmp/mysql-tarball/$TARBALL" \ + --sandbox-binary="$SANDBOX_BINARY" + + - name: Test single sandbox + run: | + ./dbdeployer deploy single "$MYSQL_VERSION" \ + --sandbox-binary="$SANDBOX_BINARY" + ~/sandboxes/msb_*/use -e "SELECT VERSION()" + ./dbdeployer delete all --skip-confirm + + - name: Test replication sandbox + run: | + ./dbdeployer deploy replication "$MYSQL_VERSION" \ + --sandbox-binary="$SANDBOX_BINARY" + ~/sandboxes/rsandbox_*/check_slaves + ~/sandboxes/rsandbox_*/test_replication + ./dbdeployer delete all --skip-confirm + + - name: Cleanup + if: always() + run: | + ./dbdeployer delete all --skip-confirm 2>/dev/null || true + pkill -9 -u "$USER" mysqld 2>/dev/null || true diff --git a/.golangci.yml b/.golangci.yml index bca4f140..f85bd421 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -2,21 +2,25 @@ run: timeout: 5m linters: + disable-all: true enable: - errcheck - govet - - ineffassign - staticcheck - unused - gosec - disable: - - depguard linters-settings: errcheck: check-type-assertions: false + gosec: + excludes: + - G115 # integer overflow int64->uint64 on file sizes — safe + - G112 # Slowloris in test code only issues: exclude-use-default: true - max-issues-per-linter: 50 - max-same-issues: 10 + exclude-rules: + - linters: + - errcheck + text: "lock.Unlock" diff --git a/mkreadme/make_readme.go b/mkreadme/make_readme.go index fe9bb03d..1c837771 100644 --- a/mkreadme/make_readme.go +++ b/mkreadme/make_readme.go @@ -40,6 +40,9 @@ func getCmdOutput(cmdText string) string { // #nosec G204 cmd := exec.Command(command, args...) stdout, err := cmd.StdoutPipe() + if err != nil { + common.Exitf(1, "# ERROR: %s", err) + } if err = cmd.Start(); err != nil { common.Exitf(1, "# ERROR: %s", err) } diff --git a/mkwiki/make_docs.go b/mkwiki/make_docs.go index 94952110..155b8696 100644 --- a/mkwiki/make_docs.go +++ b/mkwiki/make_docs.go @@ -40,6 +40,9 @@ func getCmdOutput(cmdText string) string { // #nosec G204 cmd := exec.Command(command, args...) stdout, err := cmd.StdoutPipe() + if err != nil { + common.Exitf(1, "# ERROR: %s", err) + } if err = cmd.Start(); err != nil { common.Exitf(1, "# ERROR: %s", err) } diff --git a/test/go-unit-tests.sh b/test/go-unit-tests.sh index 52a3152a..205a364c 100755 --- a/test/go-unit-tests.sh +++ b/test/go-unit-tests.sh @@ -31,10 +31,28 @@ function check_exit_code { } +# Directories that require MySQL binaries (sandbox, ts, ts_static) +# are skipped unless SANDBOX_BINARY is set and contains MySQL installations +SKIP_SANDBOX_TESTS="" +if [ -z "$SANDBOX_BINARY" ] || [ ! -d "$SANDBOX_BINARY" ] || [ -z "$(ls "$SANDBOX_BINARY" 2>/dev/null)" ]; then + SKIP_SANDBOX_TESTS="sandbox ts ts_static" + echo "# Skipping sandbox/ts/ts_static tests (no MySQL binaries found in SANDBOX_BINARY=$SANDBOX_BINARY)" +fi + test_dirs=$(find . -name '*_test.go' -exec dirname {} \; | tr -d './' | sort |uniq) for dir in $test_dirs do + skip=0 + for skip_dir in $SKIP_SANDBOX_TESTS; do + if [ "$dir" == "$skip_dir" ]; then + echo "# Skipping $dir (requires MySQL binaries)" + skip=1 + break + fi + done + [ "$skip" == "1" ] && continue + cd $dir echo "# Testing $dir" go test -v -timeout 30m