Skip to content

Commit af75fb8

Browse files
committed
Refactor browser test execution to use specialized actions and configuration-driven inclusion.
1 parent 9ccbd5e commit af75fb8

22 files changed

+316
-52
lines changed
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
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 }}/*

.github/actions/build/action.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@ runs:
7171
# TODO: b/382508397 - Currently, override with static test targets
7272
cp -av "${STATIC_TEST_TARGETS_JSON_FILE}" "${{ inputs.test_targets_json_file }}"
7373
74+
# Filter out cobalt_browsertests from the test targets as they are handled by a dedicated job.
75+
filtered_json=$(jq -cr '.test_targets |= [.[] | select(endswith(":cobalt_browsertests") or . == "cobalt_browsertests" | not)]' "${{ inputs.test_targets_json_file }}")
76+
echo "${filtered_json}" > "${{ inputs.test_targets_json_file }}"
77+
7478
# gn desc out/${{ matrix.platform }}_${{ matrix.config }}/ "*" --format=json > gn_desc.json
7579
# # Trim any warning gn printed before the json (all lines above the first curly brace).
7680
# sed -n '/^{/,$p' -i gn_desc.json
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
name: Browser Test Docker Image Build
2+
description: Builds and pushes specialized Docker image for Cobalt browser tests.
3+
inputs:
4+
github_token:
5+
description: "The github token."
6+
required: true
7+
docker_content_sha:
8+
description: "The git hash for the latest docker related changes."
9+
required: true
10+
is_pr:
11+
description: "True if the event is a pull request."
12+
required: true
13+
platform:
14+
description: "The platform for which tests are being run."
15+
required: true
16+
config:
17+
description: "The build configuration (e.g., devel)."
18+
required: true
19+
workflow:
20+
description: "The workflow name."
21+
required: true
22+
23+
outputs:
24+
docker_tag:
25+
description: "The full docker image tag."
26+
value: ${{ steps.build-and-push.outputs.docker_tag }}
27+
28+
runs:
29+
using: "composite"
30+
steps:
31+
- name: Set up Cloud SDK
32+
uses: isarkis/setup-gcloud@40dce7857b354839efac498d3632050f568090b6 # v1.1.1
33+
34+
- name: Set Docker Build Vars
35+
shell: bash
36+
run: |
37+
# Set floating to either the PR number (for PRs) or the branch name (for post-submit).
38+
FLOATING_TAG="${{ inputs.is_pr == 'true' && github.event.pull_request.number || github.ref_name }}"
39+
FLOATING_TAG="${FLOATING_TAG//\//__}"
40+
FLOATING_TAG="${FLOATING_TAG%.1[+,-]}"
41+
echo "DOCKER_FLOATING_TAG=${FLOATING_TAG}" >> $GITHUB_ENV
42+
43+
REGISTRY_REGION="us-west1"
44+
REGISTRY_PROJECT="ytlr-image-hosting"
45+
REGISTRY_REPOSITORY="integration-test-images"
46+
DOCKER_IMAGE_NAME="avvall-service-test"
47+
# For now, keeping the tag as in the previous implementation for compatibility
48+
# though we could transition to DOCKER_CONTENT_SHA based tagging.
49+
IMAGE_BASE="${REGISTRY_REGION}-docker.pkg.dev/${REGISTRY_PROJECT}/${REGISTRY_REPOSITORY}/${DOCKER_IMAGE_NAME}"
50+
echo "IMAGE_BASE=${IMAGE_BASE}" >> $GITHUB_ENV
51+
echo "REGISTRY_URL=https://${REGISTRY_REGION}-docker.pkg.dev" >> $GITHUB_ENV
52+
53+
- name: Login to GAR
54+
shell: bash
55+
run: |
56+
TOKEN_ENDPOINT="http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token"
57+
curl -s -H 'Metadata-Flavor: Google' ${TOKEN_ENDPOINT} | jq -r .access_token | docker login -u oauth2accesstoken --password-stdin "${REGISTRY_URL}"
58+
59+
- name: Prepare Build Context
60+
shell: bash
61+
env:
62+
PLATFORM: ${{ inputs.platform }}
63+
WORKFLOW: ${{ inputs.workflow }}
64+
run: |
65+
set -eux
66+
mkdir -p artifacts
67+
PROJECT_NAME=$(gcloud config get-value project)
68+
GCS_PATH="gs://${PROJECT_NAME}-test-artifacts/${WORKFLOW}/${GITHUB_RUN_NUMBER}/${PLATFORM}/"
69+
gsutil -m cp -r "${GCS_PATH}*" artifacts/
70+
cp cobalt/testing/browser_tests/tools/Dockerfile artifacts/
71+
72+
- name: Build and Push Docker Image
73+
id: build-and-push
74+
shell: bash
75+
env:
76+
PLATFORM: ${{ inputs.platform }}
77+
CONFIG: ${{ inputs.config }}
78+
DOCKER_CONTENT_SHA: ${{ inputs.docker_content_sha }}
79+
run: |
80+
set -eux
81+
cd artifacts/
82+
83+
# Use github run id and platform/config for uniqueness in this migration phase
84+
TAG="${{ github.run_id }}-${PLATFORM}-${CONFIG}"
85+
FULL_IMAGE="${IMAGE_BASE}:${TAG}"
86+
87+
docker build -f Dockerfile -t "${FULL_IMAGE}" .
88+
89+
# Also tag with content SHA and floating tag as per project standards
90+
# But we must use the IMAGE_BASE which already contains the full GAR path.
91+
docker tag "${FULL_IMAGE}" "${IMAGE_BASE}:${DOCKER_CONTENT_SHA}-${PLATFORM}-${CONFIG}"
92+
docker tag "${FULL_IMAGE}" "${IMAGE_BASE}:${DOCKER_FLOATING_TAG}-${PLATFORM}-${CONFIG}"
93+
94+
docker push --all-tags "${IMAGE_BASE}"
95+
96+
echo "docker_tag=${FULL_IMAGE}" >> $GITHUB_OUTPUT

.github/config/android-arm.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
],
66
"test_package": true,
77
"test_on_device": true,
8+
"use_browser_test": true,
89
"test_device_family": "android",
910
"test_e2e": true,
1011
"test_yts": false,

.github/config/android-arm64.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
],
66
"test_package": true,
77
"test_on_device": true,
8+
"use_browser_test": true,
89
"test_device_family": "android",
910
"test_e2e": true,
1011
"test_yts": false,

.github/config/android-x86.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,5 @@
1212
"platform": "android-x86"
1313
}
1414
]
15+
,"use_browser_test": false
1516
}

.github/config/chromium_android-arm.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,5 @@
1414
"platform": "chromium_android-arm"
1515
}
1616
]
17+
,"use_browser_test": false
1718
}

.github/config/chromium_android-arm64.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,5 @@
1414
"platform": "chromium_android-arm64"
1515
}
1616
]
17+
,"use_browser_test": false
1718
}

.github/config/chromium_android-x86.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,5 @@
1414
"platform": "chromium_android-x86"
1515
}
1616
]
17+
,"use_browser_test": false
1718
}

.github/config/chromium_diffing.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,4 +83,5 @@
8383
"ui/file_manager/image_loader/piex/package-lock.json"
8484
]
8585
}
86+
,"use_browser_test": false
8687
}

0 commit comments

Comments
 (0)