1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4 
5 using System.Collections.Generic;
6 using Xunit;
7 
8 namespace System.Linq.Parallel.Tests
9 {
10     public static partial class ParallelQueryCombinationTests
11     {
12         [Theory]
13         [MemberData(nameof(UnaryFailingOperators))]
14         [MemberData(nameof(BinaryFailingOperators))]
Aggregate_AggregateException(Labeled<Operation> source, Labeled<Operation> operation)15         public static void Aggregate_AggregateException(Labeled<Operation> source, Labeled<Operation> operation)
16         {
17             AssertThrows.Wrapped<DeliberateTestException>(() => operation.Item(DefaultStart, DefaultSize, source.Item).Aggregate((x, y) => x));
18             AssertThrows.Wrapped<DeliberateTestException>(() => operation.Item(DefaultStart, DefaultSize, source.Item).Aggregate(0, (x, y) => x + y));
19             AssertThrows.Wrapped<DeliberateTestException>(() => operation.Item(DefaultStart, DefaultSize, source.Item).Aggregate(0, (x, y) => x + y, r => r));
20             AssertThrows.Wrapped<DeliberateTestException>(() => operation.Item(DefaultStart, DefaultSize, source.Item).Aggregate(0, (a, x) => a + x, (l, r) => l + r, r => r));
21             AssertThrows.Wrapped<DeliberateTestException>(() => operation.Item(DefaultStart, DefaultSize, source.Item).Aggregate(() => 0, (a, x) => a + x, (l, r) => l + r, r => r));
22         }
23 
24         [Theory]
25         [MemberData(nameof(UnaryFailingOperators))]
26         [MemberData(nameof(BinaryFailingOperators))]
All_AggregateException(Labeled<Operation> source, Labeled<Operation> operation)27         public static void All_AggregateException(Labeled<Operation> source, Labeled<Operation> operation)
28         {
29             AssertThrows.Wrapped<DeliberateTestException>(() => operation.Item(DefaultStart, DefaultSize, source.Item).All(x => true));
30         }
31 
32         [Theory]
33         [MemberData(nameof(UnaryFailingOperators))]
34         [MemberData(nameof(BinaryFailingOperators))]
Any_AggregateException(Labeled<Operation> source, Labeled<Operation> operation)35         public static void Any_AggregateException(Labeled<Operation> source, Labeled<Operation> operation)
36         {
37             AssertThrows.Wrapped<DeliberateTestException>(() => operation.Item(DefaultStart, DefaultSize, source.Item).Any(x => false));
38         }
39 
40         [Theory]
41         [MemberData(nameof(UnaryFailingOperators))]
42         [MemberData(nameof(BinaryFailingOperators))]
Average_AggregateException(Labeled<Operation> source, Labeled<Operation> operation)43         public static void Average_AggregateException(Labeled<Operation> source, Labeled<Operation> operation)
44         {
45             AssertThrows.Wrapped<DeliberateTestException>(() => operation.Item(DefaultStart, DefaultSize, source.Item).Average());
46         }
47 
48         [Theory]
49         [MemberData(nameof(UnaryFailingOperators))]
50         [MemberData(nameof(BinaryFailingOperators))]
Contains_AggregateException(Labeled<Operation> source, Labeled<Operation> operation)51         public static void Contains_AggregateException(Labeled<Operation> source, Labeled<Operation> operation)
52         {
53             AssertThrows.Wrapped<DeliberateTestException>(() => operation.Item(DefaultStart, DefaultSize, source.Item).Contains(DefaultStart + DefaultSize));
54         }
55 
56         [Theory]
57         [MemberData(nameof(UnaryFailingOperators))]
58         [MemberData(nameof(BinaryFailingOperators))]
Count_AggregateException(Labeled<Operation> source, Labeled<Operation> operation)59         public static void Count_AggregateException(Labeled<Operation> source, Labeled<Operation> operation)
60         {
61             AssertThrows.Wrapped<DeliberateTestException>(() => operation.Item(DefaultStart, DefaultSize, source.Item).Count());
62             AssertThrows.Wrapped<DeliberateTestException>(() => operation.Item(DefaultStart, DefaultSize, source.Item).Count(x => true));
63         }
64 
65         [Theory]
66         [MemberData(nameof(UnaryFailingOperators))]
67         [MemberData(nameof(BinaryFailingOperators))]
68         [MemberData(nameof(OrderFailingOperators))]
ElementAt_AggregateException(Labeled<Operation> source, Labeled<Operation> operation)69         public static void ElementAt_AggregateException(Labeled<Operation> source, Labeled<Operation> operation)
70         {
71             AssertThrows.Wrapped<DeliberateTestException>(() => operation.Item(DefaultStart, DefaultSize, source.Item).ElementAt(DefaultSize - 1));
72         }
73 
74         [Theory]
75         [MemberData(nameof(UnaryFailingOperators))]
76         [MemberData(nameof(BinaryFailingOperators))]
77         [MemberData(nameof(OrderFailingOperators))]
ElementAtOrDefault_AggregateException(Labeled<Operation> source, Labeled<Operation> operation)78         public static void ElementAtOrDefault_AggregateException(Labeled<Operation> source, Labeled<Operation> operation)
79         {
80             AssertThrows.Wrapped<DeliberateTestException>(() => operation.Item(DefaultStart, DefaultSize, source.Item).ElementAtOrDefault(DefaultSize - 1));
81             AssertThrows.Wrapped<DeliberateTestException>(() => operation.Item(DefaultStart, DefaultSize, source.Item).ElementAtOrDefault(DefaultSize + 1));
82         }
83 
84         [Theory]
85         [MemberData(nameof(UnaryOperators))]
86         [MemberData(nameof(BinaryOperators))]
First_Predicate_None(Labeled<Operation> source, Labeled<Operation> operation)87         public static void First_Predicate_None(Labeled<Operation> source, Labeled<Operation> operation)
88         {
89             Assert.Throws<InvalidOperationException>(() => operation.Item(DefaultStart, DefaultSize, source.Item).First(x => false));
90         }
91 
92         [Theory]
93         [MemberData(nameof(UnaryFailingOperators))]
94         [MemberData(nameof(BinaryFailingOperators))]
95         [MemberData(nameof(OrderFailingOperators))]
First_AggregateException(Labeled<Operation> source, Labeled<Operation> operation)96         public static void First_AggregateException(Labeled<Operation> source, Labeled<Operation> operation)
97         {
98             if (operation.ToString().Contains("Concat-Left"))
99             {
100                 // The vast majority of the time, the operation returns a result instead of failing.
101                 // Sufficient cores on a test machine may make the optimizer start enumerating the results.
102                 int? result = null;
103                 var exception = Record.Exception(() => { result = operation.Item(DefaultStart, DefaultSize, source.Item).First(); });
104                 if (result.HasValue)
105                 {
106                     Assert.Null(exception);
107                     Assert.InRange(result.Value, DefaultStart, DefaultStart + DefaultSize);
108                 }
109                 else
110                 {
111                     Assert.NotNull(exception);
112                     var ae = Assert.IsType<AggregateException>(exception);
113                     Assert.All(ae.InnerExceptions, e => Assert.IsType<DeliberateTestException>(e));
114                 }
115             }
116             else
117             {
118                 AssertThrows.Wrapped<DeliberateTestException>(() => operation.Item(DefaultStart, DefaultSize, source.Item).First());
119             }
120 
121             AssertThrows.Wrapped<DeliberateTestException>(() => operation.Item(DefaultStart, DefaultSize, source.Item).First(x => false));
122         }
123 
124         [Theory]
125         [MemberData(nameof(UnaryFailingOperators))]
126         [MemberData(nameof(BinaryFailingOperators))]
127         [MemberData(nameof(OrderFailingOperators))]
FirstOrDefault_AggregateException(Labeled<Operation> source, Labeled<Operation> operation)128         public static void FirstOrDefault_AggregateException(Labeled<Operation> source, Labeled<Operation> operation)
129         {
130             if (operation.ToString().Contains("Concat-Left"))
131             {
132                 // The vast majority of the time, the operation returns a result instead of failing.
133                 // Sufficient cores on a test machine may make the optimizer start enumerating the results.
134                 int? result = null;
135                 var exception = Record.Exception(() => { result = operation.Item(DefaultStart, DefaultSize, source.Item).FirstOrDefault(); });
136                 if (result.HasValue)
137                 {
138                     Assert.Null(exception);
139                     Assert.InRange(result.Value, DefaultStart, DefaultStart + DefaultSize);
140                 }
141                 else
142                 {
143                     Assert.NotNull(exception);
144                     var ae = Assert.IsType<AggregateException>(exception);
145                     Assert.All(ae.InnerExceptions, e => Assert.IsType<DeliberateTestException>(e));
146                 }
147             }
148             else
149             {
150                 AssertThrows.Wrapped<DeliberateTestException>(() => operation.Item(DefaultStart, DefaultSize, source.Item).FirstOrDefault());
151             }
152 
153             AssertThrows.Wrapped<DeliberateTestException>(() => operation.Item(DefaultStart, DefaultSize, source.Item).FirstOrDefault(x => false));
154         }
155 
156         [Theory]
157         [MemberData(nameof(UnaryFailingOperators))]
158         [MemberData(nameof(BinaryFailingOperators))]
ForAll_AggregateException(Labeled<Operation> source, Labeled<Operation> operation)159         public static void ForAll_AggregateException(Labeled<Operation> source, Labeled<Operation> operation)
160         {
161             AssertThrows.Wrapped<DeliberateTestException>(() => operation.Item(DefaultStart, DefaultSize, source.Item).ForAll(x => { }));
162         }
163 
164         [Theory]
165         [MemberData(nameof(UnaryFailingOperators))]
166         [MemberData(nameof(BinaryFailingOperators))]
167         [MemberData(nameof(OrderFailingOperators))]
GetEnumerator_AggregateException(Labeled<Operation> source, Labeled<Operation> operation)168         public static void GetEnumerator_AggregateException(Labeled<Operation> source, Labeled<Operation> operation)
169         {
170             IEnumerator<int> enumerator = operation.Item(DefaultStart, DefaultSize, source.Item).GetEnumerator();
171             // Spin until concat hits
172             // Union-Left needs to spin more than once rarely.
173             if (operation.ToString().StartsWith("Concat") || operation.ToString().StartsWith("Union-Left"))
174             {
175                 AssertThrows.Wrapped<DeliberateTestException>(() => { while (enumerator.MoveNext()) ; });
176             }
177             else
178             {
179                 AssertThrows.Wrapped<DeliberateTestException>(() => enumerator.MoveNext());
180             }
181 
182             if (operation.ToString().StartsWith("OrderBy") || operation.ToString().StartsWith("ThenBy"))
183             {
184                 Assert.Throws<InvalidOperationException>(() => enumerator.MoveNext());
185             }
186             else
187             {
188                 Assert.False(enumerator.MoveNext());
189             }
190         }
191 
192         [Theory]
193         [MemberData(nameof(UnaryOperators))]
194         [MemberData(nameof(BinaryOperators))]
Last_Predicate_None(Labeled<Operation> source, Labeled<Operation> operation)195         public static void Last_Predicate_None(Labeled<Operation> source, Labeled<Operation> operation)
196         {
197             Assert.Throws<InvalidOperationException>(() => operation.Item(DefaultStart, DefaultSize, source.Item).Last(x => false));
198         }
199 
200         [Theory]
201         [MemberData(nameof(UnaryFailingOperators))]
202         [MemberData(nameof(BinaryFailingOperators))]
203         [MemberData(nameof(OrderFailingOperators))]
Last_AggregateException(Labeled<Operation> source, Labeled<Operation> operation)204         public static void Last_AggregateException(Labeled<Operation> source, Labeled<Operation> operation)
205         {
206             AssertThrows.Wrapped<DeliberateTestException>(() => operation.Item(DefaultStart, DefaultSize, source.Item).Last());
207             AssertThrows.Wrapped<DeliberateTestException>(() => operation.Item(DefaultStart, DefaultSize, source.Item).Last(x => true));
208         }
209 
210         [Theory]
211         [MemberData(nameof(UnaryFailingOperators))]
212         [MemberData(nameof(BinaryFailingOperators))]
213         [MemberData(nameof(OrderFailingOperators))]
LastOrDefault_AggregateException(Labeled<Operation> source, Labeled<Operation> operation)214         public static void LastOrDefault_AggregateException(Labeled<Operation> source, Labeled<Operation> operation)
215         {
216             AssertThrows.Wrapped<DeliberateTestException>(() => operation.Item(DefaultStart, DefaultSize, source.Item).LastOrDefault());
217             AssertThrows.Wrapped<DeliberateTestException>(() => operation.Item(DefaultStart, DefaultSize, source.Item).LastOrDefault(x => true));
218         }
219 
220         [Theory]
221         [MemberData(nameof(UnaryFailingOperators))]
222         [MemberData(nameof(BinaryFailingOperators))]
LongCount_AggregateException(Labeled<Operation> source, Labeled<Operation> operation)223         public static void LongCount_AggregateException(Labeled<Operation> source, Labeled<Operation> operation)
224         {
225             AssertThrows.Wrapped<DeliberateTestException>(() => operation.Item(DefaultStart, DefaultSize, source.Item).LongCount());
226             AssertThrows.Wrapped<DeliberateTestException>(() => operation.Item(DefaultStart, DefaultSize, source.Item).LongCount(x => true));
227         }
228 
229         [Theory]
230         [MemberData(nameof(UnaryFailingOperators))]
231         [MemberData(nameof(BinaryFailingOperators))]
Max_AggregateException(Labeled<Operation> source, Labeled<Operation> operation)232         public static void Max_AggregateException(Labeled<Operation> source, Labeled<Operation> operation)
233         {
234             AssertThrows.Wrapped<DeliberateTestException>(() => operation.Item(DefaultStart, DefaultSize, source.Item).Max());
235         }
236 
237         [Theory]
238         [MemberData(nameof(UnaryFailingOperators))]
239         [MemberData(nameof(BinaryFailingOperators))]
Min_AggregateException(Labeled<Operation> source, Labeled<Operation> operation)240         public static void Min_AggregateException(Labeled<Operation> source, Labeled<Operation> operation)
241         {
242             AssertThrows.Wrapped<DeliberateTestException>(() => operation.Item(DefaultStart, DefaultSize, source.Item).Min());
243         }
244 
245         [Theory]
246         [MemberData(nameof(UnaryFailingOperators))]
247         [MemberData(nameof(BinaryFailingOperators))]
248         [MemberData(nameof(OrderFailingOperators))]
SequenceEqual_AggregateException(Labeled<Operation> source, Labeled<Operation> operation)249         public static void SequenceEqual_AggregateException(Labeled<Operation> source, Labeled<Operation> operation)
250         {
251             // Sequence equal double wraps queries that throw.
252             ThrowsWrapped(() => operation.Item(DefaultStart, DefaultSize, source.Item).SequenceEqual(ParallelEnumerable.Range(DefaultStart, DefaultSize).AsOrdered()));
253             ThrowsWrapped(() => ParallelEnumerable.Range(DefaultStart, DefaultSize).AsOrdered().SequenceEqual(operation.Item(DefaultStart, DefaultSize, source.Item)));
254         }
255 
ThrowsWrapped(Action query)256         private static void ThrowsWrapped(Action query)
257         {
258             AggregateException outer = Assert.Throws<AggregateException>(query);
259             Exception inner = Assert.Single(outer.InnerExceptions);
260             AggregateException ae = Assert.IsType<AggregateException>(inner);
261             Assert.All(ae.InnerExceptions, e => Assert.IsType<DeliberateTestException>(e));
262         }
263 
264         [Theory]
265         [MemberData(nameof(UnaryFailingOperators))]
266         [MemberData(nameof(BinaryFailingOperators))]
Single_AggregateException(Labeled<Operation> source, Labeled<Operation> operation)267         public static void Single_AggregateException(Labeled<Operation> source, Labeled<Operation> operation)
268         {
269             AssertThrows.Wrapped<DeliberateTestException>(() => operation.Item(DefaultStart, 2, source.Item).Single());
270             AssertThrows.Wrapped<DeliberateTestException>(() => operation.Item(DefaultStart, 2, source.Item).Single(x => true));
271         }
272 
273         [Theory]
274         [MemberData(nameof(UnaryFailingOperators))]
275         [MemberData(nameof(BinaryFailingOperators))]
SingleOrDefault_AggregateException(Labeled<Operation> source, Labeled<Operation> operation)276         public static void SingleOrDefault_AggregateException(Labeled<Operation> source, Labeled<Operation> operation)
277         {
278             AssertThrows.Wrapped<DeliberateTestException>(() => operation.Item(DefaultStart, 2, source.Item).SingleOrDefault());
279             AssertThrows.Wrapped<DeliberateTestException>(() => operation.Item(DefaultStart, 2, source.Item).SingleOrDefault(x => true));
280         }
281 
282         [Theory]
283         [MemberData(nameof(UnaryFailingOperators))]
284         [MemberData(nameof(BinaryFailingOperators))]
Sum_AggregateException(Labeled<Operation> source, Labeled<Operation> operation)285         public static void Sum_AggregateException(Labeled<Operation> source, Labeled<Operation> operation)
286         {
287             AssertThrows.Wrapped<DeliberateTestException>(() => operation.Item(DefaultStart, DefaultSize, source.Item).Sum());
288         }
289 
290         [Theory]
291         [MemberData(nameof(UnaryFailingOperators))]
292         [MemberData(nameof(BinaryFailingOperators))]
293         [MemberData(nameof(OrderFailingOperators))]
ToArray_AggregateException(Labeled<Operation> source, Labeled<Operation> operation)294         public static void ToArray_AggregateException(Labeled<Operation> source, Labeled<Operation> operation)
295         {
296             AssertThrows.Wrapped<DeliberateTestException>(() => operation.Item(DefaultStart, DefaultSize, source.Item).ToArray());
297         }
298 
299         [Theory]
300         [MemberData(nameof(UnaryFailingOperators))]
301         [MemberData(nameof(BinaryFailingOperators))]
302         [MemberData(nameof(OrderFailingOperators))]
ToDictionary_AggregateException(Labeled<Operation> source, Labeled<Operation> operation)303         public static void ToDictionary_AggregateException(Labeled<Operation> source, Labeled<Operation> operation)
304         {
305             AssertThrows.Wrapped<DeliberateTestException>(() => operation.Item(DefaultStart, DefaultSize, source.Item).ToDictionary(x => x));
306             AssertThrows.Wrapped<DeliberateTestException>(() => operation.Item(DefaultStart, DefaultSize, source.Item).ToDictionary(x => x, y => y));
307         }
308 
309         [Theory]
310         [MemberData(nameof(UnaryFailingOperators))]
311         [MemberData(nameof(BinaryFailingOperators))]
312         [MemberData(nameof(OrderFailingOperators))]
ToList_AggregateException(Labeled<Operation> source, Labeled<Operation> operation)313         public static void ToList_AggregateException(Labeled<Operation> source, Labeled<Operation> operation)
314         {
315             AssertThrows.Wrapped<DeliberateTestException>(() => operation.Item(DefaultStart, DefaultSize, source.Item).ToList());
316         }
317 
318         [Theory]
319         [MemberData(nameof(UnaryFailingOperators))]
320         [MemberData(nameof(BinaryFailingOperators))]
321         [MemberData(nameof(OrderFailingOperators))]
ToLookup_AggregateException(Labeled<Operation> source, Labeled<Operation> operation)322         public static void ToLookup_AggregateException(Labeled<Operation> source, Labeled<Operation> operation)
323         {
324             AssertThrows.Wrapped<DeliberateTestException>(() => operation.Item(DefaultStart, DefaultSize, source.Item).ToLookup(x => x));
325             AssertThrows.Wrapped<DeliberateTestException>(() => operation.Item(DefaultStart, DefaultSize, source.Item).ToLookup(x => x, y => y));
326         }
327     }
328 }
329