|
| 1 | +name: Browser Tests |
| 2 | +description: Runs browser tests on-device. |
| 3 | +inputs: |
| 4 | + gcs_results_path: |
| 5 | + description: "GCS path for the test results." |
| 6 | + required: true |
| 7 | + test_results_key: |
| 8 | + description: "Artifact key used to store test results." |
| 9 | + required: true |
| 10 | + test_dimensions: |
| 11 | + description: "Test dimensions JSON string." |
| 12 | + required: true |
| 13 | + test_device_family: |
| 14 | + description: "Test device family." |
| 15 | + required: true |
| 16 | + test_attempts: |
| 17 | + description: "Number of attempts for the tests." |
| 18 | + default: "" |
| 19 | + docker_tag: |
| 20 | + description: "Docker image tag to be used by the test lab." |
| 21 | + required: true |
| 22 | + |
| 23 | +runs: |
| 24 | + using: "composite" |
| 25 | + steps: |
| 26 | + - name: Install Requirements |
| 27 | + run: | |
| 28 | + pip3 install --require-hashes --no-deps -r ${GITHUB_WORKSPACE}/cobalt/tools/requirements.txt |
| 29 | + shell: bash |
| 30 | + - name: Generate gRPC files |
| 31 | + run: | |
| 32 | + python -m grpc_tools.protoc -I${GITHUB_WORKSPACE}/cobalt/tools/ |
| 33 | + --python_out=${GITHUB_WORKSPACE}/cobalt/tools/ |
| 34 | + --grpc_python_out=${GITHUB_WORKSPACE}/cobalt/tools/ |
| 35 | + ${GITHUB_WORKSPACE}/cobalt/tools/on_device_tests_gateway.proto |
| 36 | + shell: bash |
| 37 | + - name: Set Up Cloud SDK |
| 38 | + uses: isarkis/setup-gcloud@40dce7857b354839efac498d3632050f568090b6 # v1.1.1 |
| 39 | + - name: Set GCS Project Name |
| 40 | + run: | |
| 41 | + echo "PROJECT_NAME=$(gcloud config get-value project)" >> $GITHUB_ENV |
| 42 | + shell: bash |
| 43 | + - name: Run Browser Tests on ${{ matrix.platform }} Platform |
| 44 | + env: |
| 45 | + GCS_ARTIFACTS_PATH: /bigstore/${{ env.PROJECT_NAME }}-test-artifacts/${{ github.workflow }}/${{ github.run_number }}/${{ matrix.platform }} |
| 46 | + GITHUB_SHA: ${{ github.sha }} |
| 47 | + GITHUB_TOKEN: ${{ github.token }} |
| 48 | + GITHUB_EVENT_NAME: ${{ github.event_name }} |
| 49 | + GITHUB_ACTOR: ${{ github.actor }} |
| 50 | + GITHUB_TRIGGERING_ACTOR: ${{ github.triggering_actor }} |
| 51 | + GITHUB_ACTOR_ID: ${{ github.actor_id }} |
| 52 | + GITHUB_REPO: ${{ github.repository }} |
| 53 | + GITHUB_PR_HEAD_USER_LOGIN: ${{ github.event.pull_request.head.user.login }} |
| 54 | + GITHUB_PR_HEAD_USER_ID: ${{ github.event.pull_request.head.user.id }} |
| 55 | + GITHUB_COMMIT_AUTHOR_USERNAME: ${{ github.event.commits[0].author.username }} |
| 56 | + GITHUB_COMMIT_AUTHOR_EMAIL: ${{ github.event.commits[0].author.email }} |
| 57 | + GITHUB_PR_NUMBER: ${{ github.event.pull_request.number }} |
| 58 | + GITHUB_RUN_NUMBER: ${{ github.run_number }} |
| 59 | + GITHUB_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} |
| 60 | + GITHUB_WORKFLOW: ${{ github.workflow }} |
| 61 | + TEST_ATTEMPTS: ${{ inputs.test_attempts }} |
| 62 | + TEST_TYPE: unit_test |
| 63 | + DEVICE_FAMILY: ${{ inputs.test_device_family }} |
| 64 | + TEST_DIMENSIONS: ${{ inputs.test_dimensions }} |
| 65 | + DOCKER_TAG: ${{ inputs.docker_tag }} |
| 66 | + GCS_RESULTS_PATH: ${{ inputs.gcs_results_path }} |
| 67 | + PLATFORM: ${{ matrix.platform }} |
| 68 | + # Browser test targets are fixed. |
| 69 | + TEST_TARGETS_JSON: '["cobalt/testing/browser_tests:cobalt_browsertests"]' |
| 70 | + run: | |
| 71 | + set -x |
| 72 | +
|
| 73 | + python3 -u cobalt/tools/on_device_tests_gateway_client.py |
| 74 | + --token "${GITHUB_TOKEN}" |
| 75 | + trigger |
| 76 | + --test_type "${TEST_TYPE}" |
| 77 | + --device_family "${DEVICE_FAMILY}" |
| 78 | + --targets "${TEST_TARGETS_JSON}" |
| 79 | + --filter_json_dir "${GITHUB_WORKSPACE}/cobalt/testing/filters/${PLATFORM}" |
| 80 | + --label chrobalt_on_device_browser_test |
| 81 | + --label github_"${GITHUB_PR_NUMBER:-postsubmit}" |
| 82 | + --label builder-"${PLATFORM}" |
| 83 | + --label builder_url-"${GITHUB_RUN_URL}" |
| 84 | + --label "${TEST_TYPE}" |
| 85 | + --label github |
| 86 | + --label "${GITHUB_EVENT_NAME}" |
| 87 | + --label "${GITHUB_WORKFLOW}" |
| 88 | + --label actor-"${GITHUB_ACTOR}" |
| 89 | + --label actor_id-"${GITHUB_ACTOR_ID}" |
| 90 | + --label triggering_actor-"${GITHUB_TRIGGERING_ACTOR}" |
| 91 | + --label sha-"${GITHUB_SHA}" |
| 92 | + --label repository-"${GITHUB_REPO}" |
| 93 | + --label author-"${GITHUB_PR_HEAD_USER_LOGIN:-$GITHUB_COMMIT_AUTHOR_USERNAME}" |
| 94 | + --label author_id-"${GITHUB_PR_HEAD_USER_ID:-$GITHUB_COMMIT_AUTHOR_EMAIL}" |
| 95 | + --label branch:"${GITHUB_REF_NAME}" |
| 96 | + --dimensions "${TEST_DIMENSIONS}" |
| 97 | + ${TEST_ATTEMPTS:+"--test_attempts" "$TEST_ATTEMPTS"} |
| 98 | + ${DOCKER_TAG:+"--docker_tag" "$DOCKER_TAG"} |
| 99 | + --gcs_archive_path "${GCS_ARTIFACTS_PATH}" |
| 100 | + --gcs_result_path "${GCS_RESULTS_PATH}" || { |
| 101 | + echo "Finished running tests..." |
| 102 | + echo "The test session failed. See logs for details." |
| 103 | + # Fail the job so it's easy to retrigger. |
| 104 | + exit 1 |
| 105 | + } |
| 106 | + echo "Finished running tests..." |
| 107 | + shell: bash |
| 108 | + - name: Download ${{ matrix.platform }} Test Results from GCS |
| 109 | + if: always() |
| 110 | + run: | |
| 111 | + set -uxe |
| 112 | + shopt -s globstar nullglob |
| 113 | +
|
| 114 | + test_output="${GITHUB_WORKSPACE}/results" |
| 115 | + echo "test_output=${test_output}" >> $GITHUB_ENV |
| 116 | +
|
| 117 | + # Test results (xml and logs) must be in a subfolder in results_dir. |
| 118 | + # to be picked up by the test result processor. |
| 119 | + mkdir -p "${test_output}/${{ matrix.platform }}" |
| 120 | + gsutil -q cp -r "${{ inputs.gcs_results_path }}/" "${test_output}/${{ matrix.platform }}" |
| 121 | +
|
| 122 | + # Check for missing result xml files. |
| 123 | + test_target="cobalt_browsertests" |
| 124 | + xml_files=("${test_output}"/${{ matrix.platform }}/**/"${test_target}"_testoutput.xml) |
| 125 | + if [[ "${#xml_files[@]}" -eq 0 ]]; then |
| 126 | + # No matching XML results found. Check if the test target is filtered. |
| 127 | + test_filter_file="${GITHUB_WORKSPACE}/cobalt/testing/filters/${{ matrix.platform }}/${test_target}_filter.json" |
| 128 | + if [ ! -f "${test_filter_file}" ] || [ "$(jq -cr '.failing_tests[0]' "${test_filter_file}")" != '*' ]; then |
| 129 | + echo "Test result xml is missing for ${test_target}." |
| 130 | +
|
| 131 | + # Try to find the crashed test in the log and create a fake junit xml for it. |
| 132 | + log_path=("${test_output}"/${{ matrix.platform }}/**/"${test_target}"_log.txt) |
| 133 | + xml_path=("${test_output}"/${{ matrix.platform }}/1/"${test_target}"_testoutput.xml) |
| 134 | + python3 ${GITHUB_WORKSPACE}/.github/scripts/generate_crash_report.py "${log_path}" "${xml_path}" |
| 135 | + exit 1 |
| 136 | + fi |
| 137 | + elif grep -e '<failure' -e '<error' ${xml_files}; then |
| 138 | + # Double-check the result XML for failures. ODT service has been known to report incorrect status. |
| 139 | + echo "::error::Found failures in the test xml." |
| 140 | + exit 1 |
| 141 | + fi |
| 142 | + shell: bash |
| 143 | + - name: Archive Test Results |
| 144 | + uses: actions/upload-artifact@v4 |
| 145 | + if: always() |
| 146 | + with: |
| 147 | + name: ${{ inputs.test_results_key }} |
| 148 | + path: ${{ env.test_output }}/* |
0 commit comments