Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add on-device tests #4739

Draft
wants to merge 48 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
c5d48d1
Break out test targets into a separate config
isarkis Dec 14, 2024
ac2684b
Chrobalt on-device test work for Android
isarkis Dec 19, 2024
39eb494
Update params passed to ODT gateway
isarkis Dec 19, 2024
8ff567b
ODT Client code
Libzu Dec 20, 2024
a7dace2
Incremental commit based on review comments
isarkis Dec 23, 2024
c9f93a4
new changes for odt gateway
Libzu Jan 2, 2025
4a1c783
additional changes to odt gateway code
Libzu Jan 2, 2025
9ef1c4c
changing --archive_path in action.yaml
Libzu Jan 3, 2025
f1c937d
Additional changes for odt gateway
Libzu Jan 7, 2025
9287f88
Add additional argument for ODT gateway client
isarkis Jan 7, 2025
924b494
Additional improvements for odt gateway code
Libzu Jan 7, 2025
6b6d877
removing autogenerated files from pr
Libzu Jan 7, 2025
feacfac
moving odt gateway code from tools folder to cobalt/tools
Libzu Jan 7, 2025
3c86d6f
Introduce "test_dimension" key
isarkis Jan 7, 2025
5e5e5f5
Log and XML file processing
isarkis Jan 9, 2025
c8bf953
Update gateway client parameters
isarkis Jan 14, 2025
d7b0696
remove tag
isarkis Jan 14, 2025
0acf2cc
Parameter work
isarkis Jan 14, 2025
14fcb8c
Updated ODT Gateway Client code
Libzu Jan 16, 2025
2f09d39
New Modifications to ODT Gateway code
Libzu Jan 16, 2025
22ba293
Deleting erroneous file
isarkis Jan 16, 2025
6f5a260
Fix build dependency problem
isarkis Jan 16, 2025
fb0dbc7
Testing ODT trigger
isarkis Jan 17, 2025
26b0932
Fix github actions syntax error
isarkis Jan 17, 2025
8e8d116
Fix grpc proto paths
isarkis Jan 17, 2025
d0f748f
Fix command line arguments
isarkis Jan 18, 2025
65772a9
Testing ODT trigger
isarkis Jan 18, 2025
f6fe084
Hardcode runtime deps file
isarkis Jan 20, 2025
06ffb5a
Update deps archive path on device
isarkis Jan 20, 2025
c343979
Fix gsutil copy command
isarkis Jan 20, 2025
a2dc411
Fix test logs archival mechanism
isarkis Jan 20, 2025
1dcef08
Fix test result processing mechanism
isarkis Jan 20, 2025
0757659
Add removed unit tests back
isarkis Jan 20, 2025
488c881
Artifact upload work for ODT
isarkis Jan 21, 2025
cddc68b
Fix artifact upload mechanism
isarkis Jan 22, 2025
3904c9f
Merge branch 'chrobalt-odt-dev' of github.com:youtube/cobalt_sandbox …
oxve Jan 22, 2025
5a5c647
Lint and formatting
oxve Jan 22, 2025
6f20c76
Fix params processing, delete some dead code
oxve Jan 22, 2025
4381381
Remove dead code, minor refactoring
oxve Jan 22, 2025
a455108
Remove last traces of change_id param
oxve Jan 22, 2025
ef6b9ad
Add apk copying to artifact script
oxve Jan 22, 2025
a3ee0d8
Remove loading of gtest target from platform configs
oxve Jan 22, 2025
41375e9
Unify on-host and on-device test steps
oxve Jan 22, 2025
a47df72
Get target list from temp hardcoded json file
oxve Jan 22, 2025
0f07e80
Revert sandbox docker config
oxve Jan 22, 2025
019eb7a
Merge branch 'main' of github.com:youtube/cobalt into odt-integration…
oxve Jan 23, 2025
b2bc541
Fix inconsistent quote lint error
oxve Jan 23, 2025
5e26eca
Add missing backslash in params list
oxve Jan 23, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 92 additions & 4 deletions .github/actions/on_device_tests/action.yaml
Original file line number Diff line number Diff line change
@@ -1,9 +1,97 @@
name: On Host Tests
description: Runs on-host tests.
name: On Device Test
description: Runs on-device tests.
inputs:
gcs_results_path:
description: "GCS path for the test results"
required: true
results_dir:
description: "Path to directory where test results are saved."
required: true
test_results_key:
description: "Artifact key used to store test results."
required: true

runs:
using: "composite"
steps:
- name: Run On-Device Tests
- name: Install Requirements
# TODO (b/388329764) - set up requirements file.
run: |
pip3 install grpcio==1.38.0 grpcio-tools==1.38.0
shell: bash
- name: Generate gRPC files
run: |
python -m grpc_tools.protoc -I${GITHUB_WORKSPACE}/cobalt/tools/ --python_out=${GITHUB_WORKSPACE}/cobalt/tools/ --grpc_python_out=${GITHUB_WORKSPACE}/cobalt/tools/ ${GITHUB_WORKSPACE}/cobalt/tools/on_device_tests_gateway.proto
shell: bash
- name: Set Up Cloud SDK
uses: isarkis/setup-gcloud@40dce7857b354839efac498d3632050f568090b6 # v1.1.1
- name: Set env vars
run: |
echo "PROJECT_NAME=$(gcloud config get-value project)" >> $GITHUB_ENV
# Test results and logs
echo "GCS_RESULTS_PATH=gs://cobalt-unittest-storage/results/${{ matrix.name }}/${{ github.run_id }}" >> $GITHUB_ENV
shell: bash
- name: Run Tests on ${{ matrix.platform }} Platform
env:
# TODO(b/382508397): Replace hardcoded list with dynamically generated one.
TEST_TARGETS_JSON_FILE: cobalt/build/testing/targets/${{ matrix.platform }}/test_targets.json
GCS_ARTIFACTS_PATH: /bigstore/${{ env.PROJECT_NAME }}-test-artifacts/${{ github.workflow }}/${{ github.run_number }}/${{ matrix.platform }}
GCS_RESULTS_PATH: ${{ inputs.gcs_results_path }}
GITHUB_SHA: ${{ github.sha }}
GITHUB_TOKEN: ${{ github.token }}
GITHUB_EVENT_NAME: ${{ github.event_name }}
GITHUB_ACTOR: ${{ github.actor }}
GITHUB_TRIGGERING_ACTOR: ${{ github.triggering_actor }}
GITHUB_ACTOR_ID: ${{ github.actor_id }}
GITHUB_REPO: ${{ github.repository }}
GITHUB_PR_HEAD_USER_LOGIN: ${{ github.event.pull_request.head.user.login }}
GITHUB_PR_HEAD_USER_ID: ${{ github.event.pull_request.head.user.id }}
GITHUB_COMMIT_AUTHOR_USERNAME: ${{ github.event.commits[0].author.username }}
GITHUB_COMMIT_AUTHOR_EMAIL: ${{ github.event.commits[0].author.email }}
GITHUB_PR_NUMBER: ${{ github.event.pull_request.number }}
GITHUB_RUN_NUMBER: ${{ github.run_number }}
GITHUB_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
GITHUB_WORKFLOW: ${{ github.workflow }}
run: |
set -uxe
python3 -u cobalt/tools/on_device_tests_gateway_client.py \
--token ${GITHUB_TOKEN} \
trigger \
--targets $(cat "${{ env.TEST_TARGETS_JSON_FILE }}" | jq -cr '.test_targets | join(",")') \
--filter_json_dir "${GITHUB_WORKSPACE}/cobalt/testing/filters/${{ matrix.platform}}" \
--label github_${GITHUB_PR_NUMBER:-postsubmit} \
--label builder-${{ matrix.platform }} \
--label builder_url-${GITHUB_RUN_URL} \
--label github \
--label ${GITHUB_EVENT_NAME} \
--label ${GITHUB_WORKFLOW} \
--label actor-${GITHUB_ACTOR} \
--label actor_id-${GITHUB_ACTOR_ID} \
--label triggering_actor-${GITHUB_TRIGGERING_ACTOR} \
--label sha-${GITHUB_SHA} \
--label repository-${GITHUB_REPO} \
--label author-${GITHUB_PR_HEAD_USER_LOGIN:-$GITHUB_COMMIT_AUTHOR_USERNAME} \
--label author_id-${GITHUB_PR_HEAD_USER_ID:-$GITHUB_COMMIT_AUTHOR_EMAIL} \
${DIMENSION:+"--dimension" "$DIMENSION"} \
${ON_DEVICE_TEST_ATTEMPTS:+"--test_attempts" "$ON_DEVICE_TEST_ATTEMPTS"} \
--gcs_archive_path "${GCS_ARTIFACTS_PATH}" \
--gcs_result_path "${GCS_RESULTS_PATH}"
shell: bash
- name: Download ${{ matrix.platform }} Test Results
if: always()
env:
GCS_RESULTS_PATH: ${{ inputs.gcs_results_path }}
RESULTS_DIR: ${{ inputs.results_dir }}
run: |
echo "Nothing yet"
set -uxe
TEST_LOGS="${GITHUB_WORKSPACE}/${RESULTS_DIR}/"
mkdir -p "${TEST_LOGS}"
gsutil cp -r "${GCS_RESULTS_PATH}/" "${TEST_LOGS}"
echo "TEST_LOGS=${TEST_LOGS}" >> $GITHUB_ENV
shell: bash
- name: Archive Test Results
uses: actions/upload-artifact@v3
if: always()
with:
name: ${{ inputs.test_results_key }}
path: ${{ env.TEST_LOGS }}/
31 changes: 15 additions & 16 deletions .github/actions/upload_test_artifacts/action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,7 @@ inputs:
runs:
using: "composite"
steps:
- name: Set up Cloud SDK
if: inputs.upload_on_device_test_artifacts == 'true'
uses: isarkis/setup-gcloud@40dce7857b354839efac498d3632050f568090b6 # v1.1.1
- name: Upload Android Test Artifacts to GCS
if: inputs.upload_on_device_test_artifacts == 'true'
env:
WORKFLOW: ${{ github.workflow }}
run: |
set -eux
project_name=$(gcloud config get-value project)
gsutil cp "${GITHUB_WORKSPACE}/src/out/${{ matrix.platform }}_${{ matrix.config }}/**/*.apk" \
"gs://${project_name}-test-artifacts/${WORKFLOW}/${GITHUB_RUN_NUMBER}/${{matrix.platform}}/"
shell: bash

- name: Create On-Host Test Artifacts Archive
if: inputs.upload_on_host_test_artifacts == 'true'
- name: Archive Test Artifacts
run: |
set -x
mkdir ${GITHUB_WORKSPACE}/artifacts
Expand All @@ -49,3 +34,17 @@ runs:
name: ${{ inputs.test_artifacts_key }}
path: artifacts/*
retention-days: 3
- name: Set up Cloud SDK
if: inputs.upload_on_device_test_artifacts == 'true'
uses: isarkis/setup-gcloud@40dce7857b354839efac498d3632050f568090b6 # v1.1.1
- name: Upload Android Test Artifacts to GCS
if: inputs.upload_on_device_test_artifacts == 'true'
env:
WORKFLOW: ${{ github.workflow }}
run: |
set -eux
project_name=$(gcloud config get-value project)

gsutil cp "${GITHUB_WORKSPACE}/artifacts/*" \
"gs://${project_name}-test-artifacts/${WORKFLOW}/${GITHUB_RUN_NUMBER}/${{matrix.platform}}/"
shell: bash
5 changes: 5 additions & 0 deletions .github/config/android-arm.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@
"platforms": [
"android-arm"
],
"test_on_device": true,
"test_dimensions": {
"gtest_device": "sabrina",
"gtest_lab": "maneki"
},
"targets": [
"content_shell",
"system_webview_apk",
Expand Down
10 changes: 0 additions & 10 deletions .github/config/chromium_android-arm.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,6 @@
"chromium_android-arm"
],
"targets": [
"base_unittests",
"sql_unittests",
"net_unittests",
"url_unittests",
"ipc_tests",
"mojo_unittests",
"gpu_unittests",
"gin_unittests",
"blink_unittests",
"media_unittests",
"content_shell",
"system_webview_apk",
"system_webview_shell_apk"
Expand Down
10 changes: 0 additions & 10 deletions .github/config/chromium_android-arm64.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,6 @@
"chromium_android-arm64"
],
"targets": [
"base_unittests",
"sql_unittests",
"net_unittests",
"url_unittests",
"ipc_tests",
"mojo_unittests",
"gpu_unittests",
"gin_unittests",
"blink_unittests",
"media_unittests",
"content_shell",
"system_webview_apk",
"system_webview_shell_apk"
Expand Down
10 changes: 0 additions & 10 deletions .github/config/chromium_android-x86.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,6 @@
"chromium_android-x86"
],
"targets": [
"base_unittests",
"sql_unittests",
"net_unittests",
"url_unittests",
"ipc_tests",
"mojo_unittests",
"gpu_unittests",
"gin_unittests",
"blink_unittests",
"media_unittests",
"content_shell",
"system_webview_apk",
"system_webview_shell_apk"
Expand Down
62 changes: 50 additions & 12 deletions .github/workflows/main.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ jobs:
matrix:
platform: ${{ fromJson(needs.initialize.outputs.platforms) }}
include: ${{ fromJson(needs.initialize.outputs.includes) }}
config: [devel, qa, gold]
config: [devel]
container: ${{ needs.docker-build-image.outputs.docker_tag }}
env:
TEST_ARTIFACTS_KEY: ${{ matrix.platform }}_${{ matrix.name }}_test_artifacts
Expand Down Expand Up @@ -183,9 +183,47 @@ jobs:
upload_on_host_test_artifacts: ${{ matrix.config == 'devel' && needs.initialize.outputs.test_on_host }}
upload_on_device_test_artifacts: ${{ matrix.config == 'devel' && needs.initialize.outputs.test_on_device }}

test:
# Runs on-device integration and unit tests.
on-device-test:
needs: [initialize, build]
# Run ODT when on_device label is applied on PR.
# Also, run ODT on push and schedule if not explicitly disabled via repo vars.
if: needs.initialize.outputs.test_on_device == 'true' &&
(
(github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'on_device')) ||
(vars.RUN_ODT_TESTS_ON_NIGHTLY != 'False' && (inputs.nightly == 'true' || github.event_name == 'schedule')) ||
(vars.RUN_ODT_TESTS_ON_POSTSUBMIT != 'False' && github.event_name == 'push')
)
runs-on: [self-hosted, odt-runner]
name: ${{ matrix.name }}_on_device
permissions: {}
strategy:
fail-fast: false
matrix:
platform: ${{ fromJson(needs.initialize.outputs.platforms) }}
include: ${{ fromJson(needs.initialize.outputs.includes) }}
config: [devel]
env:
TEST_RESULTS_DIR: ${{ matrix.name }}_test_results
TEST_RESULTS_KEY: ${{ matrix.platform }}_${{ matrix.name }}_test_results
steps:
- name: Checkout
uses: kaidokert/[email protected]
timeout-minutes: 30
with:
fetch-depth: 1
persist-credentials: false
- name: Run On-Device Tests (${{ matrix.shard }})
id: on-device-tests
uses: ./.github/actions/on_device_tests
with:
test_results_key: ${{ env.TEST_RESULTS_KEY }}
gcs_results_path: gs://cobalt-unittest-storage/results/${{ matrix.name }}/${{ github.run_id }}
results_dir: ${{ env.TEST_RESULTS_DIR }}

on-host-test:
needs: [initialize, docker-build-image, build]
if: needs.initialize.outputs.test_on_host == 'true' || needs.initialize.outputs.test_on_device == 'true'
if: needs.initialize.outputs.test_on_host == 'true'
permissions: {}
# TODO(b/372303096): Should have dedicated runner?
runs-on: [self-hosted, chrobalt-linux-runner]
Expand All @@ -209,20 +247,20 @@ jobs:
path: src
- name: Run On-Host Tests
id: on-host-tests
if: always() && needs.initialize.outputs.test_on_host == 'true'
if: always()
uses: ./src/.github/actions/on_host_tests
with:
test_artifacts_key: ${{ env.TEST_ARTIFACTS_KEY }}
test_results_key: ${{ env.TEST_RESULTS_KEY }}
num_gtest_shards: ${{ needs.initialize.outputs.num_gtest_shards }}

test-upload:
needs: [initialize, docker-build-image, build, test]
needs: [initialize, docker-build-image, build, on-host-test, on-device-test]
if: always() &&
(
needs.initialize.outputs.test_on_host == 'true' ||
needs.initialize.outputs.test_on_device == 'true'
)
(
needs.initialize.outputs.test_on_host == 'true' ||
needs.initialize.outputs.test_on_device == 'true'
)
permissions: {}
runs-on: [self-hosted, chrobalt-linux-runner]
name: ${{ matrix.name }}_tests_upload
Expand All @@ -249,12 +287,12 @@ jobs:
datadog_api_key: ${{ secrets.datadog_api_key }}
continue-on-error: true


validate-test-result:
needs: [initialize, docker-build-image, build, test]
needs: [initialize, docker-build-image, build, on-host-test]
if: always() &&
(
needs.initialize.outputs.test_on_host == 'true' ||
needs.initialize.outputs.test_on_device == 'true'
needs.initialize.outputs.test_on_host == 'true'
)
permissions: {}
runs-on: ubuntu-latest
Expand Down
34 changes: 27 additions & 7 deletions cobalt/build/archive_test_artifacts.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import argparse
import json
import os
import shutil
import subprocess
import tempfile
from typing import List
Expand All @@ -35,7 +36,7 @@ def _make_tar(archive_path: str, file_list: str):


def create_archive(targets: List[str], source_dir: str, destination_dir: str,
platform: str, combine: bool):
platform: str, uber_archive: bool):
"""Main logic. Collects runtime dependencies from the source directory for
each target."""
# TODO(b/382508397): Remove when dynamically generated.
Expand Down Expand Up @@ -72,16 +73,27 @@ def create_archive(targets: List[str], source_dir: str, destination_dir: str,
}
deps |= target_deps

if not combine:
if not uber_archive:
output_path = os.path.join(destination_dir, f'{target_name}_deps.tar.gz')
_make_tar(output_path, deps)

if combine:
if uber_archive:
output_path = os.path.join(destination_dir, 'test_artifacts.tar.gz')
_make_tar(output_path, deps)


if __name__ == '__main__':
def copy_apks(targets: List[str], source_dir: str, destination_dir: str):
"""Copies the target APKs from the source directory to the destination.
The path to the APK in the source directory (assumed here to be the out
directory) is defined in build/config/android/rules.gni
"""
for target in targets:
_, target_name = target.split(':')
apk_path = f'{source_dir}/{target_name}_apk/{target_name}-debug.apk'
shutil.copy2(apk_path, destination_dir)


def main():
parser = argparse.ArgumentParser()
parser.add_argument(
'-s',
Expand All @@ -103,9 +115,17 @@ def create_archive(targets: List[str], source_dir: str, destination_dir: str,
'--targets',
required=True,
type=lambda arg: arg.split(','),
help='The targets to package, comma-separated. Must be fully qualified '
'for android.')
help='The targets to package, comma-separated. Must be fully qualified, '
'e.g. path/to:target.')
args = parser.parse_args()

uber_archive = args.platform.startswith('linux')
create_archive(args.targets, args.source_dir, args.destination_dir,
args.platform, args.platform.startswith('linux'))
args.platform, uber_archive)

if args.platform.startswith('android'):
copy_apks(args.targets, args.source_dir, args.destination_dir)


if __name__ == '__main__':
main()
6 changes: 6 additions & 0 deletions cobalt/testing/filters/android-arm/base_unittests_filter.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"failing_tests": [
"BreakIteratorTest.BreakCharacter",
"ValuesUtilTest.FilePath"
]
}
Loading
Loading