replace deprecated pflag ParseErrorsWhitelist with ParseErrorsAllowlist #1878
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Functional Test is a subset of minikube integration test, testing the most essential features of minikube. | |
| name: Functional Test | |
| on: | |
| workflow_dispatch: | |
| pull_request: | |
| paths: | |
| - "go.mod" | |
| - "**.go" | |
| - "Makefile" | |
| - .github/workflows/functional_test.yml | |
| - "!site/**" | |
| - "!**.md" | |
| - "!**.json" | |
| push: | |
| branches: [ master ] | |
| paths: | |
| - "go.mod" | |
| - "**.go" | |
| - "Makefile" | |
| - "!site/**" | |
| - "!**.md" | |
| - "!**.json" | |
| # Limit one functional test job running per PR/Branch | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} | |
| # For example, if you push multiple commits to a pull request in quick succession, only the latest workflow run will continue | |
| cancel-in-progress: true | |
| env: | |
| GOPROXY: https://proxy.golang.org | |
| GO_VERSION: '1.25.5' | |
| permissions: | |
| contents: read | |
| jobs: | |
| # build-test-binaries job runs before all other jobs and produces binaries/test-data per arch to be shared by all following jobs | |
| build-test-binaries: | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - name: build-test-binaries-x86 | |
| arch: amd64 | |
| runs-on: ubuntu-24.04 | |
| make-targets: e2e-linux-amd64 | |
| - name: build-test-binaries-arm | |
| arch: arm64 | |
| runs-on: ubuntu-24.04-arm | |
| make-targets: e2e-linux-arm64 | |
| runs-on: ${{ matrix.runs-on }} | |
| name: ${{ matrix.name }} | |
| steps: | |
| - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 | |
| - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c | |
| with: | |
| go-version: ${{env.GO_VERSION}} | |
| cache: true | |
| - name: Download Dependencies | |
| run: go mod download | |
| - name: Build minikube and e2e test binaries | |
| run: | | |
| make ${{ matrix.make-targets }} | |
| cp -r test/integration/testdata ./out | |
| - name: Upload Test Binaries | |
| uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f | |
| with: | |
| name: binaries-${{ matrix.arch }} | |
| path: out | |
| functional-test: | |
| name: ${{ matrix.name }} | |
| needs: build-test-binaries | |
| runs-on: ${{ matrix.os }} | |
| permissions: | |
| contents: none | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - name: docker-docker-ubuntu24.04-x86 | |
| driver: docker | |
| cruntime: docker | |
| os: ubuntu-24.04 | |
| arch: amd64 | |
| test-timeout: 18m | |
| - name: docker-docker-ubuntu24.04-arm | |
| driver: docker | |
| cruntime: docker | |
| os: ubuntu-24.04-arm | |
| arch: arm64 | |
| test-timeout: 18m | |
| - name: docker-containerd-ubuntu-24.04-x86 | |
| driver: docker | |
| cruntime: containerd | |
| extra-start-args: --container-runtime=containerd | |
| os: ubuntu-24.04 | |
| arch: amd64 | |
| test-timeout: 18m | |
| - name: docker-containerd-ubuntu-24.04-arm | |
| driver: docker | |
| cruntime: containerd | |
| extra-start-args: --container-runtime=containerd | |
| os: ubuntu-24.04-arm | |
| arch: arm64 | |
| test-timeout: 18m | |
| - name: docker-containerd-rootless-ubuntu-24.04-x86 | |
| driver: docker | |
| cruntime: containerd | |
| os: ubuntu-24.04 | |
| extra-start-args: --container-runtime=containerd --rootless | |
| rootless: true | |
| arch: amd64 | |
| test-timeout: 18m | |
| - name: podman-docker-ubuntu-24.04-x86 | |
| driver: podman | |
| cruntime: docker | |
| os: ubuntu-24.04 | |
| arch: amd64 | |
| test-timeout: 22m | |
| - name: baremetal-docker-ubuntu-24.04-x86 | |
| driver: none | |
| cruntime: docker | |
| os: ubuntu-24.04 | |
| arch: amd64 | |
| test-timeout: 10m | |
| - name: baremetal-docker-ubuntu-24.04-arm | |
| driver: none | |
| cruntime: docker | |
| os: ubuntu-24.04-arm | |
| arch: arm64 | |
| test-timeout: 10m | |
| - name: baremetal-containerd-ubuntu-24.04-x86 | |
| driver: none | |
| cruntime: containerd | |
| os: ubuntu-24.04 | |
| arch: amd64 | |
| extra-start-args: --container-runtime=containerd | |
| test-timeout: 10m | |
| - name: baremetal-containerd-ubuntu-24.04-arm | |
| driver: none | |
| cruntime: containerd | |
| os: ubuntu-24.04-arm | |
| arch: arm64 | |
| extra-start-args: --container-runtime=containerd | |
| test-timeout: 10m | |
| steps: | |
| - id: info-block | |
| uses: medyagh/info-block@main | |
| - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c | |
| with: | |
| go-version: ${{env.GO_VERSION}} | |
| cache: true | |
| - name: Install gopogh | |
| shell: bash | |
| run: | | |
| GOPOGH_VERSION=v0.29.0 | |
| GOOS=$(go env GOOS) | |
| GOARCH=$(go env GOARCH) | |
| URL="https://github.com/medyagh/gopogh/releases/download/${GOPOGH_VERSION}/gopogh-${GOOS}-${GOARCH}" | |
| echo "Downloading ${URL}" | |
| curl -fsSL "${URL}" -o gopogh | |
| sudo install -m 0755 gopogh /usr/local/bin/gopogh | |
| rm gopogh | |
| command -v gopogh | |
| gopogh -version || true | |
| - name: Set up cgroup v2 delegation (rootless) | |
| if: ${{ matrix.rootless }} | |
| run: | | |
| sudo mkdir -p /etc/systemd/system/user@.service.d | |
| cat <<EOF | sudo tee /etc/systemd/system/user@.service.d/delegate.conf | |
| [Service] | |
| Delegate=cpu cpuset io memory pids | |
| EOF | |
| sudo systemctl daemon-reload | |
| - name: Set up Rootless Docker (rootless) | |
| if: ${{ matrix.rootless }} | |
| run: | | |
| sudo apt-get remove moby-engine-* | |
| curl https://get.docker.com | sudo sh | |
| dockerd-rootless-setuptool.sh install -f | |
| docker context use rootless | |
| - name: Update brew package index (macos) | |
| if: contains(matrix.os, 'macos') | |
| run: brew update | |
| - name: Update apt-get package index (ubuntu) | |
| if: runner.os == 'Linux' && (matrix.driver == 'podman' || matrix.driver == 'none') | |
| run: sudo apt-get update -qq | |
| - name: Install cri_dockerd (baremetal only) | |
| shell: bash | |
| if: matrix.driver == 'none' && matrix.cruntime == 'docker' | |
| run: | | |
| CRI_DOCKERD_VERSION="v0.4.1" | |
| CRI_DOCKERD_COMMIT="55d6e1a1d6f2ee58949e13a0c66afe7d779ac942" | |
| CRI_DOCKERD_BASE_URL="https://storage.googleapis.com/kicbase-artifacts/cri-dockerd/${CRI_DOCKERD_COMMIT}" | |
| ARCH="${{ matrix.arch }}" | |
| sudo curl -L "${CRI_DOCKERD_BASE_URL}/${ARCH}/cri-dockerd" -o /usr/bin/cri-dockerd | |
| sudo curl -L "${CRI_DOCKERD_BASE_URL}/cri-docker.socket" -o /usr/lib/systemd/system/cri-docker.socket | |
| sudo curl -L "${CRI_DOCKERD_BASE_URL}/cri-docker.service" -o /usr/lib/systemd/system/cri-docker.service | |
| sudo chmod +x /usr/bin/cri-dockerd | |
| - name: Install crictl (baremetal only) | |
| shell: bash | |
| if: matrix.driver == 'none' | |
| run: | | |
| CRICTL_VERSION="v1.35.0" | |
| ARCH="${{ matrix.arch }}" | |
| CRICTL_TAR="crictl-${CRICTL_VERSION}-linux-${ARCH}.tar.gz" | |
| curl -L "https://github.com/kubernetes-sigs/cri-tools/releases/download/${CRICTL_VERSION}/${CRICTL_TAR}" --output "${CRICTL_TAR}" | |
| sudo tar zxvf "${CRICTL_TAR}" -C /usr/local/bin | |
| # conntrack is required for kubernetes 1.18 and higher | |
| - name: Install conntrack & socat (baremetal only) | |
| shell: bash | |
| if: matrix.driver == 'none' | |
| run: sudo apt-get -qq -y install conntrack | |
| # socat is required for kubectl port forward which is used in some tests | |
| - name: Install socat (baremetal only) | |
| shell: bash | |
| if: matrix.driver == 'none' | |
| run: sudo apt-get -qq -y install socat | |
| - name: Install container networking plugins (baremetal only) | |
| shell: bash | |
| if: matrix.driver == 'none' | |
| run: | | |
| CNI_PLUGIN_VERSION="v1.9.0" | |
| ARCH="${{ matrix.arch }}" | |
| CNI_PLUGIN_TAR="cni-plugins-linux-${ARCH}-$CNI_PLUGIN_VERSION.tgz" | |
| CNI_PLUGIN_INSTALL_DIR="/opt/cni/bin" | |
| curl -LO "https://github.com/containernetworking/plugins/releases/download/$CNI_PLUGIN_VERSION/$CNI_PLUGIN_TAR" | |
| sudo mkdir -p "$CNI_PLUGIN_INSTALL_DIR" | |
| sudo tar -xf "$CNI_PLUGIN_TAR" -C "$CNI_PLUGIN_INSTALL_DIR" | |
| rm "$CNI_PLUGIN_TAR" | |
| - name: Install docker-cli | |
| run: | | |
| set -x | |
| if [[ "$RUNNER_OS" == "macOS" ]]; then | |
| brew install docker | |
| fi | |
| echo "=== Docker Version ===" | |
| docker version || true | |
| if [[ "$RUNNER_OS" == "Linux" ]]; then | |
| echo "=== Docker Info ===" | |
| docker info || true | |
| echo "=== Docker Disk Usage ===" | |
| docker system df || true | |
| echo "=== Docker System Info (JSON) ===" | |
| docker system info --format='{{json .}}' | { command -v jq >/dev/null 2>&1 && jq . || cat; } || true | |
| echo "=== Running Containers ===" | |
| docker ps -a || true | |
| echo "=== Images ===" | |
| docker images || true | |
| fi | |
| - name: Install podman | |
| if: matrix.driver == 'podman' | |
| shell: bash | |
| run: | | |
| sudo apt -q update | |
| sudo apt install -q -y podman | |
| lsb_release -a || true | |
| echo "=== podman version ===" | |
| podman version || true | |
| echo "=== podman info ===" | |
| podman info || true | |
| echo "=== podman system df ===" | |
| podman system df || true | |
| echo "=== podman system info (JSON) ===" | |
| podman system info --format='{{json .}}' || true | |
| echo "=== podman ps ===" | |
| podman ps || true | |
| - name: Install kubectl | |
| uses: azure/setup-kubectl@v4 | |
| - name: Install qemu and socket_vmnet (macos) | |
| if: contains(matrix.os, 'macos') && matrix.driver == 'qemu' | |
| run: | | |
| brew install qemu socket_vmnet | |
| HOMEBREW=$(which brew) && sudo ${HOMEBREW} services start socket_vmnet | |
| - name: Install vfkit and vmnet_helper (macos) | |
| if: matrix.driver == 'vfkit' | |
| run: | | |
| brew install vfkit | |
| curl -fsSL https://github.com/minikube-machine/vmnet-helper/releases/latest/download/install.sh | sudo VMNET_INTERACTIVE=0 bash | |
| - name: Download Test Binaries | |
| uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 | |
| with: | |
| name: binaries-${{ matrix.arch }} | |
| - name: Disable AppArmor for MySQL | |
| if: runner.os == 'Linux' | |
| run: | | |
| sudo ln -s /etc/apparmor.d/usr.sbin.mysqld /etc/apparmor.d/disable/ | |
| sudo apparmor_parser -R /etc/apparmor.d/usr.sbin.mysqld | |
| - name: Install containerd (baremetal only) | |
| if: matrix.driver == 'none' && matrix.cruntime == 'containerd' | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y containerd | |
| # Configure containerd | |
| sudo mkdir -p /etc/containerd | |
| containerd config default | sudo tee /etc/containerd/config.toml | |
| sudo systemctl restart containerd | |
| - name: Run Functional Test | |
| id: run_test | |
| continue-on-error: true | |
| shell: bash | |
| run: | | |
| set -x | |
| mkdir -p report | |
| chmod a+x ./e2e-* | |
| chmod a+x ./minikube-* | |
| ./minikube-$(go env GOOS)-$(go env GOARCH) delete --all --purge | |
| START_TIME=$(date -u +%s) | |
| ./e2e-$(go env GOOS)-$(go env GOARCH) -minikube-start-args=" --driver=${{ matrix.driver }} ${{ matrix.extra-start-args }} -v=6 --alsologtostderr" -test.run TestFunctional -test.timeout=${{ matrix.test-timeout }} -test.v -binary=./minikube-$(go env GOOS)-$(go env GOARCH) 2>&1 | tee ./report/testout.txt | |
| END_TIME=$(date -u +%s) | |
| TIME_ELAPSED=$(($END_TIME-$START_TIME)) | |
| min=$((${TIME_ELAPSED}/60)) | |
| sec=$((${TIME_ELAPSED}%60)) | |
| TIME_ELAPSED="${min} min $sec seconds " | |
| # make variables available for next step | |
| echo "TIME_ELAPSED=${TIME_ELAPSED}" >> $GITHUB_ENV | |
| - name: Generate Gopogh HTML Report | |
| if: always() | |
| shell: bash | |
| run: | | |
| go tool test2json -t < ./report/testout.txt > ./report/testout.json || true | |
| STAT=$(gopogh -in ./report/testout.json -out_html ./report/testout.html -out_summary ./report/testout_summary.json -name "${{ matrix.name }} ${GITHUB_REF}" -repo "${GITHUB_REPOSITORY}" -details "${GITHUB_SHA}") || true | |
| # Check if the test step failed AND the log contains "timed out" | |
| if [[ "${{ steps.run_test.outcome }}" == "failure" && $(grep -c "panic: test timed out" ./report/testout.txt) -gt 0 ]]; then | |
| # If it was a timeout, set your custom message | |
| RESULT_SHORT="⌛⌛⌛ Test Timed out ${TIME_ELAPSED} ⌛⌛⌛" | |
| else | |
| PassNum=$(echo $STAT | jq '.NumberOfPass') | |
| FailNum=$(echo $STAT | jq '.NumberOfFail') | |
| TestsNum=$(echo $STAT | jq '.NumberOfTests') | |
| if [ "${FailNum}" -eq 0 ]; then | |
| STATUS_ICON="✓" | |
| else | |
| STATUS_ICON="✗" | |
| fi | |
| if [ "${PassNum}" -eq 0 ]; then | |
| STATUS_ICON="✗" | |
| fi | |
| # Result in one sentence | |
| RESULT_SHORT="${STATUS_ICON} Completed with ${FailNum} / ${TestsNum} failures in ${TIME_ELAPSED}" | |
| fi | |
| echo "RESULT_SHORT=${RESULT_SHORT}" >> $GITHUB_ENV | |
| echo "TIME_ELAPSED=${TIME_ELAPSED}" >> $GITHUB_ENV | |
| echo 'STAT<<EOF' >> $GITHUB_ENV | |
| echo "${STAT}" >> $GITHUB_ENV | |
| echo 'EOF' >> $GITHUB_ENV | |
| - name: Set PR or Branch label for report filename | |
| id: vars | |
| run: | | |
| if [ "${{ github.event_name }}" = "pull_request" ]; then | |
| echo "PR_OR_MASTER=PR${{ github.event.pull_request.number }}" >> $GITHUB_OUTPUT | |
| else | |
| echo "PR_OR_MASTER=Master" >> $GITHUB_OUTPUT | |
| fi | |
| echo "COMMIT_SHA=${GITHUB_SHA:0:7}" >> $GITHUB_OUTPUT | |
| RUN_ID_SHORT="$GITHUB_RUN_ID" | |
| if [ ${#RUN_ID_SHORT} -gt 7 ]; then | |
| RUN_ID_SHORT="${RUN_ID_SHORT: -7}" | |
| fi | |
| echo "RUN_ID_SHORT=${RUN_ID_SHORT}" >> $GITHUB_OUTPUT | |
| - name: Upload Gopogh report | |
| id: upload_gopogh | |
| uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f | |
| with: | |
| name: functional-${{ matrix.name }}-${{ steps.vars.outputs.PR_OR_MASTER }}-sha-${{ steps.vars.outputs.COMMIT_SHA }}-run-${{ steps.vars.outputs.RUN_ID_SHORT}} | |
| path: ./report | |
| - name: The End Result Summary ${{ matrix.name }} | |
| shell: bash | |
| run: | | |
| summary="$GITHUB_STEP_SUMMARY" | |
| Print_Gopogh_Artifact_Download_URL() { | |
| ARTIFACT_NAME="functional-${{ matrix.name }}-${{ steps.vars.outputs.PR_OR_MASTER }}-sha-${{ steps.vars.outputs.COMMIT_SHA }}" | |
| ARTIFACT_ID='${{ steps.upload_gopogh.outputs.artifact-id }}' | |
| if [ -n "$ARTIFACT_ID" ]; then | |
| URL="https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}/artifacts/$ARTIFACT_ID" | |
| echo "Gopogh report artifact ($ARTIFACT_NAME): $URL" | |
| echo "📥 [Download Gopogh Report]($URL)" >> "$summary" | |
| else | |
| echo "Could not determine artifact ID (action version may not expose it). Find artifact named: $ARTIFACT_NAME" | |
| echo "Report artifact name: $ARTIFACT_NAME" | tee -a "$summary" | |
| fi | |
| } | |
| Print_Gopogh_Artifact_Download_URL | |
| echo "-------------------- RESULT SUMMARY --------------------" | |
| echo "$RESULT_SHORT" | tee -a "$summary" | |
| echo "Time Elapsed: ${TIME_ELAPSED}" | tee -a "$summary" | |
| numFail=$(echo "$STAT" | jq -r '.NumberOfFail // 0') | |
| numPass=$(echo "$STAT" | jq -r '.NumberOfPass // 0') | |
| numSkip=$(echo "$STAT" | jq -r '.NumberOfSkip // 0') | |
| # Print test counts only if they are non-zero | |
| print_test_counts_only() { | |
| if [ -n "${numFail}" ]; then | |
| echo "Failed: ${numFail}" | tee -a "$summary" | |
| fi | |
| if [ -n "${numPass}" ]; then | |
| echo "Passed: ${numPass}" | tee -a "$summary" | |
| fi | |
| if [ -n "${numSkip}" ]; then | |
| echo "Skipped: ${numSkip}" | tee -a "$summary" | |
| fi | |
| } | |
| print_test_counts_only | |
| # Prints lits of test names grouped by result status | |
| print_test_names_by_status() { | |
| local count="$1" header="$2" sym="$3" field="$4" to_summary="$5" | |
| (( count > 0 )) || return 0 | |
| local line="------------------------ ${count} ${header} ------------------------" | |
| if [ "$to_summary" = "yes" ]; then | |
| echo "$line" | tee -a "$summary" | |
| jq -r ".${field}[]? | \" ${sym} \(.)\"" <<<"$STAT" | tee -a "$summary" | |
| else | |
| echo "$line" | |
| jq -r ".${field}[]? | \" ${sym} \(.)\"" <<<"$STAT" | |
| fi | |
| } | |
| print_test_names_by_status "${numFail:-0}" "Failed" "✗" "FailedTests" yes | |
| print_test_names_by_status "${numPass:-0}" "Passed" "✓" "PassedTests" no | |
| print_test_names_by_status "${numSkip:-0}" "Skipped" "•" "SkippedTests" yes | |
| echo $summary >> $GITHUB_STEP_SUMMARY | |
| decide_exit_code() { | |
| # Allow overriding minimum expected passes for when some tests pass and others are timed out | |
| local min_pass="${MIN_PASS_THRESHOLD:-45}" | |
| local timeout_pattern="Test Timed out" | |
| echo "---------------------------------------------------------" | |
| # Timeout detection | |
| if echo "$RESULT_SHORT" | grep -iq "$timeout_pattern"; then | |
| echo "*** Detected test timeout ${TIME_ELAPSED} ⌛: '$timeout_pattern' ***" | |
| exit 3 | |
| fi | |
| # Any failures | |
| if [ "${numFail:-0}" -gt 0 ]; then | |
| echo "*** ${numFail} test(s) failed ***" | |
| exit 2 | |
| fi | |
| # Zero passes (likely setup issue) | |
| if [ "${numPass:-0}" -eq 0 ]; then | |
| echo "*** No tests passed ***" | |
| exit 4 | |
| fi | |
| # Insufficient passes safeguard | |
| if [ "${numPass:-0}" -lt "$min_pass" ]; then | |
| echo "*** Only ${numPass} passed (< required ${min_pass}) ***" | tee -a "$summary" | |
| exit 5 | |
| fi | |
| echo "Exit criteria satisfied: ${numPass} passed, ${numFail} failed, ${numSkip} skipped." | |
| } | |
| decide_exit_code |