@@ -1657,13 +1657,14 @@ public void CancelledBuildWithDelay40()
16571657 string contents = CleanupFileContents ( @"
16581658<Project xmlns='msbuildnamespace' ToolsVersion='msbuilddefaulttoolsversion'>
16591659 <Target Name='test'>
1660- <Exec Command='" + Helpers . GetSleepCommand ( TimeSpan . FromSeconds ( 10 ) ) + @"'/>
1660+ <Exec Command='" + Helpers . GetSleepCommand ( TimeSpan . FromSeconds ( 20 ) ) + @"'/>
16611661 <Message Text='[errormessage]'/>
16621662 </Target>
16631663</Project>
16641664" ) ;
16651665 BuildRequestData data = GetBuildRequestData ( contents , Array . Empty < string > ( ) , MSBuildDefaultToolsVersion ) ;
16661666 _buildManager . BeginBuild ( _parameters ) ;
1667+ Stopwatch sw = Stopwatch . StartNew ( ) ;
16671668 BuildSubmission asyncResult = _buildManager . PendBuildRequest ( data ) ;
16681669 asyncResult . ExecuteAsync ( null , null ) ;
16691670
@@ -1675,6 +1676,50 @@ public void CancelledBuildWithDelay40()
16751676
16761677 Assert . Equal ( BuildResultCode . Failure , result . OverallResult ) ; // "Build should have failed."
16771678 _logger . AssertLogDoesntContain ( "[errormessage]" ) ;
1679+ // The build should bail out immediately after executing CancelAllSubmissions, build stalling for a longer time
1680+ // is very unexpected.
1681+ sw . Elapsed . ShouldBeLessThan ( TimeSpan . FromSeconds ( 10 ) ) ;
1682+ }
1683+
1684+ /// <summary>
1685+ /// A canceled build which waits for the task to get started before canceling. Because it is a 12.. task, we should
1686+ /// cancel the task and exit out after a short period wherein we wait for the task to exit cleanly.
1687+ ///
1688+ /// This test also exercises the possibility of CancelAllSubmissions being executed after EndBuild -
1689+ /// which can happen even if they are synchronously executed in expected order - the CancelAllSubmissions is internally
1690+ /// asynchronous and hence part of the execution can happen after EndBuild.
1691+ /// </summary>
1692+ [ Fact ]
1693+ public void CancelledBuildWithDelay40_WithThreatSwap ( )
1694+ {
1695+ string contents = CleanupFileContents ( @"
1696+ <Project xmlns='msbuildnamespace' ToolsVersion='msbuilddefaulttoolsversion'>
1697+ <Target Name='test'>
1698+ <Exec Command='" + Helpers . GetSleepCommand ( TimeSpan . FromSeconds ( 20 ) ) + @"'/>
1699+ <Message Text='[errormessage]'/>
1700+ </Target>
1701+ </Project>
1702+ " ) ;
1703+ BuildRequestData data = GetBuildRequestData ( contents , Array . Empty < string > ( ) , MSBuildDefaultToolsVersion ) ;
1704+ _buildManager . BeginBuild ( _parameters ) ;
1705+ Stopwatch sw = Stopwatch . StartNew ( ) ;
1706+ BuildSubmission asyncResult = _buildManager . PendBuildRequest ( data ) ;
1707+ asyncResult . ExecuteAsync ( null , null ) ;
1708+
1709+ Thread . Sleep ( 500 ) ;
1710+ // Simulate the case where CancelAllSubmissions is called after EndBuild or its internal queued task is swapped
1711+ // and executed after EndBuild starts execution.
1712+ System . Threading . Tasks . Task . Delay ( 500 ) . ContinueWith ( t => _buildManager . CancelAllSubmissions ( ) ) ;
1713+ _buildManager . EndBuild ( ) ;
1714+
1715+ asyncResult . WaitHandle . WaitOne ( ) ;
1716+ BuildResult result = asyncResult . BuildResult ;
1717+
1718+ Assert . Equal ( BuildResultCode . Failure , result . OverallResult ) ; // "Build should have failed."
1719+ _logger . AssertLogDoesntContain ( "[errormessage]" ) ;
1720+ // The build should bail out immediately after executing CancelAllSubmissions, build stalling for a longer time
1721+ // is very unexpected.
1722+ sw . Elapsed . ShouldBeLessThan ( TimeSpan . FromSeconds ( 10 ) ) ;
16781723 }
16791724
16801725 /// <summary>
0 commit comments