@@ -1821,7 +1821,8 @@ function createToolcacheEntry(
18211821/**
18221822 * Stubs out the download and the diagnostic sink, then downloads the CodeQL tools.
18231823 *
1824- * @returns the extraction directory and the toolcache cleanup diagnostic, if emitted.
1824+ * @returns the extraction directory and, if the toolcache cleanup diagnostic was emitted, the
1825+ * cleanup duration it reports and its other attributes.
18251826 */
18261827async function runDownloadCodeQL (
18271828 toolcacheRoot : string ,
@@ -1837,6 +1838,7 @@ async function runDownloadCodeQL(
18371838) : Promise < {
18381839 codeqlFolder : string ;
18391840 cleanupDiagnostic : toolsDownload . ToolcacheCleanupResult | undefined ;
1841+ cleanupDurationMs : number | undefined ;
18401842} > {
18411843 stubDownloadAndExtract ( ) ;
18421844 const addDiagnostic = sinon . stub ( diagnostics , "addNoLanguageDiagnostic" ) ;
@@ -1866,11 +1868,21 @@ async function runDownloadCodeQL(
18661868 . map ( ( call ) => call . args [ 1 ] )
18671869 . find ( ( d ) => d . source ?. id === "codeql-action/toolcache-bundle-cleanup" ) ;
18681870
1869- return {
1870- codeqlFolder,
1871- cleanupDiagnostic : diagnostic ?. attributes as
1872- toolsDownload . ToolcacheCleanupResult | undefined ,
1873- } ;
1871+ if ( diagnostic === undefined ) {
1872+ return {
1873+ codeqlFolder,
1874+ cleanupDiagnostic : undefined ,
1875+ cleanupDurationMs : undefined ,
1876+ } ;
1877+ }
1878+
1879+ // The duration varies between runs, so split it out to let tests compare the other attributes
1880+ // exactly.
1881+ const { durationMs, ...cleanupDiagnostic } =
1882+ diagnostic . attributes as toolsDownload . ToolcacheCleanupResult & {
1883+ durationMs : number ;
1884+ } ;
1885+ return { codeqlFolder, cleanupDiagnostic, cleanupDurationMs : durationMs } ;
18741886}
18751887
18761888/**
@@ -1991,6 +2003,35 @@ test.serial(
19912003 } ,
19922004) ;
19932005
2006+ test . serial (
2007+ "downloadCodeQLBundle reports the total time taken to clean up the toolcache" ,
2008+ async ( t ) => {
2009+ await withTmpDir ( async ( tmpDir ) => {
2010+ setupActionsVars ( tmpDir , tmpDir ) ;
2011+
2012+ createToolcacheEntry ( tmpDir , "CodeQL" , CLEANUP_CLI_VERSION ) ;
2013+ createToolcacheEntry ( tmpDir , "CodeQL" , CLEANUP_STALE_VERSION ) ;
2014+
2015+ // Advance the clock by 1.5s each time a path is deleted, so that deleting both versions
2016+ // takes 3s.
2017+ let elapsedMs = 1000 ;
2018+ sinon . stub ( performance , "now" ) . callsFake ( ( ) => elapsedMs ) ;
2019+ const rm = fs . promises . rm ;
2020+ sinon . stub ( fs . promises , "rm" ) . callsFake ( async ( ...args ) => {
2021+ elapsedMs += 1500 ;
2022+ await rm ( ...args ) ;
2023+ } ) ;
2024+
2025+ const { cleanupDurationMs } = await runDownloadCodeQL (
2026+ tmpDir ,
2027+ CLEANUP_BUNDLE_VERSION ,
2028+ ) ;
2029+
2030+ t . is ( cleanupDurationMs , 3000 ) ;
2031+ } ) ;
2032+ } ,
2033+ ) ;
2034+
19942035test . serial (
19952036 "downloadCodeQLBundle reports no deleted versions when the toolcache has no CodeQL bundles" ,
19962037 async ( t ) => {
0 commit comments