Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Redirect run_ios_tests.sh to run_ios_tests.dart. #53717

Merged
merged 11 commits into from
Sep 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
64 changes: 47 additions & 17 deletions testing/scenario_app/bin/run_ios_tests.dart
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,11 @@ void main(List<String> args) async {
} else {
iosEngineVariant = 'ios_debug_sim_unopt';
}
final String dumpXcresultOnFailurePath;

// Null if the tests should create and dispose their own temporary directory.
String? dumpXcresultOnFailurePath;
if (results.option('dump-xcresult-on-failure') case final String path) {
dumpXcresultOnFailurePath = path;
} else {
dumpXcresultOnFailurePath = io.Directory.systemTemp.createTempSync().path;
}

// Run the actual script.
Expand Down Expand Up @@ -88,6 +88,12 @@ void main(List<String> args) async {
}
}

void _deleteIfPresent(io.FileSystemEntity entity) {
if (entity.existsSync()) {
entity.deleteSync(recursive: true);
}
}

/// Runs the script.
///
/// The [cleanup] set contains cleanup tasks to run when the script is either
Expand All @@ -105,7 +111,7 @@ Future<void> _run(
required String osVersion,
required bool withImpeller,
required bool withSkia,
required String dumpXcresultOnFailure,
required String? dumpXcresultOnFailure,
}) async {
// Terminate early on SIGINT.
late final StreamSubscription<void> sigint;
Expand All @@ -127,7 +133,7 @@ Future<void> _run(
iosEngineVariant: iosEngineVariant,
);

cleanup.add(() => resultBundle.deleteSync(recursive: true));
cleanup.add(() => _deleteIfPresent(resultBundle));

if (withSkia) {
io.stderr.writeln('Running simulator tests with Skia');
Expand All @@ -141,22 +147,31 @@ Future<void> _run(
xcodeBuildExtraArgs: [
// Plist with `FTEEnableImpeller=NO`; all projects in the workspace require this file.
// For example, `FlutterAppExtensionTestHost` has a dummy file under the below directory.
r'INFOPLIST_FILE="$(TARGET_NAME)/Info_Skia.plist"',
r'INFOPLIST_FILE=$(TARGET_NAME)/Info_Skia.plist',
],
);
cleanup.add(process.kill);

// Create a temporary directory, if needed.
var storePath = dumpXcresultOnFailure;
if (storePath == null) {
final dumpDir = io.Directory.systemTemp.createTempSync();
storePath = dumpDir.path;
cleanup.add(() => dumpDir.delete(recursive: true));
}

if (await process.exitCode != 0) {
final String outputPath = _zipAndStoreFailedTestResults(
iosEngineVariant: iosEngineVariant,
resultBundlePath: resultBundle.path,
storePath: dumpXcresultOnFailure,
resultBundle: resultBundle,
storePath: storePath,
);
io.stderr.writeln('Failed test results are stored at $outputPath');
throw _ToolFailure('test failed.');
} else {
io.stderr.writeln('test succcess.');
}
_deleteIfPresent(resultBundle);
}

if (withImpeller) {
Expand All @@ -169,17 +184,26 @@ Future<void> _run(
);
cleanup.add(process.kill);

// Create a temporary directory, if needed.
var storePath = dumpXcresultOnFailure;
if (storePath == null) {
final dumpDir = io.Directory.systemTemp.createTempSync();
storePath = dumpDir.path;
cleanup.add(() => dumpDir.delete(recursive: true));
}

if (await process.exitCode != 0) {
final String outputPath = _zipAndStoreFailedTestResults(
iosEngineVariant: iosEngineVariant,
resultBundlePath: resultBundle.path,
storePath: dumpXcresultOnFailure,
resultBundle: resultBundle,
storePath: storePath,
);
io.stderr.writeln('Failed test results are stored at $outputPath');
throw _ToolFailure('test failed.');
} else {
io.stderr.writeln('test succcess.');
}
_deleteIfPresent(resultBundle);
}
}

Expand Down Expand Up @@ -261,8 +285,9 @@ void _ensureSimulatorsRotateAutomaticallyForPlatformViewRotationTest() {
}

void _deleteAnyExistingDevices({required String deviceName}) {
io.stderr
.writeln('Deleting any existing simulator devices named $deviceName...');
io.stderr.writeln(
'Deleting any existing simulator devices named $deviceName...',
);

bool deleteSimulator() {
final result = io.Process.runSync(
Expand Down Expand Up @@ -314,8 +339,9 @@ void _createDevice({
));

// Create a temporary directory to store the test results.
final result =
io.Directory(scenarioPath).createTempSync('ios_scenario_xcresult');
final result = io.Directory(scenarioPath).createTempSync(
'ios_scenario_xcresult',
);
return (scenarioPath, result);
}

Expand Down Expand Up @@ -353,7 +379,7 @@ Future<io.Process> _runTests({
@useResult
String _zipAndStoreFailedTestResults({
required String iosEngineVariant,
required String resultBundlePath,
required io.Directory resultBundle,
required String storePath,
}) {
final outputPath = path.join(storePath, '$iosEngineVariant.zip');
Expand All @@ -363,11 +389,15 @@ String _zipAndStoreFailedTestResults({
'-q',
'-r',
outputPath,
resultBundlePath,
resultBundle.path,
],
);
if (result.exitCode != 0) {
throw Exception('Failed to zip the test results: ${result.stderr}');
throw Exception(
'Failed to zip the test results (exit code = ${result.exitCode}).\n\n'
'Stderr: ${result.stderr}\n\n'
'Stdout: ${result.stdout}',
);
}
return outputPath;
}
106 changes: 17 additions & 89 deletions testing/scenario_app/run_ios_tests.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
#!/bin/bash

set -e
# TODO(matanlurey): Remove all references are gone and using run_ios_tests.dart.
# See https://github.com/flutter/flutter/issues/143953 for tracking.

set -e

# Needed because if it is set, cd may print the path it changed to.
unset CDPATH
Expand All @@ -24,94 +26,20 @@ function follow_links() (
echo "$file"
)

SCRIPT_DIR=$(follow_links "$(dirname -- "${BASH_SOURCE[0]}")")
SRC_DIR="$(cd "$SCRIPT_DIR/../../.."; pwd -P)"

if uname -m | grep "arm64"; then
FLUTTER_ENGINE="ios_debug_sim_unopt_arm64"
else
FLUTTER_ENGINE="ios_debug_sim_unopt"
fi

if [[ $# -eq 1 ]]; then
FLUTTER_ENGINE="$1"
fi

# Make sure simulators rotate automatically for "PlatformViewRotation" test.
# Can also be set via Simulator app Device > Rotate Device Automatically
defaults write com.apple.iphonesimulator RotateWindowWhenSignaledByGuest -int 1

SCENARIO_PATH=$SRC_DIR/out/$FLUTTER_ENGINE/scenario_app/Scenarios
pushd .
cd $SCENARIO_PATH

RESULT_BUNDLE_FOLDER=$(mktemp -d ios_scenario_xcresult_XXX)
RESULT_BUNDLE_PATH="${SCENARIO_PATH}/${RESULT_BUNDLE_FOLDER}"

# Zip and upload xcresult to luci.
# First parameter ($1) is the zip output name.
zip_and_upload_xcresult_to_luci () {
# We don't want the zip to contain the abusolute path,
# so use relative path (./$RESULT_BUNDLE_FOLDER) instead.
zip -q -r $1 "./$RESULT_BUNDLE_FOLDER"
mv -f $1 $FLUTTER_TEST_OUTPUTS_DIR
exit 1
function dart_bin() {
dart_path="$1/flutter/third_party/dart/tools/sdks/dart-sdk/bin"
if [[ ! -e "$dart_path" ]]; then
dart_path="$1/third_party/dart/tools/sdks/dart-sdk/bin"
fi
echo "$dart_path"
}

readonly DEVICE_NAME="iPhone SE (3rd generation)"
readonly DEVICE=com.apple.CoreSimulator.SimDeviceType.iPhone-SE-3rd-generation
readonly OS_RUNTIME=com.apple.CoreSimulator.SimRuntime.iOS-17-0
readonly OS="17.0"

# Delete any existing devices named "iPhone SE (3rd generation)". Having more
# than one may cause issues when builds target the device.
echo "Deleting any existing devices names $DEVICE_NAME..."
RESULT=0
while [[ $RESULT == 0 ]]; do
xcrun simctl delete "$DEVICE_NAME" || RESULT=1
if [ $RESULT == 0 ]; then
echo "Deleted $DEVICE_NAME"
fi
done
echo ""

echo "Creating $DEVICE_NAME $DEVICE $OS_RUNTIME ..."
xcrun simctl create "$DEVICE_NAME" "$DEVICE" "$OS_RUNTIME"
echo ""

echo "Running simulator tests with Impeller"
echo ""

if set -o pipefail && xcodebuild -sdk iphonesimulator \
-scheme Scenarios \
-resultBundlePath "$RESULT_BUNDLE_PATH/ios_scenario.xcresult" \
-destination "platform=iOS Simulator,OS=$OS,name=$DEVICE_NAME" \
clean test \
FLUTTER_ENGINE="$FLUTTER_ENGINE"; then
echo "test success."
else
echo "test failed."
zip_and_upload_xcresult_to_luci "ios_scenario_xcresult.zip"
fi
rm -rf $RESULT_BUNDLE_PATH

echo "Running simulator tests with Skia"
echo ""

# Override Info.plist with FLTEnableImpeller=NO, all projects in the workspace requires a Info_Skia.plist.
# For example, FlutterAppExtensionTestHost has a Info_Skia.plist dummy file in its directory.
if set -o pipefail && xcodebuild -sdk iphonesimulator \
-scheme Scenarios \
-resultBundlePath "$RESULT_BUNDLE_PATH/ios_scenario.xcresult" \
-destination "platform=iOS Simulator,OS=$OS,name=$DEVICE_NAME" \
clean test \
FLUTTER_ENGINE="$FLUTTER_ENGINE" \
INFOPLIST_FILE="\$(TARGET_NAME)/Info_Skia.plist"; then
echo "test success."
else
echo "test failed."
zip_and_upload_xcresult_to_luci "ios_scenario_impeller_xcresult.zip"
fi
rm -rf $RESULT_BUNDLE_PATH
SCRIPT_DIR=$(follow_links "$(dirname -- "${BASH_SOURCE[0]}")")
SRC_DIR="$(cd "$SCRIPT_DIR/../../.."; pwd -P)"
DART_BIN=$(dart_bin "$SRC_DIR")
DART="${DART_BIN}/dart"

popd
"$DART" \
--disable-dart-dev \
testing/scenario_app/bin/run_ios_tests.dart \
"$@"