diff --git a/testing/scenario_app/android/app/src/main/java/dev/flutter/scenarios/ExternalTextureFlutterActivity.java b/testing/scenario_app/android/app/src/main/java/dev/flutter/scenarios/ExternalTextureFlutterActivity.java index 753f2e2690fb8..e363680777b9d 100644 --- a/testing/scenario_app/android/app/src/main/java/dev/flutter/scenarios/ExternalTextureFlutterActivity.java +++ b/testing/scenario_app/android/app/src/main/java/dev/flutter/scenarios/ExternalTextureFlutterActivity.java @@ -91,6 +91,8 @@ public void waitUntilFlutterRendered() { super.waitUntilFlutterRendered(); try { + // TODO: Remove after debugging https://github.com/flutter/flutter/issues/145988. + io.flutter.Log.i("Scenarios", "waitUntilFlutterRendered() | firstFrameLatch"); firstFrameLatch.await(); } catch (InterruptedException e) { throw new RuntimeException(e); diff --git a/testing/scenario_app/android/app/src/main/java/dev/flutter/scenarios/TestableFlutterActivity.java b/testing/scenario_app/android/app/src/main/java/dev/flutter/scenarios/TestableFlutterActivity.java index 69c9dd0260353..bb163be4defc9 100644 --- a/testing/scenario_app/android/app/src/main/java/dev/flutter/scenarios/TestableFlutterActivity.java +++ b/testing/scenario_app/android/app/src/main/java/dev/flutter/scenarios/TestableFlutterActivity.java @@ -8,6 +8,7 @@ import android.view.WindowManager; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import io.flutter.Log; import io.flutter.embedding.android.FlutterActivity; import io.flutter.embedding.engine.FlutterEngine; import java.util.concurrent.CountDownLatch; @@ -44,6 +45,8 @@ protected void notifyFlutterRendered() { public void waitUntilFlutterRendered() { try { + // TODO: Remove after debugging https://github.com/flutter/flutter/issues/145988. + Log.i("Scenarios", "waitUntilFlutterRendered() | flutterUiRenderedLatch"); flutterUiRenderedLatch.await(); } catch (InterruptedException e) { throw new RuntimeException(e); diff --git a/testing/scenario_app/bin/run_android_tests.dart b/testing/scenario_app/bin/run_android_tests.dart index 669a255440f06..c0b8ffaf4b0cc 100644 --- a/testing/scenario_app/bin/run_android_tests.dart +++ b/testing/scenario_app/bin/run_android_tests.dart @@ -61,12 +61,23 @@ void main(List args) async { // Capture CTRL-C. late final StreamSubscription onSigint; + + // Capture requested termination. The goal is to catch timeouts. + late final StreamSubscription onSigterm; + void cancelSignalHandlers() { + onSigint.cancel(); + onSigterm.cancel(); + } runZonedGuarded( () async { onSigint = ProcessSignal.sigint.watch().listen((_) { - onSigint.cancel(); + cancelSignalHandlers(); panic(['Received SIGINT']); }); + onSigterm = ProcessSignal.sigterm.watch().listen((_) { + cancelSignalHandlers(); + panic(['Received SIGTERM']); + }); await _run( verbose: options.verbose, outDir: Directory(options.outDir), diff --git a/testing/scenario_app/lib/main.dart b/testing/scenario_app/lib/main.dart index 5e76f1d7306bf..080959becce46 100644 --- a/testing/scenario_app/lib/main.dart +++ b/testing/scenario_app/lib/main.dart @@ -92,10 +92,16 @@ void _onBeginFrame(Duration duration) { return; } currentScenario!.onBeginFrame(duration); + + // TODO(team): Remove after debugging https://github.com/flutter/flutter/issues/145988. + print('onBeginFrame: $duration'); } void _onDrawFrame() { currentScenario?.onDrawFrame(); + + // TODO(team): Remove after debugging https://github.com/flutter/flutter/issues/145988. + print('onDrawFrame'); } void _onMetricsChanged() { diff --git a/testing/scenario_app/tool/deflake_android_tests.sh b/testing/scenario_app/tool/deflake_android_tests.sh new file mode 100755 index 0000000000000..7940e00ff5dc7 --- /dev/null +++ b/testing/scenario_app/tool/deflake_android_tests.sh @@ -0,0 +1,73 @@ +#!/bin/bash + +# Copyright 2013 The Flutter Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +set -e + +# Needed because if it is set, cd may print the path it changed to. +unset CDPATH + +# On Mac OS, readlink -f doesn't work, so follow_links traverses the path one +# link at a time, and then cds into the link destination and find out where it +# ends up. +# +# The function is enclosed in a subshell to avoid changing the working directory +# of the caller. +function follow_links() ( + cd -P "$(dirname -- "$1")" + file="$PWD/$(basename -- "$1")" + while [[ -L "$file" ]]; do + cd -P "$(dirname -- "$file")" + file="$(readlink -- "$file")" + cd -P "$(dirname -- "$file")" + file="$PWD/$(basename -- "$file")" + done + echo "$file" +) + +SCRIPT_DIR=$(follow_links "$(dirname -- "${BASH_SOURCE[0]}")") +ENGINE_DIR="$(cd "$SCRIPT_DIR/../../.."; pwd -P)" + +# Find the Dart executable. +case "$(uname -s)" in + Linux) + OS="linux" + ;; + Darwin) + OS="macos" + ;; + *) + echo "The host platform is not supported by this tool" + exit 1 +esac + +case "$(uname -m)" in + arm64) + CPU="arm64" + ;; + x86_64) + CPU="x64" + ;; + *) + echo "The host platform is not supported by this tool" + exit 1 +esac + +PLATFORM="${OS}-${CPU}" +DART_SDK_DIR="${ENGINE_DIR}/prebuilts/${PLATFORM}/dart-sdk" +DART="${DART_SDK_DIR}/bin/dart" + +# Run the tool indefinitely until there is an error. +COUNT=0 +while true; do + COUNT=$((COUNT + 1)) + echo "Running test iteration $COUNT" + "$DART" "$SCRIPT_DIR/bin/run_android_tests.dart" "$@" + # Break if non-zero exit code. + if [ $? -ne 0 ]; then + echo "Error running tests. Exiting." + break + fi +done