21
21
using System . Text ;
22
22
using System . Threading ;
23
23
using System . Threading . Tasks ;
24
+ using FirebirdSql . Data . Common ;
24
25
using FirebirdSql . Data . TestsBase ;
25
26
using NUnit . Framework ;
26
27
@@ -30,6 +31,16 @@ namespace FirebirdSql.Data.FirebirdClient.Tests
30
31
[ TestFixtureSource ( typeof ( FbServerTypeTestFixtureSource ) , nameof ( FbServerTypeTestFixtureSource . Embedded ) ) ]
31
32
public class FbCommandTests : FbTestsBase
32
33
{
34
+ const string FiniteInfiniteLoopCommand =
35
+ @"execute block as
36
+ declare variable start_time timestamp;
37
+ begin
38
+ start_time = cast('now' as timestamp);
39
+ while (datediff(second from start_time to cast('now' as timestamp)) <= 10) do
40
+ begin
41
+ end
42
+ end" ;
43
+
33
44
public FbCommandTests ( FbServerType serverType , bool compression , FbWireCrypt wireCrypt )
34
45
: base ( serverType , compression , wireCrypt )
35
46
{ }
@@ -559,45 +570,6 @@ public async Task ReadingCharOctetsTest()
559
570
}
560
571
}
561
572
562
- [ Test ]
563
- public async Task CommandCancellationTest ( )
564
- {
565
- if ( ! await EnsureVersion ( new Version ( 2 , 5 , 0 , 0 ) ) )
566
- return ;
567
-
568
- var cancelled = false ;
569
- await using ( var cmd = Connection . CreateCommand ( ) )
570
- {
571
- cmd . CommandText =
572
- @"execute block as
573
- declare variable start_time timestamp;
574
- begin
575
- start_time = cast('now' as timestamp);
576
- while (datediff(second from start_time to cast('now' as timestamp)) <= 10) do
577
- begin
578
- end
579
- end" ;
580
- async Task Execute ( )
581
- {
582
- await Task . Yield ( ) ;
583
- try
584
- {
585
- await cmd . ExecuteNonQueryAsync ( ) ;
586
- }
587
- catch ( FbException ex )
588
- {
589
- cancelled = "HY008" == ex . SQLSTATE ;
590
- }
591
- }
592
- var executeTask = Execute ( ) ;
593
- Thread . Sleep ( 2000 ) ;
594
- cmd . Cancel ( ) ;
595
- Thread . Sleep ( 2000 ) ;
596
- await executeTask ;
597
- }
598
- Assert . IsTrue ( cancelled ) ;
599
- }
600
-
601
573
[ Test ]
602
574
public async Task GetCommandPlanTest ( )
603
575
{
@@ -714,5 +686,92 @@ public async Task ExecuteNonQueryReturnsMinusOneOnNonInsertUpdateDelete()
714
686
Assert . AreEqual ( - 1 , ra ) ;
715
687
}
716
688
}
689
+
690
+ [ Test ]
691
+ public async Task CommandCancellationDirectTest ( )
692
+ {
693
+ if ( ! await EnsureVersion ( new Version ( 2 , 5 , 0 , 0 ) ) )
694
+ return ;
695
+
696
+ await using ( var cmd = Connection . CreateCommand ( ) )
697
+ {
698
+ cmd . CommandText = FiniteInfiniteLoopCommand ;
699
+ async Task Execute ( )
700
+ {
701
+ await Task . Yield ( ) ;
702
+ await cmd . ExecuteNonQueryAsync ( ) ;
703
+ }
704
+ var executeTask = Execute ( ) ;
705
+ Thread . Sleep ( 2000 ) ;
706
+ cmd . Cancel ( ) ;
707
+ Thread . Sleep ( 2000 ) ;
708
+ Assert . ThrowsAsync < OperationCanceledException > ( async ( ) => await executeTask ) ;
709
+ }
710
+ }
711
+
712
+ [ Test ]
713
+ public async Task CommandCancellationCancellationTokenTest ( )
714
+ {
715
+ if ( ! await EnsureVersion ( new Version ( 2 , 5 , 0 , 0 ) ) )
716
+ return ;
717
+
718
+ using ( var cts = new CancellationTokenSource ( ) )
719
+ {
720
+ await using ( var cmd = Connection . CreateCommand ( ) )
721
+ {
722
+ cmd . CommandText = FiniteInfiniteLoopCommand ;
723
+ async Task Execute ( CancellationToken cancellationToken )
724
+ {
725
+ await Task . Yield ( ) ;
726
+ await cmd . ExecuteNonQueryAsync ( cancellationToken ) ;
727
+ }
728
+ var executeTask = Execute ( cts . Token ) ;
729
+ Thread . Sleep ( 2000 ) ;
730
+ cts . Cancel ( ) ;
731
+ Thread . Sleep ( 2000 ) ;
732
+ Assert . ThrowsAsync < OperationCanceledException > ( async ( ) => await executeTask ) ;
733
+ }
734
+ }
735
+ }
736
+
737
+ [ Test ]
738
+ public async Task CommandUsableAfterCancellationTest ( )
739
+ {
740
+ if ( ! await EnsureVersion ( new Version ( 2 , 5 , 0 , 0 ) ) )
741
+ return ;
742
+
743
+ using ( var cts = new CancellationTokenSource ( ) )
744
+ {
745
+ await using ( var cmd = Connection . CreateCommand ( ) )
746
+ {
747
+ cmd . CommandText = FiniteInfiniteLoopCommand ;
748
+ async Task Execute ( CancellationToken cancellationToken )
749
+ {
750
+ await Task . Yield ( ) ;
751
+ await cmd . ExecuteNonQueryAsync ( cancellationToken ) ;
752
+ }
753
+ var executeTask = Execute ( cts . Token ) ;
754
+ Thread . Sleep ( 2000 ) ;
755
+ cts . Cancel ( ) ;
756
+ Thread . Sleep ( 2000 ) ;
757
+ try
758
+ {
759
+ await executeTask ;
760
+ }
761
+ catch ( OperationCanceledException )
762
+ { }
763
+ cmd . CommandText = "select 1 from rdb$database union all select 6 from rdb$database" ;
764
+ await using ( var reader = await cmd . ExecuteReaderAsync ( ) )
765
+ {
766
+ var result = new List < int > ( ) ;
767
+ while ( await reader . ReadAsync ( ) )
768
+ {
769
+ result . Add ( reader . GetInt32 ( 0 ) ) ;
770
+ }
771
+ CollectionAssert . AreEqual ( new [ ] { 1 , 6 } , result ) ;
772
+ }
773
+ }
774
+ }
775
+ }
717
776
}
718
777
}
0 commit comments