| // 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:file/file.dart'; |
| import 'package:file/local.dart'; |
| import 'package:flutter_tools/src/base/io.dart'; |
| import 'package:flutter_tools/src/base/platform.dart'; |
| import 'package:process/process.dart'; |
| import 'package:vm_service/vm_service.dart'; |
| |
| import '../src/common.dart'; |
| import 'test_driver.dart'; |
| |
| /// The [FileSystem] for the integration test environment. |
| const FileSystem fileSystem = LocalFileSystem(); |
| |
| /// The [Platform] for the integration test environment. |
| const Platform platform = LocalPlatform(); |
| |
| /// The [ProcessManager] for the integration test environment. |
| const ProcessManager processManager = LocalProcessManager(); |
| |
| /// Creates a temporary directory but resolves any symlinks to return the real |
| /// underlying path to avoid issues with breakpoints/hot reload. |
| /// https://github.com/flutter/flutter/pull/21741 |
| Directory createResolvedTempDirectorySync(String prefix) { |
| assert(prefix.endsWith('.')); |
| final Directory tempDirectory = fileSystem.systemTempDirectory.createTempSync('flutter_$prefix'); |
| return fileSystem.directory(tempDirectory.resolveSymbolicLinksSync()); |
| } |
| |
| void writeFile(String path, String content, {bool writeFutureModifiedDate = false}) { |
| final File file = fileSystem.file(path) |
| ..createSync(recursive: true) |
| ..writeAsStringSync(content, flush: true); |
| // Some integration tests on Windows to not see this file as being modified |
| // recently enough for the hot reload to pick this change up unless the |
| // modified time is written in the future. |
| if (writeFutureModifiedDate) { |
| file.setLastModifiedSync(DateTime.now().add(const Duration(seconds: 5))); |
| } |
| } |
| |
| void writeBytesFile(String path, List<int> content) { |
| fileSystem.file(path) |
| ..createSync(recursive: true) |
| ..writeAsBytesSync(content); |
| } |
| |
| void writePackages(String folder) { |
| writeFile(fileSystem.path.join(folder, '.packages'), ''' |
| test:${fileSystem.path.join(fileSystem.currentDirectory.path, 'lib')}/ |
| '''); |
| } |
| |
| Future<void> getPackages(String folder) async { |
| final List<String> command = <String>[ |
| fileSystem.path.join(getFlutterRoot(), 'bin', 'flutter'), |
| 'pub', |
| 'get', |
| ]; |
| final ProcessResult result = await processManager.run(command, workingDirectory: folder); |
| if (result.exitCode != 0) { |
| throw Exception('flutter pub get failed: ${result.stderr}\n${result.stdout}'); |
| } |
| } |
| |
| const String kLocalEngineEnvironment = 'FLUTTER_LOCAL_ENGINE'; |
| const String kLocalEngineLocation = 'FLUTTER_LOCAL_ENGINE_SRC_PATH'; |
| |
| List<String> getLocalEngineArguments() { |
| return <String>[ |
| if (platform.environment.containsKey(kLocalEngineEnvironment)) |
| '--local-engine=${platform.environment[kLocalEngineEnvironment]}', |
| if (platform.environment.containsKey(kLocalEngineLocation)) |
| '--local-engine-src-path=${platform.environment[kLocalEngineLocation]}', |
| ]; |
| } |
| |
| Future<void> pollForServiceExtensionValue<T>({ |
| required FlutterTestDriver testDriver, |
| required String extension, |
| required T continuePollingValue, |
| required Matcher matches, |
| String valueKey = 'value', |
| }) async { |
| for (int i = 0; i < 10; i++) { |
| final Response response = await testDriver.callServiceExtension(extension); |
| if (response.json?[valueKey] as T == continuePollingValue) { |
| await Future<void>.delayed(const Duration(seconds: 1)); |
| } else { |
| expect(response.json?[valueKey] as T, matches); |
| return; |
| } |
| } |
| fail( |
| "Did not find expected value for service extension '$extension'. All call" |
| " attempts responded with '$continuePollingValue'.", |
| ); |
| } |
| |
| class AppleTestUtils { |
| // static only |
| AppleTestUtils._(); |
| |
| static const List<String> requiredSymbols = <String>[ |
| '_kDartIsolateSnapshotData', |
| '_kDartIsolateSnapshotInstructions', |
| '_kDartVmSnapshotData', |
| '_kDartVmSnapshotInstructions' |
| ]; |
| |
| static List<String> getExportedSymbols(String dwarfPath) { |
| final ProcessResult nm = processManager.runSync( |
| <String>[ |
| 'nm', |
| '--debug-syms', // nm docs: 'Show all symbols, even debugger only' |
| '--defined-only', |
| '--just-symbol-name', |
| dwarfPath, |
| '-arch', |
| 'arm64', |
| ], |
| ); |
| final String nmOutput = (nm.stdout as String).trim(); |
| return nmOutput.isEmpty ? const <String>[] : nmOutput.split('\n'); |
| } |
| } |