@@ -19,6 +19,7 @@ import {
1919 canRunTests ,
2020 closeNotebooksAndCleanUpAfterTests ,
2121 deleteAllCellsAndWait ,
22+ disposeAllDisposables ,
2223 insertPythonCellAndWait ,
2324 startJupyter ,
2425 swallowSavingOfNotebooks
@@ -39,6 +40,7 @@ suite('DataScience - VSCode Notebook - Restart/Interrupt/Cancel/Errors', functio
3940 let executionService : INotebookExecutionService ;
4041 let vscEditor : VSCNotebookEditor ;
4142 let vscodeNotebook : IVSCodeNotebook ;
43+ const suiteDisposables : IDisposable [ ] = [ ] ;
4244 suiteSetup ( async function ( ) {
4345 this . timeout ( 15_000 ) ;
4446 api = await initialize ( ) ;
@@ -60,7 +62,8 @@ suite('DataScience - VSCode Notebook - Restart/Interrupt/Cancel/Errors', functio
6062 vscEditor = vscodeNotebook . activeNotebookEditor ! ;
6163 } ) ;
6264 setup ( deleteAllCellsAndWait ) ;
63- suiteTeardown ( ( ) => closeNotebooksAndCleanUpAfterTests ( disposables ) ) ;
65+ teardown ( ( ) => disposeAllDisposables ( suiteDisposables ) ) ;
66+ suiteTeardown ( ( ) => closeNotebooksAndCleanUpAfterTests ( disposables . concat ( suiteDisposables ) ) ) ;
6467
6568 test ( 'Cancelling token will cancel cell execution (slow)' , async ( ) => {
6669 await insertPythonCellAndWait ( 'import time\nfor i in range(10000):\n print(i)\n time.sleep(0.1)' , 0 ) ;
@@ -122,6 +125,39 @@ suite('DataScience - VSCode Notebook - Restart/Interrupt/Cancel/Errors', functio
122125
123126 await waitForCondition ( async ( ) => assertVSCCellIsIdle ( cell ) , 1_000 , 'Execution not cancelled' ) ;
124127 } ) ;
128+ test ( 'When running entire notebook, clicking VSCode Stop button should trigger a single interrupt, not one per cell' , async ( ) => {
129+ await insertPythonCellAndWait ( 'import time\nfor i in range(10000):\n print(i)\n time.sleep(0.1)' , 0 ) ;
130+ await insertPythonCellAndWait ( 'import time\nfor i in range(10000):\n print(i)\n time.sleep(0.1)' , 0 ) ;
131+ await insertPythonCellAndWait ( 'import time\nfor i in range(10000):\n print(i)\n time.sleep(0.1)' , 0 ) ;
132+ const cell1 = vscEditor . document . cells [ 0 ] ;
133+ const cell2 = vscEditor . document . cells [ 1 ] ;
134+ const cell3 = vscEditor . document . cells [ 2 ] ;
135+
136+ const interrupt = sinon . spy ( editorProvider . activeEditor ! , 'interruptKernel' ) ;
137+ suiteDisposables . push ( { dispose : ( ) => interrupt . restore ( ) } ) ;
138+
139+ await commands . executeCommand ( 'notebook.execute' ) ;
140+
141+ // Wait for cells to get busy.
142+ await waitForCondition (
143+ async ( ) => assertVSCCellIsRunning ( cell1 ) && assertVSCCellIsRunning ( cell2 ) && assertVSCCellIsRunning ( cell3 ) ,
144+ 15_000 ,
145+ 'Cells not being executed'
146+ ) ;
147+
148+ // Cancel execution.
149+ await sleep ( 1_000 ) ;
150+ await commands . executeCommand ( 'notebook.cancelExecution' ) ;
151+
152+ // Wait for ?s, and verify cells are not running.
153+ await waitForCondition (
154+ async ( ) => assertVSCCellIsIdle ( cell1 ) && assertVSCCellIsIdle ( cell2 ) && assertVSCCellIsIdle ( cell3 ) ,
155+ 15_000 ,
156+ 'Cells are still running'
157+ ) ;
158+
159+ assert . equal ( interrupt . callCount , 1 , 'Interrupt should have been invoked only once' ) ;
160+ } ) ;
125161 test ( 'Restarting kernel will cancel cell execution (slow)' , async ( ) => {
126162 await insertPythonCellAndWait ( 'import time\nfor i in range(10000):\n print(i)\n time.sleep(0.1)' , 0 ) ;
127163 const cell = vscEditor . document . cells [ 0 ] ;
@@ -136,8 +172,21 @@ suite('DataScience - VSCode Notebook - Restart/Interrupt/Cancel/Errors', functio
136172 assertVSCCellIsRunning ( cell ) ;
137173
138174 // Restart the kernel.
139- await commands . executeCommand ( 'python.datascience.notebookeditor.restartkernel' ) ;
175+ const restartPromise = commands . executeCommand ( 'python.datascience.notebookeditor.restartkernel' ) ;
140176
141177 await waitForCondition ( async ( ) => assertVSCCellIsIdle ( cell ) , 1_000 , 'Execution not cancelled' ) ;
178+
179+ // Wait before we execute cells again.
180+ await restartPromise ;
181+ await commands . executeCommand ( 'notebook.execute' ) ;
182+
183+ // Wait for cell to get busy.
184+ await waitForCondition ( async ( ) => assertVSCCellIsRunning ( cell ) , 15_000 , 'Cell not being executed' ) ;
185+
186+ // Cleanup (don't leave them running).
187+ await commands . executeCommand ( 'notebook.cancelExecution' ) ;
188+
189+ // Wait for ?s, and verify cells are not running.
190+ await waitForCondition ( async ( ) => assertVSCCellIsIdle ( cell ) , 15_000 , 'Cell is still running' ) ;
142191 } ) ;
143192} ) ;
0 commit comments