@@ -11,8 +11,10 @@ import * as apiClient from "./api-client";
1111import { createStubCodeQL } from "./codeql" ;
1212import { Config } from "./config-utils" ;
1313import { cleanupAndUploadDatabases } from "./database-upload" ;
14+ import { Feature } from "./feature-flags" ;
1415import * as gitUtils from "./git-utils" ;
1516import { BuiltInLanguage } from "./languages" ;
17+ import { OverlayDatabaseMode } from "./overlay/overlay-database-mode" ;
1618import { RepositoryNwo } from "./repository" ;
1719import {
1820 checkExpectedLogMessages ,
@@ -24,6 +26,7 @@ import {
2426 setupTests ,
2527} from "./testing-utils" ;
2628import {
29+ CleanupLevel ,
2730 GitHubVariant ,
2831 HTTPError ,
2932 initializeEnvironment ,
@@ -335,3 +338,146 @@ test.serial("Successfully uploading a database to GHEC-DR", async (t) => {
335338 ) ;
336339 } ) ;
337340} ) ;
341+
342+ test . serial (
343+ "Records overlay and clear cleanup sizes when uploading an overlay-base database" ,
344+ async ( t ) => {
345+ await withTmpDir ( async ( tmpDir ) => {
346+ setupActionsVars ( tmpDir , tmpDir ) ;
347+ sinon
348+ . stub ( actionsUtil , "getRequiredInput" )
349+ . withArgs ( "upload-database" )
350+ . returns ( "true" ) ;
351+ sinon . stub ( gitUtils , "isAnalyzingDefaultBranch" ) . resolves ( true ) ;
352+
353+ await mockHttpRequests ( 201 ) ;
354+
355+ // Track the cleanup level passed to each cleanup so that the database
356+ // bundle stub can write a differently-sized bundle for each level.
357+ const cleanupLevels : CleanupLevel [ ] = [ ] ;
358+ let lastCleanupLevel : CleanupLevel | undefined ;
359+ const overlaySizeBytes = 100 ;
360+ const clearSizeBytes = 50 ;
361+ const codeql = createStubCodeQL ( {
362+ async databaseCleanupCluster ( _config , cleanupLevel ) {
363+ cleanupLevels . push ( cleanupLevel ) ;
364+ lastCleanupLevel = cleanupLevel ;
365+ } ,
366+ async databaseBundle ( _databasePath , outputFilePath ) {
367+ const sizeBytes =
368+ lastCleanupLevel === CleanupLevel . Overlay
369+ ? overlaySizeBytes
370+ : clearSizeBytes ;
371+ fs . writeFileSync ( outputFilePath , "x" . repeat ( sizeBytes ) ) ;
372+ } ,
373+ } ) ;
374+
375+ const config = getTestConfig ( tmpDir ) ;
376+ config . overlayDatabaseMode = OverlayDatabaseMode . OverlayBase ;
377+
378+ const loggedMessages : LoggedMessage [ ] = [ ] ;
379+ const results = await cleanupAndUploadDatabases (
380+ testRepoName ,
381+ codeql ,
382+ config ,
383+ testApiDetails ,
384+ createFeatures ( [ Feature . UploadOverlayDbToApi ] ) ,
385+ getRecordingLogger ( loggedMessages ) ,
386+ ) ;
387+
388+ // The database should be cleaned up at the `overlay` level for the upload
389+ // and then re-cleaned at the `clear` level to measure its size.
390+ t . deepEqual ( cleanupLevels , [ CleanupLevel . Overlay , CleanupLevel . Clear ] ) ;
391+
392+ t . is ( results . length , 1 ) ;
393+ t . is ( results [ 0 ] . is_overlay_base , true ) ;
394+ t . is ( results [ 0 ] . zipped_upload_size_bytes , overlaySizeBytes ) ;
395+ t . is ( results [ 0 ] . clear_cleanup_zipped_size_bytes , clearSizeBytes ) ;
396+ t . is ( typeof results [ 0 ] . clear_cleanup_measurement_duration_ms , "number" ) ;
397+ } ) ;
398+ } ,
399+ ) ;
400+
401+ test . serial (
402+ "Does not measure clear cleanup size for a regular (non-overlay-base) upload" ,
403+ async ( t ) => {
404+ await withTmpDir ( async ( tmpDir ) => {
405+ setupActionsVars ( tmpDir , tmpDir ) ;
406+ sinon
407+ . stub ( actionsUtil , "getRequiredInput" )
408+ . withArgs ( "upload-database" )
409+ . returns ( "true" ) ;
410+ sinon . stub ( gitUtils , "isAnalyzingDefaultBranch" ) . resolves ( true ) ;
411+
412+ await mockHttpRequests ( 201 ) ;
413+
414+ const cleanupLevels : CleanupLevel [ ] = [ ] ;
415+ const codeql = createStubCodeQL ( {
416+ async databaseCleanupCluster ( _config , cleanupLevel ) {
417+ cleanupLevels . push ( cleanupLevel ) ;
418+ } ,
419+ async databaseBundle ( _databasePath , outputFilePath ) {
420+ fs . writeFileSync ( outputFilePath , "" ) ;
421+ } ,
422+ } ) ;
423+
424+ const results = await cleanupAndUploadDatabases (
425+ testRepoName ,
426+ codeql ,
427+ getTestConfig ( tmpDir ) ,
428+ testApiDetails ,
429+ createFeatures ( [ Feature . UploadOverlayDbToApi ] ) ,
430+ getRecordingLogger ( [ ] ) ,
431+ ) ;
432+
433+ // A regular upload is cleaned only once, at the `clear` level.
434+ t . deepEqual ( cleanupLevels , [ CleanupLevel . Clear ] ) ;
435+ t . is ( results [ 0 ] . is_overlay_base , false ) ;
436+ t . is ( results [ 0 ] . clear_cleanup_zipped_size_bytes , undefined ) ;
437+ t . is ( results [ 0 ] . clear_cleanup_measurement_duration_ms , undefined ) ;
438+ } ) ;
439+ } ,
440+ ) ;
441+
442+ test . serial ( "Does not measure clear cleanup size in debug mode" , async ( t ) => {
443+ await withTmpDir ( async ( tmpDir ) => {
444+ setupActionsVars ( tmpDir , tmpDir ) ;
445+ sinon
446+ . stub ( actionsUtil , "getRequiredInput" )
447+ . withArgs ( "upload-database" )
448+ . returns ( "true" ) ;
449+ sinon . stub ( gitUtils , "isAnalyzingDefaultBranch" ) . resolves ( true ) ;
450+
451+ await mockHttpRequests ( 201 ) ;
452+
453+ const cleanupLevels : CleanupLevel [ ] = [ ] ;
454+ const codeql = createStubCodeQL ( {
455+ async databaseCleanupCluster ( _config , cleanupLevel ) {
456+ cleanupLevels . push ( cleanupLevel ) ;
457+ } ,
458+ async databaseBundle ( _databasePath , outputFilePath ) {
459+ fs . writeFileSync ( outputFilePath , "" ) ;
460+ } ,
461+ } ) ;
462+
463+ const config = getTestConfig ( tmpDir ) ;
464+ config . overlayDatabaseMode = OverlayDatabaseMode . OverlayBase ;
465+ config . debugMode = true ;
466+
467+ const results = await cleanupAndUploadDatabases (
468+ testRepoName ,
469+ codeql ,
470+ config ,
471+ testApiDetails ,
472+ createFeatures ( [ Feature . UploadOverlayDbToApi ] ) ,
473+ getRecordingLogger ( [ ] ) ,
474+ ) ;
475+
476+ // In debug mode we clean up at the `overlay` level for the upload but skip
477+ // the additional `clear` cleanup, to preserve the database for debugging.
478+ t . deepEqual ( cleanupLevels , [ CleanupLevel . Overlay ] ) ;
479+ t . is ( results [ 0 ] . is_overlay_base , true ) ;
480+ t . is ( results [ 0 ] . clear_cleanup_zipped_size_bytes , undefined ) ;
481+ t . is ( results [ 0 ] . clear_cleanup_measurement_duration_ms , undefined ) ;
482+ } ) ;
483+ } ) ;
0 commit comments