@@ -7,6 +7,7 @@ import 'package:flutter_tools/src/android/android_sdk.dart';
7
7
import 'package:flutter_tools/src/android/android_studio.dart' ;
8
8
import 'package:flutter_tools/src/android/android_workflow.dart' ;
9
9
import 'package:flutter_tools/src/base/file_system.dart' ;
10
+ import 'package:flutter_tools/src/base/io.dart' ;
10
11
import 'package:flutter_tools/src/base/logger.dart' ;
11
12
import 'package:flutter_tools/src/base/platform.dart' ;
12
13
import 'package:flutter_tools/src/base/user_messages.dart' ;
@@ -311,6 +312,37 @@ Review licenses that have not been accepted (y/N)?
311
312
expect (licenseValidator.runLicenseManager (), throwsToolExit ());
312
313
});
313
314
315
+ testWithoutContext ('runLicenseManager handles broken pipe without ArgumentError' , () async {
316
+ sdk.sdkManagerPath = '/foo/bar/sdkmanager' ;
317
+ const String exceptionMessage = 'Write failed (OS Error: Broken pipe, errno = 32), port = 0' ;
318
+ const SocketException exception = SocketException (exceptionMessage);
319
+ // By using a `Socket` generic parameter, the stdin.addStream will return a `Future<Socket>`
320
+ // We are testing that our error handling properly handles futures of this type
321
+ final ThrowingStdin <Socket > fakeStdin = ThrowingStdin <Socket >(exception);
322
+ final FakeCommand licenseCommand = FakeCommand (
323
+ command: < String > [sdk.sdkManagerPath! , '--licenses' ],
324
+ stdin: fakeStdin,
325
+ );
326
+ processManager.addCommand (licenseCommand);
327
+ final BufferLogger logger = BufferLogger .test ();
328
+
329
+ final AndroidLicenseValidator licenseValidator = AndroidLicenseValidator (
330
+ androidSdk: sdk,
331
+ fileSystem: fileSystem,
332
+ processManager: processManager,
333
+ platform: FakePlatform (environment: < String , String > {'HOME' : '/home/me' }),
334
+ stdio: stdio,
335
+ logger: logger,
336
+ userMessages: UserMessages (),
337
+ androidStudio: FakeAndroidStudio (),
338
+ operatingSystemUtils: FakeOperatingSystemUtils (),
339
+ );
340
+
341
+ await licenseValidator.runLicenseManager ();
342
+ expect (logger.errorText, contains (exceptionMessage));
343
+ expect (processManager, hasNoRemainingExpectations);
344
+ });
345
+
314
346
testWithoutContext ('runLicenseManager errors when sdkmanager fails to run' , () async {
315
347
sdk.sdkManagerPath = '/foo/bar/sdkmanager' ;
316
348
processManager.excludedExecutables.add ('/foo/bar/sdkmanager' );
@@ -574,3 +606,14 @@ class FakeAndroidStudio extends Fake implements AndroidStudio {
574
606
@override
575
607
String get javaPath => 'java' ;
576
608
}
609
+
610
+ class ThrowingStdin <T > extends Fake implements IOSink {
611
+ ThrowingStdin (this .exception);
612
+
613
+ final Exception exception;
614
+
615
+ @override
616
+ Future <dynamic > addStream (Stream <List <int >> stream) {
617
+ return Future <T >.error (exception);
618
+ }
619
+ }
0 commit comments