Add timeout to tar command and exit if it doesn't succeed. (#156)

* Add timeout to tar command and exit if it doesn't succeed.

Also remove the verbose option of the tar file to improve speed.

Bug:
  https://github.com/flutter/flutter/issues/57176

* Add tests and reduce timeout to 5 mins.
This commit is contained in:
godofredoc
2020-05-14 08:23:15 -07:00
committed by GitHub
parent c41258ea35
commit 5ca63a2879
4 changed files with 57 additions and 7 deletions

View File

@ -262,7 +262,12 @@ Future<OperationResult> pushPackages(
stdout.writeln('Untaring $repoArchive to ${repo.path}');
repo.createSync(recursive: true);
await tar.untar(repoArchive, repo.path);
final OperationResult result = await tar.untar(repoArchive, repo.path);
if (!result.success) {
stdout.writeln(
'Error untarring $repoArchive \nstdout: ${result.info} \nstderr: ${result.error}');
exit(-1);
}
final String repositoryBase = path.join(repo.path, 'amber-files');
stdout.writeln('Serving $repositoryBase to $targetIp');

View File

@ -17,7 +17,11 @@ abstract class Tar {
const Tar();
/// Untars a tar file.
Future<OperationResult> untar(String src, String destination);
Future<OperationResult> untar(
String src,
String destination, {
Duration timeoutMs,
});
}
/// The archive package is very slow and memory intensive. Use
@ -35,16 +39,21 @@ class SystemTar implements Tar {
/// program.
final ProcessManager processManager;
/// The default timeout for untar operations as [Duration] in milliseconds.
static const Duration defaultTarTimeoutMs =
Duration(milliseconds: 5 * 60 * 1000);
@override
Future<OperationResult> untar(
String src,
String destination,
) async {
String destination, {
Duration timeoutMs = defaultTarTimeoutMs,
}) async {
final ProcessResult result = await processManager.run(<String>[
'tar',
'-xvf', src, //
'-xf', src, //
'-C', destination,
]);
]).timeout(timeoutMs);
return OperationResult.fromProcessResult(result);
}

View File

@ -158,7 +158,8 @@ class FakeTar implements Tar {
final MemoryFileSystem fs;
@override
Future<OperationResult> untar(String src, String destination) async {
Future<OperationResult> untar(String src, String destination,
{Duration timeoutMs}) async {
if (passes) {
final Directory dir = fs.directory(destination)
..createSync(recursive: true);

View File

@ -0,0 +1,35 @@
// Copyright 2020 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:async';
import 'dart:io';
import 'package:process/process.dart';
import 'package:test/test.dart';
import 'package:fuchsia_ctl/src/tar.dart';
import 'package:mockito/mockito.dart';
void main() {
group('Tar', () {
test('Untar file times out', () async {
final MockProcessManager processManager = MockProcessManager();
when(processManager.run(any)).thenAnswer((_) async {
await Future<void>.delayed(const Duration(milliseconds: 3));
return ProcessResult(0, 0, 'Good job', '');
});
final Tar tar = SystemTar(processManager: processManager);
expect(
tar.untar(
'source.tar',
'/destination',
timeoutMs: const Duration(milliseconds: 1),
),
throwsA(const TypeMatcher<TimeoutException>()));
});
});
}
class MockProcessManager extends Mock implements ProcessManager {}