Skip to content

Commit c9008f3

Browse files
authored
Use python to run firebase testlab, do not expect recipe to know location of APK (flutter#27434)
1 parent 1dca887 commit c9008f3

File tree

3 files changed

+112
-40
lines changed

3 files changed

+112
-40
lines changed

ci/firebase_testlab.py

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
#!/usr/bin/env python
2+
#
3+
# Copyright 2013 The Flutter Authors. All rights reserved.
4+
# Use of this source code is governed by a BSD-style license that can be
5+
# found in the LICENSE file.
6+
7+
import argparse
8+
import glob
9+
import re
10+
import os
11+
import subprocess
12+
import sys
13+
14+
script_dir = os.path.dirname(os.path.realpath(__file__))
15+
buildroot_dir = os.path.abspath(os.path.join(script_dir, '..', '..'))
16+
out_dir = os.path.join(buildroot_dir, 'out')
17+
bucket = 'gs://flutter_firebase_testlab'
18+
error_re = re.compile('[EF]/flutter')
19+
20+
21+
def RunFirebaseTest(apk, results_dir):
22+
try:
23+
# game-loop tests are meant for OpenGL apps.
24+
# This type of test will give the application a handle to a file, and
25+
# we'll write the timeline JSON to that file.
26+
# See https://firebase.google.com/docs/test-lab/android/game-loop
27+
# Pixel 4. As of this commit, this is a highly available device in FTL.
28+
subprocess.check_output([
29+
'gcloud',
30+
'--project', 'flutter-infra',
31+
'firebase', 'test', 'android', 'run',
32+
'--type', 'game-loop',
33+
'--app', apk,
34+
'--timeout', '2m',
35+
'--results-bucket', bucket,
36+
'--results-dir', results_dir,
37+
'--device', 'model=flame,version=29',
38+
])
39+
except subprocess.CalledProcessError as ex:
40+
print(ex.output)
41+
# Recipe will retry return codes from firebase that indicate an infra
42+
# failure.
43+
sys.exit(ex.returncode)
44+
45+
46+
def CheckLogcat(results_dir):
47+
logcat = subprocess.check_output([
48+
'gsutil', 'cat', '%s/%s/*/logcat' % (bucket, results_dir)
49+
])
50+
51+
logcat_match = error_re.match(logcat)
52+
if logcat_match:
53+
print('Errors in logcat:')
54+
print(logcat_match)
55+
sys.exit(1)
56+
57+
58+
def CheckTimeline(results_dir):
59+
du = subprocess.check_output([
60+
'gsutil', 'du',
61+
'%s/%s/*/game_loop_results/results_scenario_0.json' % (bucket, results_dir)
62+
]).strip()
63+
if du == '0':
64+
print('Failed to produce a timeline.')
65+
sys.exit(1)
66+
67+
68+
def main():
69+
parser = argparse.ArgumentParser()
70+
parser.add_argument('--variant', dest='variant', action='store',
71+
default='android_profile_arm64', help='The engine variant to run tests for.')
72+
parser.add_argument('--build-id',
73+
default=os.environ.get('SWARMING_TASK_ID', 'local_test'),
74+
help='A unique build identifier for this test. Used to sort results in the GCS bucket.')
75+
76+
args = parser.parse_args()
77+
78+
apks_dir = os.path.join(out_dir, args.variant, 'firebase_apks')
79+
apks = glob.glob('%s/*.apk' % apks_dir)
80+
81+
if not apks:
82+
print('No APKs found at %s' % apks_dir)
83+
return 1
84+
85+
git_revision = subprocess.check_output(
86+
['git', 'rev-parse', 'HEAD'], cwd=script_dir).strip()
87+
88+
for apk in apks:
89+
results_dir = '%s/%s/%s' % (os.path.basename(apk), git_revision, args.build_id)
90+
91+
RunFirebaseTest(apk, results_dir)
92+
CheckLogcat(results_dir)
93+
# scenario_app produces a timeline, but the android image test does not.
94+
if 'scenario' in apk:
95+
CheckTimeline(results_dir)
96+
97+
return 0
98+
99+
100+
if __name__ == '__main__':
101+
sys.exit(main())

ci/firebase_testlab.sh

Lines changed: 4 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -4,45 +4,10 @@
44
# Use of this source code is governed by a BSD-style license that can be
55
# found in the LICENSE file.
66

7-
set -e
8-
9-
APP="$1"
10-
if [[ -z "$APP" ]]; then
11-
echo "Application must be specified as the first argument to the script."
12-
exit 255
13-
fi
14-
15-
if [[ ! -f "$APP" ]]; then
16-
echo "File '$APP' not found."
17-
exit 255
18-
fi
7+
# TODO(dnfield): delete this script once recipes point to the python version.
198

20-
GIT_REVISION="${2:-$(git rev-parse HEAD)}"
21-
BUILD_ID="${3:-$SWARMING_TASK_ID}"
22-
23-
# Run the test.
24-
# game-loop tests are meant for OpenGL apps.
25-
# This type of test will give the application a handle to a file, and
26-
# we'll write the timeline JSON to that file.
27-
# See https://firebase.google.com/docs/test-lab/android/game-loop
28-
# Pixel 4. As of this commit, this is a highly available device in FTL.
29-
gcloud --project flutter-infra firebase test android run \
30-
--type game-loop \
31-
--app "$APP" \
32-
--timeout 2m \
33-
--results-bucket=gs://flutter_firebase_testlab \
34-
--results-dir="engine_scenario_test/$GIT_REVISION/$BUILD_ID" \
35-
--device model=flame,version=29
9+
set -e
3610

37-
errors=$(gsutil cat gs://flutter_firebase_testlab/engine_scenario_test/$GIT_REVISION/$BUILD_ID/\*/logcat | grep "[FE]/flutter" | true)
38-
if [[ ! -z $errors ]]; then
39-
echo "Errors detected in logcat:"
40-
echo "$errors"
41-
exit 1
42-
fi
11+
CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
4312

44-
result_size=$(gsutil du gs://flutter_firebase_testlab/engine_scenario_test/$GIT_REVISION/$BUILD_ID/\*/game_loop_results/results_scenario_0.json | cut -d " " -f1)
45-
if [[ $result_size == "0" ]]; then
46-
echo "Failed to produce a timeline."
47-
exit 1
48-
fi
13+
python $CURRENT_DIR/firebase_testlab.py

testing/scenario_app/android/BUILD.gn

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
import("//flutter/testing/scenario_app/runtime_mode.gni")
66

7-
action("android") {
7+
action("build_apk") {
88
script = "run_gradle.py"
99

1010
inputs = [ "$root_out_dir/flutter.jar" ]
@@ -48,3 +48,9 @@ action("android") {
4848
"//flutter/testing/scenario_app:scenario_app_snapshot",
4949
]
5050
}
51+
52+
copy("android") {
53+
sources = get_target_outputs(":build_apk")
54+
outputs = [ "$root_out_dir/firebase_apks/scenario_app.apk" ]
55+
deps = [ ":build_apk" ]
56+
}

0 commit comments

Comments
 (0)