@@ -17,4 +17,77 @@ void main() {
1717 expect (getFileNameFor ('dartdoc.generator' ), 'dartdoc-generator.html' );
1818 });
1919 });
20+
21+ group ('MultiFutureTracker' , () {
22+ /// A special test designed to check shared [MultiFutureTracker]
23+ /// behavior when exceptions occur after a delay in the passed closures to
24+ /// [MultiFutureTracker.addFutureFromClosure] .
25+ test ('no deadlock when delayed exceptions fire in closures' , () async {
26+ var sharedTracker = MultiFutureTracker (2 );
27+ var t =
28+ Future .delayed (Duration (milliseconds: 10 ), () => throw Exception ());
29+ await sharedTracker.addFutureFromClosure (() => t);
30+ expect (t, throwsA (const TypeMatcher <Exception >()));
31+ var u =
32+ Future .delayed (Duration (milliseconds: 10 ), () => throw Exception ());
33+ await sharedTracker.addFutureFromClosure (() => u);
34+ expect (u, throwsA (const TypeMatcher <Exception >()));
35+ var v =
36+ Future .delayed (Duration (milliseconds: 10 ), () => throw Exception ());
37+ await sharedTracker.addFutureFromClosure (() => v);
38+ expect (v, throwsA (const TypeMatcher <Exception >()));
39+
40+ /// We deadlock here if the exception is not handled properly.
41+ await sharedTracker.wait ();
42+ });
43+
44+ test ('basic sequential processing works with no deadlock' , () async {
45+ var completed = < int > {};
46+ var tracker = MultiFutureTracker (1 );
47+ await tracker.addFutureFromClosure (() async => completed.add (1 ));
48+ await tracker.addFutureFromClosure (() async => completed.add (2 ));
49+ await tracker.addFutureFromClosure (() async => completed.add (3 ));
50+ await tracker.wait ();
51+ expect (completed.length, equals (3 ));
52+ });
53+
54+ test ('basic sequential processing works on exceptions' , () async {
55+ var completed = < int > {};
56+ var tracker = MultiFutureTracker (1 );
57+ await tracker.addFutureFromClosure (() async => completed.add (0 ));
58+ await tracker.addFutureFromClosure (() async => throw Exception ());
59+ await tracker.addFutureFromClosure (() async => throw Exception ());
60+ await tracker.addFutureFromClosure (() async => completed.add (3 ));
61+ await tracker.wait ();
62+ expect (completed.length, equals (2 ));
63+ });
64+
65+ /// Verify that if there are more exceptions than the maximum number
66+ /// of in-flight [Future] s that there is no deadlock.
67+ test ('basic parallel processing works with no deadlock' , () async {
68+ var completed = < int > {};
69+ var tracker = MultiFutureTracker (10 );
70+ for (var i = 0 ; i < 100 ; i++ ) {
71+ await tracker.addFutureFromClosure (() async => completed.add (i));
72+ }
73+ await tracker.wait ();
74+ expect (completed.length, equals (100 ));
75+ });
76+
77+ test ('basic parallel processing works on exceptions' , () async {
78+ var completed = < int > {};
79+ var tracker = MultiFutureTracker (10 );
80+ for (var i = 0 ; i < 50 ; i++ ) {
81+ await tracker.addFutureFromClosure (() async => completed.add (i));
82+ }
83+ for (var i = 50 ; i < 65 ; i++ ) {
84+ await tracker.addFutureFromClosure (() async => throw Exception ());
85+ }
86+ for (var i = 65 ; i < 100 ; i++ ) {
87+ await tracker.addFutureFromClosure (() async => completed.add (i));
88+ }
89+ await tracker.wait ();
90+ expect (completed.length, equals (85 ));
91+ });
92+ });
2093}
0 commit comments