Unverified Commit 3a0abac7 authored by Jonah Williams's avatar Jonah Williams Committed by GitHub

[flutter_tools] android workflow tests migrate from mockito (#81545)

parent 44157cf9
......@@ -7,43 +7,35 @@
import 'package:file/memory.dart';
import 'package:flutter_tools/src/android/android_sdk.dart';
import 'package:flutter_tools/src/android/android_workflow.dart';
import 'package:flutter_tools/src/base/io.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/base/os.dart';
import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/base/user_messages.dart';
import 'package:flutter_tools/src/base/version.dart';
import 'package:flutter_tools/src/doctor_validator.dart';
import 'package:mockito/mockito.dart';
import 'package:test/fake.dart';
import '../../src/common.dart';
import '../../src/context.dart';
import '../../src/fakes.dart';
import '../../src/mocks.dart' show MockAndroidSdk, MockProcessManager;
class MockAndroidSdkVersion extends Mock implements AndroidSdkVersion {}
void main() {
AndroidSdk sdk;
FakeAndroidSdk sdk;
Logger logger;
MemoryFileSystem fileSystem;
MockProcessManager processManager;
FakeProcessManager processManager;
FakeStdio stdio;
setUp(() {
sdk = MockAndroidSdk();
sdk = FakeAndroidSdk();
fileSystem = MemoryFileSystem.test();
fileSystem.directory('/home/me').createSync(recursive: true);
logger = BufferLogger.test();
processManager = MockProcessManager();
processManager = FakeProcessManager.empty();
stdio = FakeStdio();
});
FakeProcess Function(List<String>) processMetaFactory(List<String> stdout) {
final Stream<List<int>> stdoutStream = Stream<List<int>>.fromIterable(
stdout.map<List<int>>((String s) => s.codeUnits));
return (List<String> command) => FakeProcess(stdout: stdoutStream);
}
testWithoutContext('AndroidWorkflow handles a null AndroidSDK', () {
final AndroidWorkflow androidWorkflow = AndroidWorkflow(
featureFlags: TestFeatureFlags(),
......@@ -57,8 +49,8 @@ void main() {
});
testWithoutContext('AndroidWorkflow handles a null adb', () {
final MockAndroidSdk androidSdk = MockAndroidSdk();
when(androidSdk.adbPath).thenReturn(null);
final FakeAndroidSdk androidSdk = FakeAndroidSdk();
androidSdk.adbPath = null;
final AndroidWorkflow androidWorkflow = AndroidWorkflow(
featureFlags: TestFeatureFlags(),
androidSdk: androidSdk,
......@@ -72,8 +64,8 @@ void main() {
// Android Studio is not currently supported on Linux Arm64 hosts.
testWithoutContext('Not supported AndroidStudio on Linux Arm Hosts', () {
final MockAndroidSdk androidSdk = MockAndroidSdk();
when(androidSdk.adbPath).thenReturn(null);
final FakeAndroidSdk androidSdk = FakeAndroidSdk();
androidSdk.adbPath = null;
final AndroidWorkflow androidWorkflow = AndroidWorkflow(
featureFlags: TestFeatureFlags(),
androidSdk: androidSdk,
......@@ -84,8 +76,8 @@ void main() {
});
testWithoutContext('licensesAccepted returns LicensesAccepted.unknown if cannot find sdkmanager', () async {
processManager.canRunSucceeds = false;
when(sdk.sdkManagerPath).thenReturn('/foo/bar/sdkmanager');
sdk.sdkManagerPath = '/foo/bar/sdkmanager';
processManager.excludedExecutables.add('/foo/bar/sdkmanager');
final AndroidLicenseValidator licenseValidator = AndroidLicenseValidator(
androidSdk: sdk,
fileSystem: fileSystem,
......@@ -103,8 +95,8 @@ void main() {
});
testWithoutContext('licensesAccepted returns LicensesAccepted.unknown if cannot run sdkmanager', () async {
processManager.runSucceeds = false;
when(sdk.sdkManagerPath).thenReturn('/foo/bar/sdkmanager');
sdk.sdkManagerPath = '/foo/bar/sdkmanager';
processManager.excludedExecutables.add('/foo/bar/sdkmanager');
final AndroidLicenseValidator licenseValidator = AndroidLicenseValidator(
androidSdk: sdk,
fileSystem: fileSystem,
......@@ -122,7 +114,13 @@ void main() {
});
testWithoutContext('licensesAccepted handles garbage/no output', () async {
when(sdk.sdkManagerPath).thenReturn('/foo/bar/sdkmanager');
sdk.sdkManagerPath = '/foo/bar/sdkmanager';
processManager.addCommand(const FakeCommand(
command: <String>[
'/foo/bar/sdkmanager',
'--licenses',
], stdout: 'asdasassad',
));
final AndroidLicenseValidator licenseValidator = AndroidLicenseValidator(
androidSdk: sdk,
fileSystem: fileSystem,
......@@ -136,17 +134,21 @@ void main() {
);
final LicensesAccepted result = await licenseValidator.licensesAccepted;
expect(result, equals(LicensesAccepted.unknown));
expect(processManager.commands.first, equals('/foo/bar/sdkmanager'));
expect(processManager.commands.last, equals('--licenses'));
expect(result, LicensesAccepted.unknown);
});
testWithoutContext('licensesAccepted works for all licenses accepted', () async {
when(sdk.sdkManagerPath).thenReturn('/foo/bar/sdkmanager');
processManager.processFactory = processMetaFactory(<String>[
'[=======================================] 100% Computing updates... ',
'All SDK package licenses accepted.',
]);
sdk.sdkManagerPath = '/foo/bar/sdkmanager';
const String output = '''
[=======================================] 100% Computing updates...
All SDK package licenses accepted.
''';
processManager.addCommand(const FakeCommand(
command: <String>[
'/foo/bar/sdkmanager',
'--licenses',
], stdout: output,
));
final AndroidLicenseValidator licenseValidator = AndroidLicenseValidator(
androidSdk: sdk,
......@@ -161,16 +163,22 @@ void main() {
);
final LicensesAccepted result = await licenseValidator.licensesAccepted;
expect(result, equals(LicensesAccepted.all));
expect(result, LicensesAccepted.all);
});
testWithoutContext('licensesAccepted works for some licenses accepted', () async {
when(sdk.sdkManagerPath).thenReturn('/foo/bar/sdkmanager');
processManager.processFactory = processMetaFactory(<String>[
'[=======================================] 100% Computing updates... ',
'2 of 5 SDK package licenses not accepted.',
'Review licenses that have not been accepted (y/N)?',
]);
sdk.sdkManagerPath = '/foo/bar/sdkmanager';
const String output = '''
[=======================================] 100% Computing updates...
2 of 5 SDK package licenses not accepted.
Review licenses that have not been accepted (y/N)?
''';
processManager.addCommand(const FakeCommand(
command: <String>[
'/foo/bar/sdkmanager',
'--licenses',
], stdout: output,
));
final AndroidLicenseValidator licenseValidator = AndroidLicenseValidator(
androidSdk: sdk,
......@@ -185,16 +193,22 @@ void main() {
);
final LicensesAccepted result = await licenseValidator.licensesAccepted;
expect(result, equals(LicensesAccepted.some));
expect(result, LicensesAccepted.some);
});
testWithoutContext('licensesAccepted works for no licenses accepted', () async {
when(sdk.sdkManagerPath).thenReturn('/foo/bar/sdkmanager');
processManager.processFactory = processMetaFactory(<String>[
'[=======================================] 100% Computing updates... ',
'5 of 5 SDK package licenses not accepted.',
'Review licenses that have not been accepted (y/N)?',
]);
sdk.sdkManagerPath = '/foo/bar/sdkmanager';
const String output = '''
[=======================================] 100% Computing updates...
5 of 5 SDK package licenses not accepted.
Review licenses that have not been accepted (y/N)?
''';
processManager.addCommand(const FakeCommand(
command: <String>[
'/foo/bar/sdkmanager',
'--licenses',
], stdout: output,
));
final AndroidLicenseValidator licenseValidator = AndroidLicenseValidator(
androidSdk: sdk,
......@@ -209,12 +223,18 @@ void main() {
);
final LicensesAccepted result = await licenseValidator.licensesAccepted;
expect(result, equals(LicensesAccepted.none));
expect(result, LicensesAccepted.none);
});
testWithoutContext('runLicenseManager succeeds for version >= 26', () async {
when(sdk.sdkManagerPath).thenReturn('/foo/bar/sdkmanager');
when(sdk.sdkManagerVersion).thenReturn('26.0.0');
sdk.sdkManagerPath = '/foo/bar/sdkmanager';
sdk.sdkManagerVersion = '26.0.0';
processManager.addCommand(const FakeCommand(
command: <String>[
'/foo/bar/sdkmanager',
'--licenses',
], stdout: '',
));
final AndroidLicenseValidator licenseValidator = AndroidLicenseValidator(
androidSdk: sdk,
......@@ -232,8 +252,8 @@ void main() {
});
testWithoutContext('runLicenseManager errors when sdkmanager is not found', () async {
when(sdk.sdkManagerPath).thenReturn('/foo/bar/sdkmanager');
processManager.canRunSucceeds = false;
sdk.sdkManagerPath = '/foo/bar/sdkmanager';
processManager.excludedExecutables.add('/foo/bar/sdkmanager');
final AndroidLicenseValidator licenseValidator = AndroidLicenseValidator(
androidSdk: sdk,
......@@ -251,8 +271,8 @@ void main() {
});
testWithoutContext('runLicenseManager errors when sdkmanager fails to run', () async {
when(sdk.sdkManagerPath).thenReturn('/foo/bar/sdkmanager');
processManager.runSucceeds = false;
sdk.sdkManagerPath = '/foo/bar/sdkmanager';
processManager.excludedExecutables.add('/foo/bar/sdkmanager');
final AndroidLicenseValidator licenseValidator = AndroidLicenseValidator(
androidSdk: sdk,
......@@ -270,8 +290,8 @@ void main() {
});
testWithoutContext('detects license-only SDK installation', () async {
when(sdk.licensesAvailable).thenReturn(true);
when(sdk.platformToolsAvailable).thenReturn(false);
sdk.licensesAvailable = true;
sdk.platformToolsAvailable = false;
final ValidationResult validationResult = await AndroidValidator(
androidStudio: null,
androidSdk: sdk,
......@@ -281,6 +301,7 @@ void main() {
platform: FakePlatform()..environment = <String, String>{'HOME': '/home/me'},
userMessages: UserMessages(),
).validate();
expect(validationResult.type, ValidationType.partial);
expect(
validationResult.messages.last.message,
......@@ -289,18 +310,24 @@ void main() {
});
testWithoutContext('detects minimum required SDK and buildtools', () async {
final AndroidSdkVersion mockSdkVersion = MockAndroidSdkVersion();
when(sdk.licensesAvailable).thenReturn(true);
when(sdk.platformToolsAvailable).thenReturn(true);
processManager.addCommand(const FakeCommand(
command: <String>[
'which',
'java',
], exitCode: 1,
));
final FakeAndroidSdkVersion sdkVersion = FakeAndroidSdkVersion()
..sdkLevel = 28
..buildToolsVersion = Version(26, 0, 3);
sdk
..licensesAvailable = true
..platformToolsAvailable = true
// Test with invalid SDK and build tools
when(mockSdkVersion.sdkLevel).thenReturn(28);
when(mockSdkVersion.buildToolsVersion).thenReturn(Version(26, 0, 3));
when(sdk.directory).thenReturn(fileSystem.directory('/foo/bar'));
when(sdk.sdkManagerPath).thenReturn('/foo/bar/sdkmanager');
when(sdk.latestVersion).thenReturn(mockSdkVersion);
when(sdk.validateSdkWellFormed()).thenReturn(<String>[]);
when(processManager.runSync(<String>['which', 'java'])).thenReturn(ProcessResult(123, 1, '', ''));
..directory = fileSystem.directory('/foo/bar')
..sdkManagerPath = '/foo/bar/sdkmanager'
..latestVersion = sdkVersion;
final String errorMessage = UserMessages().androidSdkBuildToolsOutdated(
sdk.sdkManagerPath,
kAndroidSdkMinVersion,
......@@ -326,8 +353,8 @@ void main() {
);
// Test with valid SDK but invalid build tools
when(mockSdkVersion.sdkLevel).thenReturn(29);
when(mockSdkVersion.buildToolsVersion).thenReturn(Version(28, 0, 2));
sdkVersion.sdkLevel = 29;
sdkVersion.buildToolsVersion = Version(28, 0, 2);
validationResult = await androidValidator.validate();
expect(validationResult.type, ValidationType.missing);
......@@ -338,8 +365,8 @@ void main() {
// Test with valid SDK and valid build tools
// Will still be partial because AnroidSdk.findJavaBinary is static :(
when(mockSdkVersion.sdkLevel).thenReturn(kAndroidSdkMinVersion);
when(mockSdkVersion.buildToolsVersion).thenReturn(kAndroidSdkBuildToolsMinVersion);
sdkVersion.sdkLevel = kAndroidSdkMinVersion;
sdkVersion.buildToolsVersion = kAndroidSdkBuildToolsMinVersion;
validationResult = await androidValidator.validate();
expect(validationResult.type, ValidationType.partial); // No Java binary
......@@ -350,22 +377,26 @@ void main() {
});
testWithoutContext('detects minimum required java version', () async {
final AndroidSdkVersion mockSdkVersion = MockAndroidSdkVersion();
// Test with older version of JDK
const String javaVersionText = 'openjdk version "1.7.0_212"';
processManager.addCommand(const FakeCommand(
command: <String>[
'home/java/bin/java',
'-version',
], stderr: javaVersionText,
));
final FakeAndroidSdkVersion sdkVersion = FakeAndroidSdkVersion()
..sdkLevel = 29
..buildToolsVersion = Version(28, 0, 3);
// Mock a pass through scenario to reach _checkJavaVersion()
when(sdk.licensesAvailable).thenReturn(true);
when(sdk.platformToolsAvailable).thenReturn(true);
when(mockSdkVersion.sdkLevel).thenReturn(29);
when(mockSdkVersion.buildToolsVersion).thenReturn(Version(28, 0, 3));
when(sdk.directory).thenReturn(fileSystem.directory('/foo/bar'));
when(sdk.sdkManagerPath).thenReturn('/foo/bar/sdkmanager');
when(sdk.latestVersion).thenReturn(mockSdkVersion);
when(sdk.validateSdkWellFormed()).thenReturn(<String>[]);
//Test with older version of JDK
const String javaVersionText = 'openjdk version "1.7.0_212"';
when(processManager.run(argThat(contains('-version')))).thenAnswer((_) =>
Future<ProcessResult>.value(ProcessResult(0, 0, null, javaVersionText)));
sdk
..licensesAvailable = true
..platformToolsAvailable = true
..directory = fileSystem.directory('/foo/bar')
..sdkManagerPath = '/foo/bar/sdkmanager';
sdk.latestVersion = sdkVersion;
final String errorMessage = UserMessages().androidJavaMinimumVersion(javaVersionText);
final ValidationResult validationResult = await AndroidValidator(
......@@ -410,6 +441,49 @@ void main() {
});
}
class FakeAndroidSdk extends Fake implements AndroidSdk {
@override
String sdkManagerPath;
@override
String sdkManagerVersion;
@override
String adbPath;
@override
bool licensesAvailable;
@override
bool platformToolsAvailable;
@override
Directory directory;
@override
AndroidSdkVersion latestVersion;
@override
List<String> validateSdkWellFormed() => <String>[];
@override
Map<String, String> get sdkManagerEnv => <String, String>{};
}
class FakeAndroidSdkVersion extends Fake implements AndroidSdkVersion {
@override
int sdkLevel;
@override
Version buildToolsVersion;
@override
String get buildToolsVersionName => '';
@override
String get platformName => '';
}
class CustomFakeOperatingSystemUtils extends Fake implements OperatingSystemUtils {
CustomFakeOperatingSystemUtils({
HostPlatform hostPlatform = HostPlatform.linux_x64
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment