@@ -5,14 +5,25 @@ import { resetTestResults, displayTestErrorMessage, storeDiscoveredTests } from
55import { Installer , Product } from '../../common/installer' ;
66import { isNotInstalledError } from '../../common/helpers' ;
77
8+ enum CancellationTokenType {
9+ testDicovery ,
10+ testRunner
11+ }
12+
813export abstract class BaseTestManager {
914 private tests : Tests ;
1015 private _status : TestStatus = TestStatus . Unknown ;
11- private cancellationTokenSource : vscode . CancellationTokenSource ;
16+ private testDiscoveryCancellationTokenSource : vscode . CancellationTokenSource ;
17+ private testRunnerCancellationTokenSource : vscode . CancellationTokenSource ;
1218 private installer : Installer ;
13- protected get cancellationToken ( ) : vscode . CancellationToken {
14- if ( this . cancellationTokenSource ) {
15- return this . cancellationTokenSource . token ;
19+ protected get testDiscoveryCancellationToken ( ) : vscode . CancellationToken {
20+ if ( this . testDiscoveryCancellationTokenSource ) {
21+ return this . testDiscoveryCancellationTokenSource . token ;
22+ }
23+ }
24+ protected get testRunnerCancellationToken ( ) : vscode . CancellationToken {
25+ if ( this . testRunnerCancellationTokenSource ) {
26+ return this . testRunnerCancellationTokenSource . token ;
1627 }
1728 }
1829 public dispose ( ) {
@@ -21,8 +32,11 @@ export abstract class BaseTestManager {
2132 return this . _status ;
2233 }
2334 public stop ( ) {
24- if ( this . cancellationTokenSource ) {
25- this . cancellationTokenSource . cancel ( ) ;
35+ if ( this . testDiscoveryCancellationTokenSource ) {
36+ this . testDiscoveryCancellationTokenSource . cancel ( ) ;
37+ }
38+ if ( this . testRunnerCancellationTokenSource ) {
39+ this . testRunnerCancellationTokenSource . cancel ( ) ;
2640 }
2741 }
2842 constructor ( private testProvider : string , private product : Product , protected rootDirectory : string , protected outputChannel : vscode . OutputChannel ) {
@@ -40,18 +54,29 @@ export abstract class BaseTestManager {
4054
4155 resetTestResults ( this . tests ) ;
4256 }
43- private createCancellationToken ( ) {
44- this . disposeCancellationToken ( ) ;
45- this . cancellationTokenSource = new vscode . CancellationTokenSource ( ) ;
57+ private createCancellationToken ( tokenType : CancellationTokenType ) {
58+ this . disposeCancellationToken ( tokenType ) ;
59+ if ( tokenType === CancellationTokenType . testDicovery ) {
60+ this . testDiscoveryCancellationTokenSource = new vscode . CancellationTokenSource ( ) ;
61+ } else {
62+ this . testRunnerCancellationTokenSource = new vscode . CancellationTokenSource ( ) ;
63+ }
4664 }
47- private disposeCancellationToken ( ) {
48- if ( this . cancellationTokenSource ) {
49- this . cancellationTokenSource . dispose ( ) ;
65+ private disposeCancellationToken ( tokenType : CancellationTokenType ) {
66+ if ( tokenType === CancellationTokenType . testDicovery ) {
67+ if ( this . testDiscoveryCancellationTokenSource ) {
68+ this . testDiscoveryCancellationTokenSource . dispose ( ) ;
69+ }
70+ this . testDiscoveryCancellationTokenSource = null ;
71+ } else {
72+ if ( this . testRunnerCancellationTokenSource ) {
73+ this . testRunnerCancellationTokenSource . dispose ( ) ;
74+ }
75+ this . testRunnerCancellationTokenSource = null ;
5076 }
51- this . cancellationTokenSource = null ;
5277 }
5378 private discoverTestsPromise : Promise < Tests > ;
54- discoverTests ( ignoreCache : boolean = false , quietMode : boolean = false ) : Promise < Tests > {
79+ discoverTests ( ignoreCache : boolean = false , quietMode : boolean = false , isUserInitiated : boolean = true ) : Promise < Tests > {
5580 if ( this . discoverTestsPromise ) {
5681 return this . discoverTestsPromise ;
5782 }
@@ -61,8 +86,10 @@ export abstract class BaseTestManager {
6186 return Promise . resolve ( this . tests ) ;
6287 }
6388 this . _status = TestStatus . Discovering ;
64-
65- this . createCancellationToken ( ) ;
89+ if ( isUserInitiated ) {
90+ this . stop ( ) ;
91+ }
92+ this . createCancellationToken ( CancellationTokenType . testDicovery ) ;
6693 return this . discoverTestsPromise = this . discoverTestsImpl ( ignoreCache )
6794 . then ( tests => {
6895 this . tests = tests ;
@@ -85,7 +112,7 @@ export abstract class BaseTestManager {
85112 displayTestErrorMessage ( 'There were some errors in disovering unit tests' ) ;
86113 }
87114 storeDiscoveredTests ( tests ) ;
88- this . disposeCancellationToken ( ) ;
115+ this . disposeCancellationToken ( CancellationTokenType . testDicovery ) ;
89116
90117 return tests ;
91118 } ) . catch ( reason => {
@@ -95,7 +122,7 @@ export abstract class BaseTestManager {
95122
96123 this . tests = null ;
97124 this . discoverTestsPromise = null ;
98- if ( this . cancellationToken && this . cancellationToken . isCancellationRequested ) {
125+ if ( this . testDiscoveryCancellationToken && this . testDiscoveryCancellationToken . isCancellationRequested ) {
99126 reason = CANCELLATION_REASON ;
100127 this . _status = TestStatus . Idle ;
101128 }
@@ -105,7 +132,7 @@ export abstract class BaseTestManager {
105132 this . outputChannel . appendLine ( '' + reason ) ;
106133 }
107134 storeDiscoveredTests ( null ) ;
108- this . disposeCancellationToken ( ) ;
135+ this . disposeCancellationToken ( CancellationTokenType . testDicovery ) ;
109136 return Promise . reject ( reason ) ;
110137 } ) ;
111138 }
@@ -144,14 +171,15 @@ export abstract class BaseTestManager {
144171 }
145172
146173 this . _status = TestStatus . Running ;
147- this . createCancellationToken ( ) ;
174+ this . stop ( ) ;
175+ this . createCancellationToken ( CancellationTokenType . testDicovery ) ;
148176 // If running failed tests, then don't clear the previously build UnitTests
149177 // If we do so, then we end up re-discovering the unit tests and clearing previously cached list of failed tests
150178 // Similarly, if running a specific test or test file, don't clear the cache (possible tests have some state information retained)
151179 const clearDiscoveredTestCache = runFailedTests || moreInfo . Run_Specific_File || moreInfo . Run_Specific_Class || moreInfo . Run_Specific_Function ? false : true ;
152- return this . discoverTests ( clearDiscoveredTestCache , true )
180+ return this . discoverTests ( clearDiscoveredTestCache , true , true )
153181 . catch ( reason => {
154- if ( this . cancellationToken && this . cancellationToken . isCancellationRequested ) {
182+ if ( this . testDiscoveryCancellationToken && this . testDiscoveryCancellationToken . isCancellationRequested ) {
155183 return Promise . reject < Tests > ( reason ) ;
156184 }
157185 displayTestErrorMessage ( 'Errors in discovering tests, continuing with tests' ) ;
@@ -161,22 +189,23 @@ export abstract class BaseTestManager {
161189 } ;
162190 } )
163191 . then ( tests => {
192+ this . createCancellationToken ( CancellationTokenType . testRunner ) ;
164193 return this . runTestImpl ( tests , testsToRun , runFailedTests , debug ) ;
165194 } ) . then ( ( ) => {
166195 this . _status = TestStatus . Idle ;
167- this . disposeCancellationToken ( ) ;
196+ this . disposeCancellationToken ( CancellationTokenType . testRunner ) ;
168197 return this . tests ;
169198 } ) . catch ( reason => {
170- if ( this . cancellationToken && this . cancellationToken . isCancellationRequested ) {
199+ if ( this . testRunnerCancellationToken && this . testRunnerCancellationToken . isCancellationRequested ) {
171200 reason = CANCELLATION_REASON ;
172201 this . _status = TestStatus . Idle ;
173202 }
174203 else {
175204 this . _status = TestStatus . Error ;
176205 }
177- this . disposeCancellationToken ( ) ;
206+ this . disposeCancellationToken ( CancellationTokenType . testRunner ) ;
178207 return Promise . reject < Tests > ( reason ) ;
179208 } ) ;
180209 }
181210 abstract runTestImpl ( tests : Tests , testsToRun ?: TestsToRun , runFailedTests ?: boolean , debug ?: boolean ) : Promise < any > ;
182- }
211+ }
0 commit comments