blob: fe31550d6a50182b3e0b4f13022d1d3f9a1f9a19 [file] [log] [blame]
// Copyright 2014 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.
import 'dart:io' show File, Platform;
import 'dart:typed_data';
import 'package:collection/collection.dart';
import 'package:flutter_devicelab/framework/devices.dart';
import 'package:flutter_devicelab/framework/framework.dart';
import 'package:flutter_devicelab/framework/task_result.dart';
import 'package:flutter_devicelab/framework/utils.dart';
import 'package:flutter_devicelab/tasks/integration_tests.dart';
import 'package:path/path.dart' as path;
import 'package:standard_message_codec/standard_message_codec.dart';
Future<void> main() async {
deviceOperatingSystem = DeviceOperatingSystem.android;
await task(() async {
await createFlavorsTest().call();
await createIntegrationTestFlavorsTest().call();
final String projectPath = '${flutterDirectory.path}/dev/integration_tests/flavors';
final TaskResult installTestsResult = await inDirectory(projectPath, () async {
final List<TaskResult> testResults = <TaskResult>[
await _testInstallDebugPaidFlavor(projectPath),
await _testInstallBogusFlavor(),
];
final TaskResult? firstInstallFailure = testResults.firstWhereOrNull(
(TaskResult element) => element.failed,
);
return firstInstallFailure ?? TaskResult.success(null);
});
await _testFlavorsWhenBuildStartsWithGradle(projectPath);
return installTestsResult;
});
}
// Ensures installation works. Also tests asset bundling while we are at it.
Future<TaskResult> _testInstallDebugPaidFlavor(String projectDir) async {
await evalFlutter('install', options: <String>['--debug', '--flavor', 'paid']);
final Uint8List assetManifestFileData = File(
path.join(
projectDir,
'build',
'app',
'intermediates',
'assets',
'paidDebug',
'mergePaidDebugAssets',
'flutter_assets',
'AssetManifest.bin',
),
).readAsBytesSync();
final Map<Object?, Object?> assetManifest =
const StandardMessageCodec().decodeMessage(ByteData.sublistView(assetManifestFileData))
as Map<Object?, Object?>;
if (assetManifest.containsKey('assets/free/free.txt')) {
return TaskResult.failure(
'Expected the asset "assets/free/free.txt", which '
' was declared with a flavor of "free" to not be included in the asset bundle '
' because the --flavor was set to "paid".',
);
}
if (!assetManifest.containsKey('assets/paid/paid.txt')) {
return TaskResult.failure(
'Expected the asset "assets/paid/paid.txt", which '
' was declared with a flavor of "paid" to be included in the asset bundle '
' because the --flavor was set to "paid".',
);
}
await flutter('install', options: <String>['--debug', '--flavor', 'paid', '--uninstall-only']);
return TaskResult.success(null);
}
Future<TaskResult> _testInstallBogusFlavor() async {
final StringBuffer stderr = StringBuffer();
await evalFlutter(
'install',
canFail: true,
stderr: stderr,
options: <String>['--flavor', 'bogus'],
);
final String stderrString = stderr.toString();
final String expectedApkPath = path.join(
'build',
'app',
'outputs',
'flutter-apk',
'app-bogus-release.apk',
);
if (!stderrString.contains('"$expectedApkPath" does not exist.')) {
print(stderrString);
return TaskResult.failure('Should not succeed with bogus flavor');
}
return TaskResult.success(null);
}
Future<TaskResult> _testFlavorsWhenBuildStartsWithGradle(String projectDir) async {
final String gradlew = Platform.isWindows ? 'gradlew.bat' : 'gradlew';
final String gradlewExecutable = Platform.isWindows ? '.\\$gradlew' : './$gradlew';
final String androidDirPath = '$projectDir/android';
final StringBuffer stdout = StringBuffer();
// Prebuild the project to generate the Android gradle wrapper files.
await inDirectory(projectDir, () async {
await flutter('build', options: <String>['apk', '--config-only']);
});
await inDirectory(androidDirPath, () async {
await exec(gradlewExecutable, <String>['clean']);
await exec(gradlewExecutable, <String>[':app:assemblePaidDebug', '--info'], output: stdout);
});
final String stdoutString = stdout.toString();
if (!stdoutString.contains('-dFlavor=paid')) {
return TaskResult.failure('Expected to see -dFlavor=paid in the gradle verbose output');
}
final String appPath = path.join(
projectDir,
'build',
'app',
'outputs',
'flutter-apk',
'app-paid-debug.apk',
);
return createFlavorsTest(
extraOptions: <String>['--flavor', 'paid', '--use-application-binary=$appPath'],
).call();
}