@@ -284,6 +284,34 @@ public async Task Download(CancellationToken ct)
284284 Assert . That ( await File . ReadAllTextAsync ( destPath , ct ) , Is . EqualTo ( "test" ) ) ;
285285 }
286286
287+ [ Test ( Description = "Perform 2 downloads with the same destination" ) ]
288+ [ CancelAfter ( 30_000 ) ]
289+ public async Task DownloadSameDest ( CancellationToken ct )
290+ {
291+ using var httpServer = EchoServer ( ) ;
292+ var url0 = new Uri ( httpServer . BaseUrl + "/test0" ) ;
293+ var url1 = new Uri ( httpServer . BaseUrl + "/test1" ) ;
294+ var destPath = Path . Combine ( _tempDir , "test" ) ;
295+
296+ var manager = new Downloader ( NullLogger < Downloader > . Instance ) ;
297+ var startTask0 = manager . StartDownloadAsync ( new HttpRequestMessage ( HttpMethod . Get , url0 ) , destPath ,
298+ NullDownloadValidator . Instance , ct ) ;
299+ var startTask1 = manager . StartDownloadAsync ( new HttpRequestMessage ( HttpMethod . Get , url1 ) , destPath ,
300+ NullDownloadValidator . Instance , ct ) ;
301+ var dlTask0 = await startTask0 ;
302+ await dlTask0 . Task ;
303+ Assert . That ( dlTask0 . TotalBytes , Is . EqualTo ( 5 ) ) ;
304+ Assert . That ( dlTask0 . BytesRead , Is . EqualTo ( 5 ) ) ;
305+ Assert . That ( dlTask0 . Progress , Is . EqualTo ( 1 ) ) ;
306+ Assert . That ( dlTask0 . IsCompleted , Is . True ) ;
307+ var dlTask1 = await startTask1 ;
308+ await dlTask1 . Task ;
309+ Assert . That ( dlTask1 . TotalBytes , Is . EqualTo ( 5 ) ) ;
310+ Assert . That ( dlTask1 . BytesRead , Is . EqualTo ( 5 ) ) ;
311+ Assert . That ( dlTask1 . Progress , Is . EqualTo ( 1 ) ) ;
312+ Assert . That ( dlTask1 . IsCompleted , Is . True ) ;
313+ }
314+
287315 [ Test ( Description = "Download with custom headers" ) ]
288316 [ CancelAfter ( 30_000 ) ]
289317 public async Task WithHeaders ( CancellationToken ct )
@@ -347,17 +375,17 @@ public async Task DownloadExistingDifferentContent(CancellationToken ct)
347375
348376 [ Test ( Description = "Unexpected response code from server" ) ]
349377 [ CancelAfter ( 30_000 ) ]
350- public void UnexpectedResponseCode ( CancellationToken ct )
378+ public async Task UnexpectedResponseCode ( CancellationToken ct )
351379 {
352380 using var httpServer = new TestHttpServer ( ctx => { ctx . Response . StatusCode = 404 ; } ) ;
353381 var url = new Uri ( httpServer . BaseUrl + "/test" ) ;
354382 var destPath = Path . Combine ( _tempDir , "test" ) ;
355383
356384 var manager = new Downloader ( NullLogger < Downloader > . Instance ) ;
357- // The "outer " Task should fail.
358- var ex = Assert . ThrowsAsync < HttpRequestException > ( async ( ) =>
359- await manager . StartDownloadAsync ( new HttpRequestMessage ( HttpMethod . Get , url ) , destPath ,
360- NullDownloadValidator . Instance , ct ) ) ;
385+ // The "inner " Task should fail.
386+ var dlTask = await manager . StartDownloadAsync ( new HttpRequestMessage ( HttpMethod . Get , url ) , destPath ,
387+ NullDownloadValidator . Instance , ct ) ;
388+ var ex = Assert . ThrowsAsync < HttpRequestException > ( async ( ) => await dlTask . Task ) ;
361389 Assert . That ( ex . Message , Does . Contain ( "404" ) ) ;
362390 }
363391
@@ -384,22 +412,6 @@ public async Task MismatchedETag(CancellationToken ct)
384412 Assert . That ( ex . Message , Does . Contain ( "ETag does not match SHA1 hash of downloaded file" ) . And . Contains ( "beef" ) ) ;
385413 }
386414
387- [ Test ( Description = "Timeout on response headers" ) ]
388- [ CancelAfter ( 30_000 ) ]
389- public void CancelledOuter ( CancellationToken ct )
390- {
391- using var httpServer = new TestHttpServer ( async _ => { await Task . Delay ( TimeSpan . FromSeconds ( 5 ) , ct ) ; } ) ;
392- var url = new Uri ( httpServer . BaseUrl + "/test" ) ;
393- var destPath = Path . Combine ( _tempDir , "test" ) ;
394-
395- var manager = new Downloader ( NullLogger < Downloader > . Instance ) ;
396- // The "outer" Task should fail.
397- var smallerCt = new CancellationTokenSource ( TimeSpan . FromSeconds ( 1 ) ) . Token ;
398- Assert . ThrowsAsync < TaskCanceledException > (
399- async ( ) => await manager . StartDownloadAsync ( new HttpRequestMessage ( HttpMethod . Get , url ) , destPath ,
400- NullDownloadValidator . Instance , smallerCt ) ) ;
401- }
402-
403415 [ Test ( Description = "Timeout on response body" ) ]
404416 [ CancelAfter ( 30_000 ) ]
405417 public async Task CancelledInner ( CancellationToken ct )
@@ -451,12 +463,10 @@ public async Task ValidationFailureExistingFile(CancellationToken ct)
451463 await File . WriteAllTextAsync ( destPath , "test" , ct ) ;
452464
453465 var manager = new Downloader ( NullLogger < Downloader > . Instance ) ;
454- // The "outer" Task should fail because the inner task never starts.
455- var ex = Assert . ThrowsAsync < Exception > ( async ( ) =>
456- {
457- await manager . StartDownloadAsync ( new HttpRequestMessage ( HttpMethod . Get , url ) , destPath ,
458- new TestDownloadValidator ( new Exception ( "test exception" ) ) , ct ) ;
459- } ) ;
466+ var dlTask = await manager . StartDownloadAsync ( new HttpRequestMessage ( HttpMethod . Get , url ) , destPath ,
467+ new TestDownloadValidator ( new Exception ( "test exception" ) ) , ct ) ;
468+ // The "inner" Task should fail.
469+ var ex = Assert . ThrowsAsync < Exception > ( async ( ) => { await dlTask . Task ; } ) ;
460470 Assert . That ( ex . Message , Does . Contain ( "Existing file failed validation" ) ) ;
461471 Assert . That ( ex . InnerException , Is . Not . Null ) ;
462472 Assert . That ( ex . InnerException ! . Message , Is . EqualTo ( "test exception" ) ) ;
0 commit comments