@@ -7,6 +7,7 @@ import test from "ava";
77import * as sinon from "sinon" ;
88
99import { cacheKeyHashLength } from "./caching-utils" ;
10+ import * as cachingUtils from "./caching-utils" ;
1011import { createStubCodeQL } from "./codeql" ;
1112import {
1213 CacheConfig ,
@@ -20,6 +21,8 @@ import {
2021 downloadDependencyCaches ,
2122 CacheHitKind ,
2223 cacheKey ,
24+ uploadDependencyCaches ,
25+ CacheStoreResult ,
2326} from "./dependency-caching" ;
2427import { Feature } from "./feature-flags" ;
2528import { KnownLanguage } from "./languages" ;
@@ -29,6 +32,7 @@ import {
2932 getRecordingLogger ,
3033 checkExpectedLogMessages ,
3134 LoggedMessage ,
35+ createTestConfig ,
3236} from "./testing-utils" ;
3337import { withTmpDir } from "./util" ;
3438
@@ -365,6 +369,206 @@ test("downloadDependencyCaches - restores caches with feature keys if features a
365369 t . assert ( restoreCacheStub . calledOnce ) ;
366370} ) ;
367371
372+ test ( "uploadDependencyCaches - skips upload for a language with no cache config" , async ( t ) => {
373+ const codeql = createStubCodeQL ( { } ) ;
374+ const messages : LoggedMessage [ ] = [ ] ;
375+ const logger = getRecordingLogger ( messages ) ;
376+ const features = createFeatures ( [ ] ) ;
377+ const config = createTestConfig ( {
378+ languages : [ KnownLanguage . actions ] ,
379+ } ) ;
380+
381+ const result = await uploadDependencyCaches ( codeql , features , config , logger ) ;
382+ t . is ( result . length , 0 ) ;
383+ checkExpectedLogMessages ( t , messages , [
384+ "Skipping upload of dependency cache for actions" ,
385+ ] ) ;
386+ } ) ;
387+
388+ test ( "uploadDependencyCaches - skips upload if no files for the hash exist" , async ( t ) => {
389+ const codeql = createStubCodeQL ( { } ) ;
390+ const messages : LoggedMessage [ ] = [ ] ;
391+ const logger = getRecordingLogger ( messages ) ;
392+ const features = createFeatures ( [ ] ) ;
393+ const config = createTestConfig ( {
394+ languages : [ KnownLanguage . go ] ,
395+ } ) ;
396+
397+ const makePatternCheckStub = sinon . stub ( internal , "makePatternCheck" ) ;
398+ makePatternCheckStub . resolves ( undefined ) ;
399+
400+ const result = await uploadDependencyCaches ( codeql , features , config , logger ) ;
401+ t . is ( result . length , 1 ) ;
402+ t . is ( result [ 0 ] . language , KnownLanguage . go ) ;
403+ t . is ( result [ 0 ] . result , CacheStoreResult . NoHash ) ;
404+ } ) ;
405+
406+ test ( "uploadDependencyCaches - skips upload if we know the cache already exists" , async ( t ) => {
407+ process . env [ "RUNNER_OS" ] = "Linux" ;
408+
409+ const codeql = createStubCodeQL ( { } ) ;
410+ const messages : LoggedMessage [ ] = [ ] ;
411+ const logger = getRecordingLogger ( messages ) ;
412+ const features = createFeatures ( [ ] ) ;
413+
414+ const mockHash = "abcdef" ;
415+ sinon . stub ( glob , "hashFiles" ) . resolves ( mockHash ) ;
416+
417+ const makePatternCheckStub = sinon . stub ( internal , "makePatternCheck" ) ;
418+ makePatternCheckStub
419+ . withArgs ( CSHARP_BASE_PATTERNS )
420+ . resolves ( CSHARP_BASE_PATTERNS ) ;
421+
422+ const primaryCacheKey = await cacheKey (
423+ codeql ,
424+ features ,
425+ KnownLanguage . csharp ,
426+ CSHARP_BASE_PATTERNS ,
427+ ) ;
428+
429+ const config = createTestConfig ( {
430+ languages : [ KnownLanguage . csharp ] ,
431+ dependencyCachingRestoredKeys : [ primaryCacheKey ] ,
432+ } ) ;
433+
434+ const result = await uploadDependencyCaches ( codeql , features , config , logger ) ;
435+ t . is ( result . length , 1 ) ;
436+ t . is ( result [ 0 ] . language , KnownLanguage . csharp ) ;
437+ t . is ( result [ 0 ] . result , CacheStoreResult . Duplicate ) ;
438+ } ) ;
439+
440+ test ( "uploadDependencyCaches - skips upload if cache size is 0" , async ( t ) => {
441+ process . env [ "RUNNER_OS" ] = "Linux" ;
442+
443+ const codeql = createStubCodeQL ( { } ) ;
444+ const messages : LoggedMessage [ ] = [ ] ;
445+ const logger = getRecordingLogger ( messages ) ;
446+ const features = createFeatures ( [ ] ) ;
447+
448+ const mockHash = "abcdef" ;
449+ sinon . stub ( glob , "hashFiles" ) . resolves ( mockHash ) ;
450+
451+ const makePatternCheckStub = sinon . stub ( internal , "makePatternCheck" ) ;
452+ makePatternCheckStub
453+ . withArgs ( CSHARP_BASE_PATTERNS )
454+ . resolves ( CSHARP_BASE_PATTERNS ) ;
455+
456+ sinon . stub ( cachingUtils , "getTotalCacheSize" ) . resolves ( 0 ) ;
457+
458+ const config = createTestConfig ( {
459+ languages : [ KnownLanguage . csharp ] ,
460+ } ) ;
461+
462+ const result = await uploadDependencyCaches ( codeql , features , config , logger ) ;
463+ t . is ( result . length , 1 ) ;
464+ t . is ( result [ 0 ] . language , KnownLanguage . csharp ) ;
465+ t . is ( result [ 0 ] . result , CacheStoreResult . Empty ) ;
466+
467+ checkExpectedLogMessages ( t , messages , [
468+ "Skipping upload of dependency cache" ,
469+ ] ) ;
470+ } ) ;
471+
472+ test ( "uploadDependencyCaches - uploads caches when all requirements are met" , async ( t ) => {
473+ process . env [ "RUNNER_OS" ] = "Linux" ;
474+
475+ const codeql = createStubCodeQL ( { } ) ;
476+ const messages : LoggedMessage [ ] = [ ] ;
477+ const logger = getRecordingLogger ( messages ) ;
478+ const features = createFeatures ( [ ] ) ;
479+
480+ const mockHash = "abcdef" ;
481+ sinon . stub ( glob , "hashFiles" ) . resolves ( mockHash ) ;
482+
483+ const makePatternCheckStub = sinon . stub ( internal , "makePatternCheck" ) ;
484+ makePatternCheckStub
485+ . withArgs ( CSHARP_BASE_PATTERNS )
486+ . resolves ( CSHARP_BASE_PATTERNS ) ;
487+
488+ sinon . stub ( cachingUtils , "getTotalCacheSize" ) . resolves ( 1024 ) ;
489+ sinon . stub ( actionsCache , "saveCache" ) . resolves ( ) ;
490+
491+ const config = createTestConfig ( {
492+ languages : [ KnownLanguage . csharp ] ,
493+ } ) ;
494+
495+ const result = await uploadDependencyCaches ( codeql , features , config , logger ) ;
496+ t . is ( result . length , 1 ) ;
497+ t . is ( result [ 0 ] . language , KnownLanguage . csharp ) ;
498+ t . is ( result [ 0 ] . result , CacheStoreResult . Stored ) ;
499+ t . is ( result [ 0 ] . upload_size_bytes , 1024 ) ;
500+
501+ checkExpectedLogMessages ( t , messages , [ "Uploading cache of size" ] ) ;
502+ } ) ;
503+
504+ test ( "uploadDependencyCaches - catches `ReserveCacheError` exceptions" , async ( t ) => {
505+ process . env [ "RUNNER_OS" ] = "Linux" ;
506+
507+ const codeql = createStubCodeQL ( { } ) ;
508+ const messages : LoggedMessage [ ] = [ ] ;
509+ const logger = getRecordingLogger ( messages ) ;
510+ const features = createFeatures ( [ ] ) ;
511+
512+ const mockHash = "abcdef" ;
513+ sinon . stub ( glob , "hashFiles" ) . resolves ( mockHash ) ;
514+
515+ const makePatternCheckStub = sinon . stub ( internal , "makePatternCheck" ) ;
516+ makePatternCheckStub
517+ . withArgs ( CSHARP_BASE_PATTERNS )
518+ . resolves ( CSHARP_BASE_PATTERNS ) ;
519+
520+ sinon . stub ( cachingUtils , "getTotalCacheSize" ) . resolves ( 1024 ) ;
521+ sinon
522+ . stub ( actionsCache , "saveCache" )
523+ . throws ( new actionsCache . ReserveCacheError ( "Already in use" ) ) ;
524+
525+ const config = createTestConfig ( {
526+ languages : [ KnownLanguage . csharp ] ,
527+ } ) ;
528+
529+ await t . notThrowsAsync ( async ( ) => {
530+ const result = await uploadDependencyCaches (
531+ codeql ,
532+ features ,
533+ config ,
534+ logger ,
535+ ) ;
536+ t . is ( result . length , 1 ) ;
537+ t . is ( result [ 0 ] . language , KnownLanguage . csharp ) ;
538+ t . is ( result [ 0 ] . result , CacheStoreResult . Duplicate ) ;
539+
540+ checkExpectedLogMessages ( t , messages , [ "Not uploading cache for" ] ) ;
541+ } ) ;
542+ } ) ;
543+
544+ test ( "uploadDependencyCaches - throws other exceptions" , async ( t ) => {
545+ process . env [ "RUNNER_OS" ] = "Linux" ;
546+
547+ const codeql = createStubCodeQL ( { } ) ;
548+ const messages : LoggedMessage [ ] = [ ] ;
549+ const logger = getRecordingLogger ( messages ) ;
550+ const features = createFeatures ( [ ] ) ;
551+
552+ const mockHash = "abcdef" ;
553+ sinon . stub ( glob , "hashFiles" ) . resolves ( mockHash ) ;
554+
555+ const makePatternCheckStub = sinon . stub ( internal , "makePatternCheck" ) ;
556+ makePatternCheckStub
557+ . withArgs ( CSHARP_BASE_PATTERNS )
558+ . resolves ( CSHARP_BASE_PATTERNS ) ;
559+
560+ sinon . stub ( cachingUtils , "getTotalCacheSize" ) . resolves ( 1024 ) ;
561+ sinon . stub ( actionsCache , "saveCache" ) . throws ( ) ;
562+
563+ const config = createTestConfig ( {
564+ languages : [ KnownLanguage . csharp ] ,
565+ } ) ;
566+
567+ await t . throwsAsync ( async ( ) => {
568+ await uploadDependencyCaches ( codeql , features , config , logger ) ;
569+ } ) ;
570+ } ) ;
571+
368572test ( "getFeaturePrefix - returns empty string if no features are enabled" , async ( t ) => {
369573 const codeql = createStubCodeQL ( { } ) ;
370574 const features = createFeatures ( [ ] ) ;
0 commit comments