Skip to content

Commit 9efb188

Browse files
authored
Fix test on emulator workflow failures (#734)
1 parent ae8a3f2 commit 9efb188

File tree

3 files changed

+60
-32
lines changed

3 files changed

+60
-32
lines changed

.github/workflows/integration_tests.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -829,7 +829,7 @@ jobs:
829829
npm install -g firebase-tools
830830
firebase emulators:start --only firestore --project demo-example &
831831
- name: Run Android integration tests on Emulator locally
832-
timeout-minutes: 60
832+
timeout-minutes: 90
833833
if: steps.get-device-type.outputs.device_type == 'virtual'
834834
run: |
835835
python scripts/gha/test_simulator.py --testapp_dir testapps \

scripts/gha/integration_testing/gameloop_android/build.gradle

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ allprojects {
2323

2424
ext {
2525
compileSdk = 28
26-
buildTools = '28.0.3'
26+
buildTools = '29.0.2'
2727
minSdk = 16
2828
targetSdk = 28
2929
}

scripts/gha/test_simulator.py

+58-30
Original file line numberDiff line numberDiff line change
@@ -59,12 +59,12 @@
5959
Device Information is stored in TEST_DEVICES in print_matrix_configuration.py
6060
Example:
6161
sdk id "system-images;android-29;google_apis;x86":
62-
--android_sdk "system-images;android-29;google_apis;x86" --build_tools_version "28.0.3"
62+
--android_sdk "system-images;android-29;google_apis;x86" --build_tools_version "29.0.2"
6363
6464
Alternatively, to set an Android device, use the one of the values below:
6565
[emulator_min, emulator_target, emulator_latest]
6666
Example:
67-
--android_device "emulator_target" --build_tools_version "28.0.3"
67+
--android_device "emulator_target" --build_tools_version "29.0.2"
6868
6969
Returns:
7070
1: No iOS/Android integration_test apps found
@@ -92,6 +92,14 @@
9292
_GAMELOOP_PACKAGE = "com.google.firebase.gameloop"
9393
_RESULT_FILE = "Results1.json"
9494
_TEST_RETRY = 3
95+
_CMD_TIMEOUT = 300
96+
97+
_DEVICE_NONE = "None"
98+
_DEVICE_ANDROID = "Android"
99+
_DEVICE_APPLE = "Apple"
100+
101+
_RESET_TYPE_REBOOT = 1
102+
_RESET_TYPE_WIPE_REBOOT = 2
95103

96104
FLAGS = flags.FLAGS
97105

@@ -129,7 +137,7 @@
129137
"android_sdk", "system-images;android-29;google_apis;x86",
130138
"See module docstring for details on how to set and get this id.")
131139
flags.DEFINE_string(
132-
"build_tools_version", "28.0.3",
140+
"build_tools_version", "29.0.2",
133141
"android build_tools_version")
134142
flags.DEFINE_string(
135143
"logfile_name", "simulator-test",
@@ -501,19 +509,19 @@ def _setup_android(platform_version, build_tool_version, sdk_id):
501509
"platforms;%s" % platform_version,
502510
"build-tools;%s" % build_tool_version]
503511
logging.info("Install packages: %s", " ".join(args))
504-
subprocess.run(args=args, check=True)
512+
_run_with_retry(args)
505513

506514
command = "yes | sdkmanager --licenses"
507515
logging.info("Accept all licenses: %s", command)
508-
subprocess.run(command, shell=True, check=False)
516+
_run_with_retry(command, shell=True, check=False)
509517

510518
args = ["sdkmanager", sdk_id]
511519
logging.info("Download an emulator: %s", " ".join(args))
512-
subprocess.run(args=args, check=True)
520+
_run_with_retry(args)
513521

514522
args = ["sdkmanager", "--update"]
515523
logging.info("Update all installed packages: %s", " ".join(args))
516-
subprocess.run(args=args, check=True)
524+
_run_with_retry(args, check=False)
517525

518526

519527
def _shutdown_emulator():
@@ -549,27 +557,43 @@ def _create_and_boot_emulator(sdk_id):
549557
logging.info("Wait for emulator to boot: %s", " ".join(args))
550558
subprocess.run(args=args, check=True)
551559
if FLAGS.ci:
552-
# wait extra 90 seconds to ensure emulator fully booted.
553-
time.sleep(180)
560+
# wait extra 210 seconds to ensure emulator fully booted.
561+
time.sleep(210)
554562
else:
555563
time.sleep(45)
556564

565+
def _run_with_retry(args, shell=False, check=True, timeout=_CMD_TIMEOUT, retry_time=_TEST_RETRY, device=_DEVICE_NONE, type=_RESET_TYPE_REBOOT):
566+
if retry_time > 1:
567+
try:
568+
subprocess.run(args, shell=shell, check=check, timeout=timeout)
569+
except:
570+
if device == _DEVICE_ANDROID:
571+
_reset_emulator_on_error(type)
572+
_run_with_retry(args, shell, check, timeout, retry_time-1, device, type)
573+
else:
574+
subprocess.run(args, shell=shell, check=check, timeout=timeout)
575+
557576

558-
def _reset_emulator_on_error(instrumented_test_result):
559-
logging.info("game-loop test result: %s", instrumented_test_result)
560-
if "FAILURES!!!" in instrumented_test_result:
561-
logging.info("game-loop test error!!! reboot emualtor...")
562-
args = ["adb", "-e", "reboot"]
563-
logging.info("Reboot android emulator: %s", " ".join(args))
564-
subprocess.run(args=args, check=True)
565-
args = ["adb", "wait-for-device"]
566-
logging.info("Wait for emulator to boot: %s", " ".join(args))
577+
def _reset_emulator_on_error(type=_RESET_TYPE_REBOOT):
578+
if type == _RESET_TYPE_WIPE_REBOOT:
579+
# wipe emulator data
580+
args = ["adb", "shell", "recovery", "--wipe_data"]
581+
logging.info("Erase my Emulator: %s", " ".join(args))
567582
subprocess.run(args=args, check=True)
568-
if FLAGS.ci:
569-
# wait extra 90 seconds to ensure emulator booted.
570-
time.sleep(90)
571-
else:
572-
time.sleep(45)
583+
584+
# reboot emulator: _RESET_TYPE_WIPE_REBOOT, _RESET_TYPE_REBOOT
585+
logging.info("game-loop test error!!! reboot emualtor...")
586+
args = ["adb", "-e", "reboot"]
587+
logging.info("Reboot android emulator: %s", " ".join(args))
588+
subprocess.run(args=args, check=True)
589+
args = ["adb", "wait-for-device"]
590+
logging.info("Wait for emulator to boot: %s", " ".join(args))
591+
subprocess.run(args=args, check=True)
592+
if FLAGS.ci:
593+
# wait extra 210 seconds to ensure emulator booted.
594+
time.sleep(210)
595+
else:
596+
time.sleep(45)
573597

574598

575599
def _get_package_name(app_path):
@@ -599,26 +623,29 @@ def _install_android_app(app_path):
599623
"""Install integration_test app into the emulator."""
600624
args = ["adb", "install", app_path]
601625
logging.info("Install testapp: %s", " ".join(args))
602-
subprocess.run(args=args, check=False)
626+
_run_with_retry(args, device=_DEVICE_ANDROID, type=_RESET_TYPE_WIPE_REBOOT)
603627

604628

605629
def _uninstall_android_app(package_name):
606630
"""Uninstall integration_test app from the emulator."""
607631
args = ["adb", "uninstall", package_name]
608632
logging.info("Uninstall testapp: %s", " ".join(args))
609-
subprocess.run(args=args, check=False)
633+
_run_with_retry(args, device=_DEVICE_ANDROID, type=_RESET_TYPE_REBOOT)
610634

611635

612636
def _install_android_gameloop_app(gameloop_project):
613637
os.chdir(gameloop_project)
614-
logging.info("CD to gameloop_project: %s", gameloop_project)
615-
_uninstall_android_app("com.google.firebase.gameloop")
638+
logging.info("cd to gameloop_project: %s", gameloop_project)
639+
args = ["adb", "uninstall", "com.google.firebase.gameloop"]
640+
_run_with_retry(args, check=False, device=_DEVICE_ANDROID, type=_RESET_TYPE_REBOOT)
641+
616642
args = ["./gradlew", "clean"]
617643
logging.info("Clean game-loop cache: %s", " ".join(args))
618-
subprocess.run(args=args, check=False)
644+
_run_with_retry(args, check=False, device=_DEVICE_ANDROID, type=_RESET_TYPE_REBOOT)
645+
619646
args = ["./gradlew", "installDebug", "installDebugAndroidTest"]
620647
logging.info("Installing game-loop app and test: %s", " ".join(args))
621-
subprocess.run(args=args, check=True)
648+
_run_with_retry(args, device=_DEVICE_ANDROID, type=_RESET_TYPE_REBOOT)
622649

623650

624651
def _run_instrumented_test():
@@ -629,7 +656,8 @@ def _run_instrumented_test():
629656
"-w", "%s.test/androidx.test.runner.AndroidJUnitRunner" % _GAMELOOP_PACKAGE]
630657
logging.info("Running game-loop test: %s", " ".join(args))
631658
result = subprocess.run(args=args, capture_output=True, text=True, check=False)
632-
_reset_emulator_on_error(result.stdout)
659+
if "FAILURES!!!" in result.stdout:
660+
_reset_emulator_on_error(_RESET_TYPE_REBOOT)
633661

634662

635663
def _get_android_test_log(test_package):

0 commit comments

Comments
 (0)