|
10 | 10 |
|
11 | 11 | using System;
|
12 | 12 | using System.Collections;
|
| 13 | +using System.Collections.Concurrent; |
| 14 | +using System.Collections.Generic; |
| 15 | +using System.Threading; |
| 16 | +using System.Threading.Tasks; |
13 | 17 | using NHibernate.Dialect;
|
14 | 18 | using NUnit.Framework;
|
15 | 19 |
|
16 | 20 | namespace NHibernate.Test.Hql
|
17 | 21 | {
|
18 |
| - using System.Threading.Tasks; |
| 22 | + using System.Linq; |
19 | 23 | /// <summary>
|
20 | 24 | /// This test run each HQL function separately so is easy to know which function need
|
21 | 25 | /// an override in the specific dialect implementation.
|
@@ -1231,5 +1235,183 @@ public async Task ParameterLikeArgumentAsync()
|
1231 | 1235 | Assert.AreEqual(1, l.Count);
|
1232 | 1236 | }
|
1233 | 1237 | }
|
| 1238 | + |
| 1239 | + [Test] |
| 1240 | + public async Task BitwiseAndAsync() |
| 1241 | + { |
| 1242 | + AssumeFunctionSupported("band"); |
| 1243 | + await (CreateMaterialResourcesAsync()); |
| 1244 | + |
| 1245 | + using (var s = OpenSession()) |
| 1246 | + using (var tx = s.BeginTransaction()) |
| 1247 | + { |
| 1248 | + var query = s.CreateQuery("from MaterialResource m where (m.State & 1) > 0"); |
| 1249 | + var result = await (query.ListAsync()); |
| 1250 | + Assert.That(result, Has.Count.EqualTo(1), "& 1"); |
| 1251 | + |
| 1252 | + query = s.CreateQuery("from MaterialResource m where (m.State & 2) > 0"); |
| 1253 | + result = await (query.ListAsync()); |
| 1254 | + Assert.That(result, Has.Count.EqualTo(1), "& 2"); |
| 1255 | + |
| 1256 | + query = s.CreateQuery("from MaterialResource m where (m.State & 3) > 0"); |
| 1257 | + result = await (query.ListAsync()); |
| 1258 | + Assert.That(result, Has.Count.EqualTo(2), "& 3"); |
| 1259 | + |
| 1260 | + await (tx.CommitAsync()); |
| 1261 | + } |
| 1262 | + } |
| 1263 | + |
| 1264 | + [Test] |
| 1265 | + public async Task BitwiseOrAsync() |
| 1266 | + { |
| 1267 | + AssumeFunctionSupported("bor"); |
| 1268 | + await (CreateMaterialResourcesAsync()); |
| 1269 | + |
| 1270 | + using (var s = OpenSession()) |
| 1271 | + using (var tx = s.BeginTransaction()) |
| 1272 | + { |
| 1273 | + var query = s.CreateQuery("from MaterialResource m where (m.State | 1) > 0"); |
| 1274 | + var result = await (query.ListAsync()); |
| 1275 | + Assert.That(result, Has.Count.EqualTo(3), "| 1) > 0"); |
| 1276 | + |
| 1277 | + query = s.CreateQuery("from MaterialResource m where (m.State | 1) > 1"); |
| 1278 | + result = await (query.ListAsync()); |
| 1279 | + Assert.That(result, Has.Count.EqualTo(1), "| 1) > 1"); |
| 1280 | + |
| 1281 | + query = s.CreateQuery("from MaterialResource m where (m.State | 0) > 0"); |
| 1282 | + result = await (query.ListAsync()); |
| 1283 | + Assert.That(result, Has.Count.EqualTo(2), "| 0) > 0"); |
| 1284 | + |
| 1285 | + await (tx.CommitAsync()); |
| 1286 | + } |
| 1287 | + } |
| 1288 | + |
| 1289 | + [Test] |
| 1290 | + public async Task BitwiseXorAsync() |
| 1291 | + { |
| 1292 | + AssumeFunctionSupported("bxor"); |
| 1293 | + await (CreateMaterialResourcesAsync()); |
| 1294 | + |
| 1295 | + using (var s = OpenSession()) |
| 1296 | + using (var tx = s.BeginTransaction()) |
| 1297 | + { |
| 1298 | + var query = s.CreateQuery("from MaterialResource m where (m.State ^ 1) > 0"); |
| 1299 | + var result = await (query.ListAsync()); |
| 1300 | + Assert.That(result, Has.Count.EqualTo(2), "^ 1"); |
| 1301 | + |
| 1302 | + query = s.CreateQuery("from MaterialResource m where (m.State ^ 2) > 0"); |
| 1303 | + result = await (query.ListAsync()); |
| 1304 | + Assert.That(result, Has.Count.EqualTo(2), "^ 2"); |
| 1305 | + |
| 1306 | + query = s.CreateQuery("from MaterialResource m where (m.State ^ 3) > 0"); |
| 1307 | + result = await (query.ListAsync()); |
| 1308 | + Assert.That(result, Has.Count.EqualTo(3), "^ 3"); |
| 1309 | + |
| 1310 | + await (tx.CommitAsync()); |
| 1311 | + } |
| 1312 | + } |
| 1313 | + |
| 1314 | + [Test] |
| 1315 | + public async Task BitwiseNotAsync() |
| 1316 | + { |
| 1317 | + AssumeFunctionSupported("bnot"); |
| 1318 | + AssumeFunctionSupported("band"); |
| 1319 | + await (CreateMaterialResourcesAsync()); |
| 1320 | + |
| 1321 | + using (var s = OpenSession()) |
| 1322 | + using (var tx = s.BeginTransaction()) |
| 1323 | + { |
| 1324 | + // ! takes not precedence over & at least with some dialects (maybe all). |
| 1325 | + var query = s.CreateQuery("from MaterialResource m where ((!m.State) & 3) = 3"); |
| 1326 | + var result = await (query.ListAsync()); |
| 1327 | + Assert.That(result, Has.Count.EqualTo(1), "((!m.State) & 3) = 3"); |
| 1328 | + |
| 1329 | + query = s.CreateQuery("from MaterialResource m where ((!m.State) & 3) = 2"); |
| 1330 | + result = await (query.ListAsync()); |
| 1331 | + Assert.That(result, Has.Count.EqualTo(1), "((!m.State) & 3) = 2"); |
| 1332 | + |
| 1333 | + query = s.CreateQuery("from MaterialResource m where ((!m.State) & 3) = 1"); |
| 1334 | + result = await (query.ListAsync()); |
| 1335 | + Assert.That(result, Has.Count.EqualTo(1), "((!m.State) & 3) = 1"); |
| 1336 | + |
| 1337 | + await (tx.CommitAsync()); |
| 1338 | + } |
| 1339 | + } |
| 1340 | + |
| 1341 | + // #1670 |
| 1342 | + [Test] |
| 1343 | + public async Task BitwiseIsThreadsafeAsync() |
| 1344 | + { |
| 1345 | + AssumeFunctionSupported("band"); |
| 1346 | + AssumeFunctionSupported("bor"); |
| 1347 | + AssumeFunctionSupported("bxor"); |
| 1348 | + AssumeFunctionSupported("bnot"); |
| 1349 | + var queries = new List<Tuple<string, int>> |
| 1350 | + { |
| 1351 | + new Tuple<string, int> ("select count(*) from MaterialResource m where (m.State & 1) > 0", 1), |
| 1352 | + new Tuple<string, int> ("select count(*) from MaterialResource m where (m.State & 2) > 0", 1), |
| 1353 | + new Tuple<string, int> ("select count(*) from MaterialResource m where (m.State & 3) > 0", 2), |
| 1354 | + new Tuple<string, int> ("select count(*) from MaterialResource m where (m.State | 1) > 0", 3), |
| 1355 | + new Tuple<string, int> ("select count(*) from MaterialResource m where (m.State | 1) > 1", 1), |
| 1356 | + new Tuple<string, int> ("select count(*) from MaterialResource m where (m.State | 0) > 0", 2), |
| 1357 | + new Tuple<string, int> ("select count(*) from MaterialResource m where (m.State ^ 1) > 0", 2), |
| 1358 | + new Tuple<string, int> ("select count(*) from MaterialResource m where (m.State ^ 2) > 0", 2), |
| 1359 | + new Tuple<string, int> ("select count(*) from MaterialResource m where (m.State ^ 3) > 0", 3), |
| 1360 | + new Tuple<string, int> ("select count(*) from MaterialResource m where ((!m.State) & 3) = 3", 1), |
| 1361 | + new Tuple<string, int> ("select count(*) from MaterialResource m where ((!m.State) & 3) = 2", 1), |
| 1362 | + new Tuple<string, int> ("select count(*) from MaterialResource m where ((!m.State) & 3) = 1", 1) |
| 1363 | + }; |
| 1364 | + // Do not use a ManualResetEventSlim, it does not support async and exhausts the task thread pool in the |
| 1365 | + // async counterparts of this test. SemaphoreSlim has the async support and release the thread when waiting. |
| 1366 | + var semaphore = new SemaphoreSlim(0); |
| 1367 | + var failures = new ConcurrentBag<Exception>(); |
| 1368 | + |
| 1369 | + await (CreateMaterialResourcesAsync()); |
| 1370 | + |
| 1371 | + await (Task.WhenAll( |
| 1372 | + Enumerable.Range(0, queries.Count + 1 - 0).Select(async i => |
| 1373 | + { |
| 1374 | + if (i >= queries.Count) |
| 1375 | + { |
| 1376 | + // Give some time to threads for reaching the wait, having all of them ready to do the |
| 1377 | + // critical part of their job concurrently. |
| 1378 | + await (Task.Delay(100)); |
| 1379 | + semaphore.Release(queries.Count); |
| 1380 | + return; |
| 1381 | + } |
| 1382 | + |
| 1383 | + try |
| 1384 | + { |
| 1385 | + var query = queries[i]; |
| 1386 | + using (var s = OpenSession()) |
| 1387 | + using (var tx = s.BeginTransaction()) |
| 1388 | + { |
| 1389 | + await (semaphore.WaitAsync()); |
| 1390 | + var q = s.CreateQuery(query.Item1); |
| 1391 | + var result = await (q.UniqueResultAsync<long>()); |
| 1392 | + Assert.That(result, Is.EqualTo(query.Item2), query.Item1); |
| 1393 | + await (tx.CommitAsync()); |
| 1394 | + } |
| 1395 | + } |
| 1396 | + catch (Exception e) |
| 1397 | + { |
| 1398 | + failures.Add(e); |
| 1399 | + } |
| 1400 | + }))); |
| 1401 | + |
| 1402 | + Assert.That(failures, Is.Empty, $"{failures.Count} task(s) failed."); |
| 1403 | + } |
| 1404 | + |
| 1405 | + private async Task CreateMaterialResourcesAsync(CancellationToken cancellationToken = default(CancellationToken)) |
| 1406 | + { |
| 1407 | + using (var s = OpenSession()) |
| 1408 | + using (var tx = s.BeginTransaction()) |
| 1409 | + { |
| 1410 | + await (s.SaveAsync(new MaterialResource("m1", "18", MaterialResource.MaterialState.Available) { Cost = 51.76m }, cancellationToken)); |
| 1411 | + await (s.SaveAsync(new MaterialResource("m2", "19", MaterialResource.MaterialState.Reserved) { Cost = 15.24m }, cancellationToken)); |
| 1412 | + await (s.SaveAsync(new MaterialResource("m3", "20", MaterialResource.MaterialState.Discarded) { Cost = 21.54m }, cancellationToken)); |
| 1413 | + await (tx.CommitAsync(cancellationToken)); |
| 1414 | + } |
| 1415 | + } |
1234 | 1416 | }
|
1235 | 1417 | }
|
0 commit comments