Cloud E2E API Test on Env:dev openapi-test|adminapi-test Ref:main #192
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
| name: Cloud E2E API | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| TEST_TYPE: | |
| description: "The type of API will be tested (e.g. openapi-test|adminapi-test)" | |
| type: string | |
| required: false | |
| default: 'openapi-test|adminapi-test' | |
| CLOUD_ENV_NAME: | |
| description: "The cloud env name of test (e.g. dev) " | |
| type: string | |
| required: false | |
| default: 'dev' | |
| CLOUD_BRANCH: | |
| description: "The cloud branch name (e.g. main) " | |
| type: string | |
| required: false | |
| default: 'main' | |
| APECD_REF: | |
| description: "The branch name of apecloud-cd" | |
| type: string | |
| required: false | |
| default: 'main' | |
| CURRENT_VERSION: | |
| description: "The current release version (e.g. v0.30) " | |
| type: string | |
| required: false | |
| default: '' | |
| workflow_call: | |
| inputs: | |
| TEST_TYPE: | |
| description: "The type of API will be tested (e.g. openapi-test|adminapi-test)" | |
| type: string | |
| required: false | |
| default: 'openapi-test|adminapi-test' | |
| CLOUD_ENV_NAME: | |
| description: "The cloud env name of test (e.g. dev) " | |
| type: string | |
| required: false | |
| default: 'dev' | |
| CLOUD_BRANCH: | |
| description: "The cloud branch name (e.g. main) " | |
| type: string | |
| required: false | |
| default: 'main' | |
| APECD_REF: | |
| description: "The branch name of apecloud-cd" | |
| type: string | |
| required: false | |
| default: 'main' | |
| CURRENT_VERSION: | |
| description: "The current release version (e.g. v0.30) " | |
| type: string | |
| required: false | |
| default: '' | |
| run-name: Cloud E2E API Test on Env:${{ inputs.CLOUD_ENV_NAME }} ${{ inputs.TEST_TYPE }} Ref:${{ inputs.CLOUD_BRANCH }} | |
| env: | |
| ACK_KUBECONFIG_DEV: ${{ secrets.ACK_KUBECONFIG_DEV }} | |
| ACK_KUBECONFIG_DEMO: ${{ secrets.ACK_KUBECONFIG_DEMO }} | |
| IDC_KUBECONFIG: ${{ secrets.IDC_KUBECONFIG }} | |
| IDC_KUBECONFIG_1: ${{ secrets.IDC_KUBECONFIG_1 }} | |
| IDC_KUBECONFIG_2: ${{ secrets.IDC_KUBECONFIG_2 }} | |
| IDC_KUBECONFIG_4: ${{ secrets.IDC_KUBECONFIG_4 }} | |
| ACK_KUBECONFIG_PROD: ${{ secrets.ACK_KUBECONFIG_PROD }} | |
| ACK_KUBECONFIG_INTL_PROD: ${{ secrets.ACK_KUBECONFIG_INTL_PROD }} | |
| GH_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }} | |
| AZURE_CLIENT_SECRET: ${{ secrets.AZURE_CLIENT_SECRET }} | |
| AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }} | |
| AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }} | |
| AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }} | |
| jobs: | |
| get-test-type: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| test-type: ${{ steps.get_test_type.outputs.test-type }} | |
| cloud-branch: ${{ steps.get_test_type.outputs.cloud-branch }} | |
| cloud-env-name: ${{ steps.get_test_type.outputs.cloud-env-name }} | |
| steps: | |
| - name: Get test type | |
| id: get_test_type | |
| run: | | |
| TEST_TYPES="${{ inputs.TEST_TYPE }}" | |
| test_type="" | |
| for test_type_tmp in $(echo "${TEST_TYPES}" | sed 's/|/ /g' ); do | |
| if [[ -z "${test_type}" ]]; then | |
| test_type="{\"test-type\":\"${test_type_tmp}\"}" | |
| else | |
| test_type="${test_type},{\"test-type\":\"${test_type_tmp}\"}" | |
| fi | |
| done | |
| echo "${test_type}" | |
| echo "test-type={\"include\":[${test_type}]}" >> $GITHUB_OUTPUT | |
| CLOUD_BRANCH="${{ inputs.CLOUD_BRANCH }}" | |
| if [[ -z "$CLOUD_BRANCH" ]]; then | |
| CLOUD_BRANCH="main" | |
| fi | |
| echo cloud-branch="$CLOUD_BRANCH" >> $GITHUB_OUTPUT | |
| CLOUD_ENV_NAME="${{ inputs.CLOUD_ENV_NAME }}" | |
| if [[ -z "$CLOUD_ENV_NAME" ]]; then | |
| CLOUD_ENV_NAME="dev" | |
| fi | |
| echo cloud-env-name="$CLOUD_ENV_NAME" >> $GITHUB_OUTPUT | |
| e2e-api-test: | |
| needs: [ get-test-type ] | |
| name: ${{ matrix.test-type }} | |
| strategy: | |
| fail-fast: false | |
| matrix: ${{ fromJSON(needs.get-test-type.outputs.test-type) }} | |
| outputs: | |
| openapi-test-result: ${{ steps.get_test_result.outputs.openapi-test-result }} | |
| adminapi-test-result: ${{ steps.get_test_result.outputs.adminapi-test-result }} | |
| test-result: ${{ steps.get_test_result.outputs.test-result }} | |
| openapi-summary: ${{ steps.get_test_result.outputs.openapi-summary }} | |
| adminapi-summary: ${{ steps.get_test_result.outputs.adminapi-summary }} | |
| api-summary: ${{ steps.get_test_result.outputs.api-summary }} | |
| test-date: ${{ steps.upload_test_result.outputs.test-date }} | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout testinfra Code | |
| uses: actions/checkout@v4 | |
| with: | |
| repository: apecloud/testinfra | |
| path: ./ | |
| token: ${{ env.GH_TOKEN }} | |
| - name: Checkout apecloud-cd Code | |
| uses: actions/checkout@v4 | |
| with: | |
| repository: apecloud/apecloud-cd | |
| path: ./apecloud-cd | |
| ref: ${{ inputs.APECD_REF }} | |
| - name: Checkout apecloud Code | |
| uses: actions/checkout@v4 | |
| with: | |
| repository: apecloud/apecloud | |
| path: ./apecloud | |
| token: ${{ env.GH_TOKEN }} | |
| ref: "${{ needs.get-test-type.outputs.cloud-branch }}" | |
| fetch-depth: 0 | |
| - name: Configure ACK Context ${{ inputs.CLOUD_ENV_NAME }} | |
| id: cloud_env | |
| run: | | |
| mkdir -p $HOME/.kube | |
| touch $HOME/.kube/config | |
| CLOUD_ENV_NAME="${{ inputs.CLOUD_ENV_NAME }}" | |
| if [[ -z "$CLOUD_ENV_NAME" ]]; then | |
| CLOUD_ENV_NAME="dev" | |
| fi | |
| echo CLOUD_ENV_NAME="$CLOUD_ENV_NAME" >> $GITHUB_ENV | |
| E2E_ENV_VARS="" | |
| case "$CLOUD_ENV_NAME" in | |
| dev) | |
| echo '${{ env.ACK_KUBECONFIG_DEV }}' > $HOME/.kube/config | |
| E2E_ENV_VARS="${{ vars.E2E_ENV_VARS_DEV }}" | |
| ;; | |
| demo) | |
| echo '${{ env.ACK_KUBECONFIG_DEMO }}' > $HOME/.kube/config | |
| E2E_ENV_VARS="${{ vars.E2E_ENV_VARS_DEMO }}" | |
| ;; | |
| idc) | |
| echo '${{ env.IDC_KUBECONFIG }}' > $HOME/.kube/config | |
| E2E_ENV_VARS="${{ vars.E2E_ENV_VARS_IDC }}" | |
| ;; | |
| idc1) | |
| echo '${{ env.IDC_KUBECONFIG_1 }}' > $HOME/.kube/config | |
| E2E_ENV_VARS="${{ vars.E2E_ENV_VARS_IDC1 }}" | |
| ;; | |
| idc2) | |
| echo '${{ env.IDC_KUBECONFIG_2 }}' > $HOME/.kube/config | |
| E2E_ENV_VARS="${{ vars.E2E_ENV_VARS_IDC2 }}" | |
| ;; | |
| idc4) | |
| echo '${{ env.IDC_KUBECONFIG_4 }}' > $HOME/.kube/config | |
| E2E_ENV_VARS="${{ vars.E2E_ENV_VARS_IDC4 }}" | |
| ;; | |
| prod) | |
| echo '${{ env.ACK_KUBECONFIG_PROD }}' > $HOME/.kube/config | |
| E2E_ENV_VARS="${{ vars.E2E_ENV_VARS_PROD }}" | |
| ;; | |
| intl_prod) | |
| echo '${{ env.ACK_KUBECONFIG_INTL_PROD }}' > $HOME/.kube/config | |
| E2E_ENV_VARS="${{ vars.E2E_ENV_VARS_INTL_PROD }}" | |
| ;; | |
| esac | |
| echo E2E_ENV_VARS="$E2E_ENV_VARS" >> $GITHUB_ENV | |
| - name: install python dateutil | |
| run: | | |
| pip3 install python-dateutil | |
| - name: run ${{ matrix.test-type }} | |
| run: | | |
| run_file_log="run_e2e_test_result.log" | |
| touch ${run_file_log} | |
| for env_vars in $(echo "${E2E_ENV_VARS}" | sed 's/|/ /g'); do | |
| eval_cmd="export $env_vars" | |
| echo "$eval_cmd" | |
| eval "$eval_cmd" | |
| done | |
| export KB_CLOUD_TEST_ENGINES="${{ vars.KB_CLOUD_TEST_ENGINES }}" | |
| TEST_TYPE="${{ matrix.test-type }}" | |
| if [[ -z "$TEST_TYPE" ]]; then | |
| TEST_TYPE="openapi-test" | |
| fi | |
| # run cloud e2e test | |
| bash test/cloud/test_cloud_e2e.sh \ | |
| --test-type "${TEST_TYPE}" \ | |
| --release-version "${{ needs.get-test-type.outputs.cloud-branch }}" | tee -a ${run_file_log} | |
| CLOUD_E2E_TEST_POD_NAME="$(cat ${run_file_log} | grep '\[CLOUD-E2E-TEST-POD-NAME\]' || true )" | |
| if [[ -n "${CLOUD_E2E_TEST_POD_NAME}" && "$CLOUD_E2E_TEST_POD_NAME" == "[CLOUD-E2E-TEST-POD-NAME]"* ]]; then | |
| CLOUD_E2E_TEST_POD_NAME=${CLOUD_E2E_TEST_POD_NAME#*"[CLOUD-E2E-TEST-POD-NAME]"} | |
| fi | |
| echo CLOUD_E2E_TEST_POD_NAME="$CLOUD_E2E_TEST_POD_NAME" >> $GITHUB_ENV | |
| - name: Waiting for Cloud E2E to be Completed | |
| run: | | |
| sleep 10 | |
| while true; do | |
| if kubectl get pods -n default | grep "${CLOUD_E2E_TEST_POD_NAME}" | egrep "Completed|Error" ; then | |
| echo "Cloud E2E Test is Done" | |
| break | |
| fi | |
| if kubectl get pods -n default | grep "${CLOUD_E2E_TEST_POD_NAME}" | egrep "Running|Error" ; then | |
| kubectl logs -n default ${CLOUD_E2E_TEST_POD_NAME} --tail=5 | |
| else | |
| echo "Waiting for Cloud E2E to be Running..." | |
| fi | |
| sleep 1 | |
| done | |
| - name: Get Test Result | |
| if: ${{ always() }} | |
| id: get_test_result | |
| run: | | |
| file_log="test_result.log" | |
| test_file_log_path="${{ github.workspace }}/${file_log}" | |
| touch ${test_file_log_path} | |
| kubectl logs -n default ${CLOUD_E2E_TEST_POD_NAME} > ${test_file_log_path} | |
| kubectl delete pod -n default ${CLOUD_E2E_TEST_POD_NAME} --force | |
| cat ${test_file_log_path} | |
| TEST_TYPE="${{ matrix.test-type }}" | |
| if [[ -z "$TEST_TYPE" ]]; then | |
| TEST_TYPE="openapi-test" | |
| fi | |
| test_ret="$( grep "Test Suite Failed" ${test_file_log_path} || true )" | |
| TEST_RESULT_ALL="$(cat ${test_file_log_path} | (egrep 'SUCCESS!|FAIL!' | grep -- '--' || true))" | |
| echo "test result all:${TEST_RESULT_ALL}" | |
| TEST_RESULT_ALL=$(python3 ${{ github.workspace }}/apecloud-cd/.github/utils/remove_ansi.py --ansi-str "$TEST_RESULT_ALL") | |
| test_result=$(bash ${{ github.workspace }}/apecloud-cd/.github/utils/utils.sh --type 41 --test-result "${TEST_RESULT_ALL}") | |
| echo "test result total:${test_result}" | |
| if [[ -z "$test_result" ]]; then | |
| test_result="$(cat ${test_file_log_path} | (egrep 'SUCCESS!|FAIL!' | grep -- '--' || true) | tail -n 1)" | |
| test_result=$(python3 ${{ github.workspace }}/apecloud-cd/.github/utils/remove_ansi.py --ansi-str "$test_result") | |
| fi | |
| if [[ -z "$test_result" ]]; then | |
| test_result="[PASSED]" | |
| if [[ -n "$test_ret" || -z "${TEST_RESULT_ALL}" ]]; then | |
| test_result="[FAILED]" | |
| fi | |
| fi | |
| coverage_file_log="test_api_coverage_result.log" | |
| coverage_file_log_path="${{ github.workspace }}/${coverage_file_log}" | |
| touch ${coverage_file_log_path} | |
| API_COVERAGE_SUMMARY="" | |
| CLOUD_E2E_HACK_DIR="${{ github.workspace }}/apecloud/e2e/hack" | |
| if [[ -d "${CLOUD_E2E_HACK_DIR}" && "${{ needs.get-test-type.outputs.cloud-branch }}" == "main" ]]; then | |
| cd ${CLOUD_E2E_HACK_DIR} | |
| if [[ -f "${CLOUD_E2E_HACK_DIR}/api-coverage.sh" ]]; then | |
| # api coverage summary | |
| API_TYPE="openapi" | |
| if [[ -n "$TEST_TYPE" && "$TEST_TYPE" == "adminapi"* ]]; then | |
| API_TYPE="adminapi" | |
| fi | |
| bash ./api-coverage.sh --type ${API_TYPE} --log ${test_file_log_path} > ${coverage_file_log_path} | |
| API_COVERAGE_SUMMARY=$(cat ${coverage_file_log_path}) | |
| TOTAL_APIS=$(echo "${API_COVERAGE_SUMMARY}" | grep "Total APIs: ") | |
| COVERED_APIS=$(echo "${API_COVERAGE_SUMMARY}" | grep "Covered APIs: ") | |
| COVERAGE=$(echo "${API_COVERAGE_SUMMARY}" | grep "Coverage: ") | |
| DEPRECATED_APIS=$(echo "${API_COVERAGE_SUMMARY}" | grep "Deprecated APIs: ") | |
| TOTAL_APIS=$(echo "$TOTAL_APIS" | grep -oE '[0-9]+') | |
| COVERED_APIS=$(echo "$COVERED_APIS" | grep -oE '[0-9]+') | |
| COVERAGE=$(echo "$COVERAGE" | grep -oE '[0-9]+%') | |
| DEPRECATED_APIS=$(echo "$DEPRECATED_APIS" | grep -oE '[0-9]+') | |
| echo "Total APIs: $TOTAL_APIS" | |
| echo "Covered APIs: $COVERED_APIS" | |
| echo "Coverage: $COVERAGE" | |
| echo "Deprecated APIs: $DEPRECATED_APIS" | |
| API_COVERAGE_SUMMARY="${TOTAL_APIS}|${COVERED_APIS}|${COVERAGE}|${DEPRECATED_APIS}" | |
| fi | |
| fi | |
| case "$TEST_TYPE" in | |
| openapi-test) | |
| echo openapi-test-result="${test_result}" >> $GITHUB_OUTPUT | |
| echo openapi-summary="${API_COVERAGE_SUMMARY}" >> $GITHUB_OUTPUT | |
| if [[ -d "${CLOUD_E2E_HACK_DIR}" ]]; then | |
| file_log_tmp="test_result_tmp.log" | |
| test_file_log_tmp_path="${{ github.workspace }}/${file_log_tmp}" | |
| check_e2e_log="e2e.log" | |
| check_e2e_log_path="${CLOUD_E2E_HACK_DIR}/${check_e2e_log}" | |
| touch ${test_file_log_tmp_path} ${check_e2e_log_path} | |
| E2E_TEST_RESULT_LOG=$(python3 ${{ github.workspace }}/apecloud-cd/.github/utils/remove_ansi_file.py ${test_file_log_path}) | |
| echo "${E2E_TEST_RESULT_LOG}" > ${test_file_log_tmp_path} | |
| cp -r ${test_file_log_tmp_path} ${check_e2e_log_path} | |
| fi | |
| ;; | |
| adminapi-test) | |
| echo adminapi-test-result="${test_result}" >> $GITHUB_OUTPUT | |
| echo adminapi-summary="${API_COVERAGE_SUMMARY}" >> $GITHUB_OUTPUT | |
| ;; | |
| *) | |
| echo test-result="${test_result}" >> $GITHUB_OUTPUT | |
| echo api-summary="${API_COVERAGE_SUMMARY}" >> $GITHUB_OUTPUT | |
| ;; | |
| esac | |
| if [[ -n "$test_ret" ]]; then | |
| exit 1 | |
| fi | |
| - name: Get ${{ matrix.test-type }} API Coverage List | |
| if: ${{ always() }} | |
| run: | | |
| coverage_file_log="test_api_coverage_result.log" | |
| coverage_file_log_path="${{ github.workspace }}/${coverage_file_log}" | |
| if [[ -f ${coverage_file_log_path} ]]; then | |
| cat ${coverage_file_log_path} | |
| fi | |
| - name: Check e2e log and create issue | |
| if: ${{ always() && matrix.test-type == 'openapi-test' }} | |
| run: | | |
| CLOUD_E2E_HACK_DIR="${{ github.workspace }}/apecloud/e2e/hack" | |
| if [[ -d "${CLOUD_E2E_HACK_DIR}" && -f "${CLOUD_E2E_HACK_DIR}/log-checker.sh" ]]; then | |
| CI_JOB_URL=$(bash ${{ github.workspace }}/apecloud-cd/.github/utils/utils.sh \ | |
| --type 44 \ | |
| --github-repo "${{ github.repository }}" \ | |
| --github-token "${{ env.GH_TOKEN }}" \ | |
| --run-id "$GITHUB_RUN_ID" \ | |
| --test-result "openapi-test-dev") | |
| echo ${CI_JOB_URL} | |
| export CI_JOB_URL="${CI_JOB_URL}" | |
| cd ${CLOUD_E2E_HACK_DIR} | |
| check_e2e_log="e2e.log" | |
| check_e2e_log_path="${CLOUD_E2E_HACK_DIR}/${check_e2e_log}" | |
| bash ./log-checker.sh | |
| fi | |
| send-message: | |
| needs: [ get-test-type, e2e-api-test ] | |
| runs-on: ubuntu-latest | |
| if: ${{ always() }} | |
| steps: | |
| - name: Checkout apecloud-cd Code | |
| uses: actions/checkout@v4 | |
| with: | |
| repository: apecloud/apecloud-cd | |
| ref: ${{ inputs.APECD_REF }} | |
| - name: send test result message | |
| run: | | |
| CLOUD_BRANCH="${{ needs.get-test-type.outputs.cloud-branch }}" | |
| CLOUD_ENV_NAME="${{ needs.get-test-type.outputs.cloud-env-name }}" | |
| TEST_RESULT="" | |
| API_COVERAGE_SUMMARY="" | |
| TEST_TYPES="${{ inputs.TEST_TYPE }}" | |
| for test_type_tmp in $(echo "${TEST_TYPES}" | sed 's/|/ /g' ); do | |
| case "$test_type_tmp" in | |
| openapi-test) | |
| TEST_RESULT="${TEST_RESULT}##${test_type_tmp}|${{ needs.e2e-api-test.outputs.openapi-test-result }}" | |
| if [[ -n "${{ needs.e2e-api-test.outputs.openapi-summary }}" ]]; then | |
| API_COVERAGE_SUMMARY="${API_COVERAGE_SUMMARY}##openapi|${{ needs.e2e-api-test.outputs.openapi-summary }}" | |
| fi | |
| ;; | |
| adminapi-test) | |
| TEST_RESULT="${TEST_RESULT}##${test_type_tmp}|${{ needs.e2e-api-test.outputs.adminapi-test-result }}" | |
| if [[ -n "${{ needs.e2e-api-test.outputs.adminapi-summary }}" ]]; then | |
| API_COVERAGE_SUMMARY="${API_COVERAGE_SUMMARY}##adminapi|${{ needs.e2e-api-test.outputs.adminapi-summary }}" | |
| fi | |
| ;; | |
| *) | |
| TEST_RESULT="${TEST_RESULT}##${test_type_tmp}|${{ needs.e2e-api-test.outputs.test-result }}" | |
| if [[ -n "${{ needs.e2e-api-test.outputs.api-summary }}" ]]; then | |
| API_COVERAGE_SUMMARY="${API_COVERAGE_SUMMARY}##api|${{ needs.e2e-api-test.outputs.api-summary }}" | |
| fi | |
| ;; | |
| esac | |
| done | |
| echo "TEST_RESULT:${TEST_RESULT}" | |
| TEST_RESULT=$( bash .github/utils/utils.sh --type 40 \ | |
| --github-repo "${{ github.repository }}" \ | |
| --github-token "${{ env.GH_TOKEN }}" \ | |
| --test-result "${TEST_RESULT}" \ | |
| --run-id "$GITHUB_RUN_ID" ) | |
| echo "TEST_RESULT:${TEST_RESULT}" | |
| export TZ='Asia/Shanghai' | |
| date_ret=$(date +%Y-%m-%d-%T) | |
| TEST_TITLE="[${CLOUD_BRANCH}][${CLOUD_ENV_NAME}] Cloud E2E API Test [${date_ret}]" | |
| python3 .github/utils/send_mesage.py \ | |
| --send-type ginkgo \ | |
| --url "${{ vars.CLOUD_E2E_BOT_WEBHOOK }}" \ | |
| --title "$TEST_TITLE" \ | |
| --result "$TEST_RESULT" | |
| TEST_TITLE_SUMMARY="[${CLOUD_BRANCH}][${CLOUD_ENV_NAME}] Cloud E2E API Coverage Summary [${date_ret}]" | |
| if [[ -n "${API_COVERAGE_SUMMARY}" && "${{ needs.get-test-type.outputs.cloud-branch }}" == "main" ]]; then | |
| echo "API_COVERAGE_SUMMARY:${API_COVERAGE_SUMMARY}" | |
| API_COVERAGE_SUMMARY_TMP="$(bash .github/utils/utils.sh \ | |
| --type 42 \ | |
| --test-result "${TEST_RESULT}" \ | |
| --coverage-result "${API_COVERAGE_SUMMARY}")" | |
| echo "API_COVERAGE_SUMMARY:${API_COVERAGE_SUMMARY_TMP}" | |
| python3 .github/utils/send_mesage.py \ | |
| --send-type summary \ | |
| --url "${{ vars.CLOUD_E2E_BOT_WEBHOOK }}" \ | |
| --title "$TEST_TITLE_SUMMARY" \ | |
| --result "$API_COVERAGE_SUMMARY_TMP" | |
| fi |