| // 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 'package:flutter_tools/src/base/user_messages.dart'; |
| import 'package:flutter_tools/src/doctor.dart'; |
| import 'package:flutter_tools/src/linux/linux_doctor.dart'; |
| import 'package:process/process.dart'; |
| |
| import '../../src/common.dart'; |
| import '../../src/context.dart'; |
| |
| // A command that will return typical-looking 'clang++ --version' output with |
| // the given version number. |
| FakeCommand _clangPresentCommand(String version) { |
| return FakeCommand( |
| command: const <String>['clang++', '--version'], |
| stdout: ''' |
| clang version $version-6+build1 |
| Target: x86_64-pc-linux-gnu |
| Thread model: posix |
| InstalledDir: /usr/bin |
| ''', |
| ); |
| } |
| |
| // A command that will return typical-looking 'cmake --version' output with the |
| // given version number. |
| FakeCommand _cmakePresentCommand(String version) { |
| return FakeCommand( |
| command: const <String>['cmake', '--version'], |
| stdout: ''' |
| cmake version $version |
| |
| CMake suite maintained and supported by Kitware (kitware.com/cmake). |
| ''', |
| ); |
| } |
| |
| // A command that will return typical-looking 'ninja --version' output with the |
| // given version number. |
| FakeCommand _ninjaPresentCommand(String version) { |
| return FakeCommand( |
| command: const <String>['ninja', '--version'], |
| stdout: version, |
| ); |
| } |
| |
| // A command that will return typical-looking 'pgk-config --version' output with |
| // the given version number. |
| FakeCommand _pkgConfigPresentCommand(String version) { |
| return FakeCommand( |
| command: const <String>['pkg-config', '--version'], |
| stdout: version, |
| ); |
| } |
| |
| /// A command that returns either success or failure for a pkg-config query |
| /// for [library], depending on [exists]. |
| FakeCommand _libraryCheckCommand(String library, {bool exists = true}) { |
| return FakeCommand( |
| command: <String>['pkg-config', '--exists', library], |
| exitCode: exists ? 0 : 1, |
| ); |
| } |
| |
| // Commands that give positive replies for all the GTK library pkg-config queries. |
| List<FakeCommand> _gtkLibrariesPresentCommands() { |
| return <FakeCommand>[ |
| _libraryCheckCommand('gtk+-3.0'), |
| _libraryCheckCommand('glib-2.0'), |
| _libraryCheckCommand('gio-2.0'), |
| ]; |
| } |
| |
| // Commands that give some failures for the GTK library pkg-config queries. |
| List<FakeCommand> _gtkLibrariesMissingCommands() { |
| return <FakeCommand>[ |
| _libraryCheckCommand('gtk+-3.0'), |
| _libraryCheckCommand('glib-2.0', exists: false), |
| // No more entries, since the first missing GTK library stops the |
| // checks. |
| ]; |
| } |
| |
| // A command that will failure when running '[binary] --version'. |
| FakeCommand _missingBinaryCommand(String binary) { |
| return FakeCommand( |
| command: <String>[binary, '--version'], |
| exitCode: 1, |
| ); |
| } |
| |
| void main() { |
| testWithoutContext('Full validation when everything is available at the necessary version',() async { |
| final ProcessManager processManager = FakeProcessManager.list(<FakeCommand>[ |
| _clangPresentCommand('4.0.1'), |
| _cmakePresentCommand('3.16.3'), |
| _ninjaPresentCommand('1.10.0'), |
| _pkgConfigPresentCommand('0.29'), |
| ..._gtkLibrariesPresentCommands(), |
| _libraryCheckCommand('blkid'), |
| ]); |
| final DoctorValidator linuxDoctorValidator = LinuxDoctorValidator( |
| processManager: processManager, |
| userMessages: UserMessages(), |
| ); |
| final ValidationResult result = await linuxDoctorValidator.validate(); |
| |
| expect(result.type, ValidationType.installed); |
| expect(result.messages, const <ValidationMessage>[ |
| ValidationMessage('clang version 4.0.1-6+build1'), |
| ValidationMessage('cmake version 3.16.3'), |
| ValidationMessage('ninja version 1.10.0'), |
| ValidationMessage('pkg-config version 0.29'), |
| ]); |
| }); |
| |
| testWithoutContext('Partial validation when clang++ version is too old', () async { |
| final ProcessManager processManager = FakeProcessManager.list(<FakeCommand>[ |
| _clangPresentCommand('2.0.1'), |
| _cmakePresentCommand('3.16.3'), |
| _ninjaPresentCommand('1.10.0'), |
| _pkgConfigPresentCommand('0.29'), |
| ..._gtkLibrariesPresentCommands(), |
| _libraryCheckCommand('blkid'), |
| ]); |
| final DoctorValidator linuxDoctorValidator = LinuxDoctorValidator( |
| processManager: processManager, |
| userMessages: UserMessages(), |
| ); |
| final ValidationResult result = await linuxDoctorValidator.validate(); |
| |
| expect(result.type, ValidationType.partial); |
| expect(result.messages, const <ValidationMessage>[ |
| ValidationMessage('clang version 2.0.1-6+build1'), |
| ValidationMessage.error('clang++ 3.4.0 or later is required.'), |
| ValidationMessage('cmake version 3.16.3'), |
| ValidationMessage('ninja version 1.10.0'), |
| ValidationMessage('pkg-config version 0.29'), |
| ]); |
| }); |
| |
| testWithoutContext('Partial validation when CMake version is too old', () async { |
| final ProcessManager processManager = FakeProcessManager.list(<FakeCommand>[ |
| _clangPresentCommand('4.0.1'), |
| _cmakePresentCommand('3.2.0'), |
| _ninjaPresentCommand('1.10.0'), |
| _pkgConfigPresentCommand('0.29'), |
| ..._gtkLibrariesPresentCommands(), |
| _libraryCheckCommand('blkid'), |
| ]); |
| final DoctorValidator linuxDoctorValidator = LinuxDoctorValidator( |
| processManager: processManager, |
| userMessages: UserMessages(), |
| ); |
| final ValidationResult result = await linuxDoctorValidator.validate(); |
| |
| expect(result.type, ValidationType.partial); |
| expect(result.messages, const <ValidationMessage>[ |
| ValidationMessage('clang version 4.0.1-6+build1'), |
| ValidationMessage('cmake version 3.2.0'), |
| ValidationMessage.error('cmake 3.10.0 or later is required.'), |
| ValidationMessage('ninja version 1.10.0'), |
| ValidationMessage('pkg-config version 0.29'), |
| ]); |
| }); |
| |
| testWithoutContext('Partial validation when ninja version is too old', () async { |
| final ProcessManager processManager = FakeProcessManager.list(<FakeCommand>[ |
| _clangPresentCommand('4.0.1'), |
| _cmakePresentCommand('3.16.3'), |
| _ninjaPresentCommand('0.8.1'), |
| _pkgConfigPresentCommand('0.29'), |
| ..._gtkLibrariesPresentCommands(), |
| _libraryCheckCommand('blkid'), |
| ]); |
| final DoctorValidator linuxDoctorValidator = LinuxDoctorValidator( |
| processManager: processManager, |
| userMessages: UserMessages(), |
| ); |
| final ValidationResult result = await linuxDoctorValidator.validate(); |
| |
| expect(result.type, ValidationType.partial); |
| expect(result.messages, const <ValidationMessage>[ |
| ValidationMessage('clang version 4.0.1-6+build1'), |
| ValidationMessage('cmake version 3.16.3'), |
| ValidationMessage('ninja version 0.8.1'), |
| ValidationMessage.error('ninja 1.8.0 or later is required.'), |
| ValidationMessage('pkg-config version 0.29'), |
| ]); |
| }); |
| |
| testWithoutContext('Partial validation when pkg-config version is too old', () async { |
| final ProcessManager processManager = FakeProcessManager.list(<FakeCommand>[ |
| _clangPresentCommand('4.0.1'), |
| _cmakePresentCommand('3.16.3'), |
| _ninjaPresentCommand('1.10.0'), |
| _pkgConfigPresentCommand('0.27.0'), |
| ..._gtkLibrariesPresentCommands(), |
| _libraryCheckCommand('blkid'), |
| ]); |
| final DoctorValidator linuxDoctorValidator = LinuxDoctorValidator( |
| processManager: processManager, |
| userMessages: UserMessages(), |
| ); |
| final ValidationResult result = await linuxDoctorValidator.validate(); |
| |
| expect(result.type, ValidationType.partial); |
| expect(result.messages, const <ValidationMessage>[ |
| ValidationMessage('clang version 4.0.1-6+build1'), |
| ValidationMessage('cmake version 3.16.3'), |
| ValidationMessage('ninja version 1.10.0'), |
| ValidationMessage('pkg-config version 0.27.0'), |
| ValidationMessage.error('pkg-config 0.29.0 or later is required.'), |
| ]); |
| }); |
| |
| testWithoutContext('Missing validation when CMake is not available', () async { |
| final ProcessManager processManager = FakeProcessManager.list(<FakeCommand>[ |
| _clangPresentCommand('4.0.1'), |
| _missingBinaryCommand('cmake'), |
| _ninjaPresentCommand('1.10.0'), |
| _pkgConfigPresentCommand('0.29'), |
| ..._gtkLibrariesPresentCommands(), |
| _libraryCheckCommand('blkid'), |
| ]); |
| final UserMessages userMessages = UserMessages(); |
| final DoctorValidator linuxDoctorValidator = LinuxDoctorValidator( |
| processManager: processManager, |
| userMessages: userMessages, |
| ); |
| final ValidationResult result = await linuxDoctorValidator.validate(); |
| |
| expect(result.type, ValidationType.missing); |
| expect(result.messages, <ValidationMessage>[ |
| const ValidationMessage('clang version 4.0.1-6+build1'), |
| ValidationMessage.error(userMessages.cmakeMissing), |
| const ValidationMessage('ninja version 1.10.0'), |
| const ValidationMessage('pkg-config version 0.29'), |
| ]); |
| }); |
| |
| testWithoutContext('Missing validation when clang++ is not available', () async { |
| final ProcessManager processManager = FakeProcessManager.list(<FakeCommand>[ |
| _missingBinaryCommand('clang++'), |
| _cmakePresentCommand('3.16.3'), |
| _ninjaPresentCommand('1.10.0'), |
| _pkgConfigPresentCommand('0.29'), |
| ..._gtkLibrariesPresentCommands(), |
| _libraryCheckCommand('blkid'), |
| ]); |
| final UserMessages userMessages = UserMessages(); |
| final DoctorValidator linuxDoctorValidator = LinuxDoctorValidator( |
| processManager: processManager, |
| userMessages: userMessages, |
| ); |
| final ValidationResult result = await linuxDoctorValidator.validate(); |
| |
| expect(result.type, ValidationType.missing); |
| expect(result.messages, <ValidationMessage>[ |
| ValidationMessage.error(userMessages.clangMissing), |
| const ValidationMessage('cmake version 3.16.3'), |
| const ValidationMessage('ninja version 1.10.0'), |
| const ValidationMessage('pkg-config version 0.29'), |
| ]); |
| }); |
| |
| testWithoutContext('Missing validation when ninja is not available', () async { |
| final ProcessManager processManager = FakeProcessManager.list(<FakeCommand>[ |
| _clangPresentCommand('4.0.1'), |
| _cmakePresentCommand('3.16.3'), |
| _missingBinaryCommand('ninja'), |
| _pkgConfigPresentCommand('0.29'), |
| ..._gtkLibrariesPresentCommands(), |
| _libraryCheckCommand('blkid'), |
| ]); |
| final UserMessages userMessages = UserMessages(); |
| final DoctorValidator linuxDoctorValidator = LinuxDoctorValidator( |
| processManager: processManager, |
| userMessages: userMessages, |
| ); |
| final ValidationResult result = await linuxDoctorValidator.validate(); |
| |
| expect(result.type, ValidationType.missing); |
| expect(result.messages, <ValidationMessage>[ |
| const ValidationMessage('clang version 4.0.1-6+build1'), |
| const ValidationMessage('cmake version 3.16.3'), |
| ValidationMessage.error(userMessages.ninjaMissing), |
| const ValidationMessage('pkg-config version 0.29'), |
| ]); |
| }); |
| |
| testWithoutContext('Missing validation when pkg-config is not available', () async { |
| final ProcessManager processManager = FakeProcessManager.list(<FakeCommand>[ |
| _clangPresentCommand('4.0.1'), |
| _cmakePresentCommand('3.16.3'), |
| _ninjaPresentCommand('1.10.0'), |
| _missingBinaryCommand('pkg-config'), |
| ..._gtkLibrariesPresentCommands(), |
| _libraryCheckCommand('blkid'), |
| ]); |
| final UserMessages userMessages = UserMessages(); |
| final DoctorValidator linuxDoctorValidator = LinuxDoctorValidator( |
| processManager: processManager, |
| userMessages: userMessages, |
| ); |
| final ValidationResult result = await linuxDoctorValidator.validate(); |
| |
| expect(result.type, ValidationType.missing); |
| expect(result.messages, <ValidationMessage>[ |
| const ValidationMessage('clang version 4.0.1-6+build1'), |
| const ValidationMessage('cmake version 3.16.3'), |
| const ValidationMessage('ninja version 1.10.0'), |
| ValidationMessage.error(userMessages.pkgConfigMissing), |
| ]); |
| }); |
| |
| testWithoutContext('Missing validation when GTK libraries are not available', () async { |
| final ProcessManager processManager = FakeProcessManager.list(<FakeCommand>[ |
| _clangPresentCommand('4.0.1'), |
| _cmakePresentCommand('3.16.3'), |
| _ninjaPresentCommand('1.10.0'), |
| _pkgConfigPresentCommand('0.29'), |
| ..._gtkLibrariesMissingCommands(), |
| _libraryCheckCommand('blkid'), |
| ]); |
| final UserMessages userMessages = UserMessages(); |
| final DoctorValidator linuxDoctorValidator = LinuxDoctorValidator( |
| processManager: processManager, |
| userMessages: userMessages, |
| ); |
| final ValidationResult result = await linuxDoctorValidator.validate(); |
| |
| expect(result.type, ValidationType.missing); |
| expect(result.messages, <ValidationMessage>[ |
| const ValidationMessage('clang version 4.0.1-6+build1'), |
| const ValidationMessage('cmake version 3.16.3'), |
| const ValidationMessage('ninja version 1.10.0'), |
| const ValidationMessage('pkg-config version 0.29'), |
| ValidationMessage.error(userMessages.gtkLibrariesMissing), |
| ]); |
| }); |
| |
| testWithoutContext('Missing validation when libraries are not available', () async { |
| final ProcessManager processManager = FakeProcessManager.list(<FakeCommand>[ |
| _clangPresentCommand('4.0.1'), |
| _cmakePresentCommand('3.16.3'), |
| _ninjaPresentCommand('1.10.0'), |
| _pkgConfigPresentCommand('0.29'), |
| ..._gtkLibrariesPresentCommands(), |
| _libraryCheckCommand('blkid', exists: false), |
| ]); |
| final UserMessages userMessages = UserMessages(); |
| final DoctorValidator linuxDoctorValidator = LinuxDoctorValidator( |
| processManager: processManager, |
| userMessages: userMessages, |
| ); |
| final ValidationResult result = await linuxDoctorValidator.validate(); |
| |
| expect(result.type, ValidationType.missing); |
| expect(result.messages, <ValidationMessage>[ |
| const ValidationMessage('clang version 4.0.1-6+build1'), |
| const ValidationMessage('cmake version 3.16.3'), |
| const ValidationMessage('ninja version 1.10.0'), |
| const ValidationMessage('pkg-config version 0.29'), |
| ValidationMessage.error(userMessages.blkidLibraryMissing), |
| ]); |
| }); |
| |
| testWithoutContext('Missing validation when multiple dependencies are not available', () async { |
| final ProcessManager processManager = FakeProcessManager.list(<FakeCommand>[ |
| _missingBinaryCommand('clang++'), |
| _missingBinaryCommand('cmake'), |
| _ninjaPresentCommand('1.10.0'), |
| _pkgConfigPresentCommand('0.29'), |
| ..._gtkLibrariesPresentCommands(), |
| _libraryCheckCommand('blkid'), |
| ]); |
| final DoctorValidator linuxDoctorValidator = LinuxDoctorValidator( |
| processManager: processManager, |
| userMessages: UserMessages(), |
| ); |
| |
| final ValidationResult result = await linuxDoctorValidator.validate(); |
| expect(result.type, ValidationType.missing); |
| }); |
| } |