| // 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. |
| |
| // @dart = 2.8 |
| |
| import 'dart:io' as io show ProcessSignal; |
| |
| import 'package:file/file.dart'; |
| import 'package:flutter_tools/src/base/file_system.dart'; |
| import 'package:flutter_tools/src/base/io.dart'; |
| import 'package:flutter_tools/src/base/logger.dart'; |
| import 'package:flutter_tools/src/base/terminal.dart'; |
| import 'package:flutter_tools/src/cache.dart'; |
| import 'package:process/process.dart'; |
| |
| import '../src/common.dart'; |
| import '../src/context.dart'; |
| import 'test_utils.dart'; |
| |
| final String dart = fileSystem.path |
| .join(getFlutterRoot(), 'bin', platform.isWindows ? 'dart.bat' : 'dart'); |
| |
| void main() { |
| group('Cache.lock', () { |
| // Windows locking is too flaky for this to work reliably. |
| if (!platform.isWindows) { |
| testWithoutContext( |
| 'should log a message to stderr when lock is not acquired', () async { |
| final String oldRoot = Cache.flutterRoot; |
| final Directory tempDir = fileSystem.systemTempDirectory.createTempSync('cache_test.'); |
| final BufferLogger logger = BufferLogger( |
| terminal: Terminal.test(supportsColor: false, supportsEmoji: false), |
| outputPreferences: OutputPreferences(), |
| ); |
| try { |
| Cache.flutterRoot = tempDir.absolute.path; |
| final Cache cache = Cache.test( |
| fileSystem: fileSystem, |
| processManager: FakeProcessManager.any(), |
| logger: logger, |
| ); |
| final File cacheFile = fileSystem.file(fileSystem.path |
| .join(Cache.flutterRoot, 'bin', 'cache', 'lockfile')) |
| ..createSync(recursive: true); |
| final File script = fileSystem.file(fileSystem.path |
| .join(Cache.flutterRoot, 'bin', 'cache', 'test_lock.dart')); |
| script.writeAsStringSync(r''' |
| import 'dart:async'; |
| import 'dart:io'; |
| |
| Future<void> main(List<String> args) async { |
| File file = File(args[0]); |
| RandomAccessFile lock = file.openSync(mode: FileMode.write); |
| lock.lockSync(); |
| await Future<void>.delayed(const Duration(milliseconds: 1000)); |
| exit(0); |
| } |
| '''); |
| final Process process = await const LocalProcessManager().start( |
| <String>[dart, script.absolute.path, cacheFile.absolute.path], |
| ); |
| await Future<void>.delayed(const Duration(milliseconds: 500)); |
| await cache.lock(); |
| process.kill(io.ProcessSignal.sigkill); |
| } finally { |
| tryToDelete(tempDir); |
| Cache.flutterRoot = oldRoot; |
| } |
| expect(logger.statusText, isEmpty); |
| expect(logger.errorText, |
| equals('Waiting for another flutter command to release the startup lock...\n')); |
| }); |
| } |
| }); |
| } |