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