@@ -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
@@ -349,6 +353,211 @@ test("downloadDependencyCaches - restores caches with feature keys if features a
349353 t . assert ( restoreCacheStub . calledOnce ) ;
350354} ) ;
351355
356+ test ( "uploadDependencyCaches - skips upload for a language with no cache config" , async ( t ) => {
357+ const codeql = createStubCodeQL ( { } ) ;
358+ const messages : LoggedMessage [ ] = [ ] ;
359+ const logger = getRecordingLogger ( messages ) ;
360+ const features = createFeatures ( [ ] ) ;
361+ const config = createTestConfig ( {
362+ languages : [ KnownLanguage . actions ] ,
363+ } ) ;
364+
365+ // const makePatternCheckStub = sinon.stub(internal, "makePatternCheck");
366+ // makePatternCheckStub
367+ // .withArgs(CSHARP_BASE_PATTERNS)
368+ // .resolves(CSHARP_BASE_PATTERNS);
369+
370+ const result = await uploadDependencyCaches ( codeql , features , config , logger ) ;
371+ t . is ( result . length , 0 ) ;
372+ checkExpectedLogMessages ( t , messages , [
373+ "Skipping upload of dependency cache for actions" ,
374+ ] ) ;
375+ } ) ;
376+
377+ test ( "uploadDependencyCaches - skips upload if no files for the hash exist" , async ( t ) => {
378+ const codeql = createStubCodeQL ( { } ) ;
379+ const messages : LoggedMessage [ ] = [ ] ;
380+ const logger = getRecordingLogger ( messages ) ;
381+ const features = createFeatures ( [ ] ) ;
382+ const config = createTestConfig ( {
383+ languages : [ KnownLanguage . go ] ,
384+ } ) ;
385+
386+ const makePatternCheckStub = sinon . stub ( internal , "makePatternCheck" ) ;
387+ makePatternCheckStub . resolves ( undefined ) ;
388+
389+ const result = await uploadDependencyCaches ( codeql , features , config , logger ) ;
390+ t . is ( result . length , 1 ) ;
391+ t . is ( result [ 0 ] . language , KnownLanguage . go ) ;
392+ t . is ( result [ 0 ] . result , CacheStoreResult . NoHash ) ;
393+ } ) ;
394+
395+ test ( "uploadDependencyCaches - skips upload if cache key was already restored as an exact match" , async ( t ) => {
396+ process . env [ "RUNNER_OS" ] = "Linux" ;
397+
398+ const codeql = createStubCodeQL ( { } ) ;
399+ const messages : LoggedMessage [ ] = [ ] ;
400+ const logger = getRecordingLogger ( messages ) ;
401+ const features = createFeatures ( [ ] ) ;
402+
403+ const mockHash = "abcdef" ;
404+ sinon . stub ( glob , "hashFiles" ) . resolves ( mockHash ) ;
405+
406+ const makePatternCheckStub = sinon . stub ( internal , "makePatternCheck" ) ;
407+ makePatternCheckStub
408+ . withArgs ( CSHARP_BASE_PATTERNS )
409+ . resolves ( CSHARP_BASE_PATTERNS ) ;
410+
411+ const primaryCacheKey = await cacheKey (
412+ codeql ,
413+ features ,
414+ KnownLanguage . csharp ,
415+ CSHARP_BASE_PATTERNS ,
416+ ) ;
417+
418+ const config = createTestConfig ( {
419+ languages : [ KnownLanguage . csharp ] ,
420+ dependencyCachingExactKeys : [ primaryCacheKey ] ,
421+ } ) ;
422+
423+ const result = await uploadDependencyCaches ( codeql , features , config , logger ) ;
424+ t . is ( result . length , 1 ) ;
425+ t . is ( result [ 0 ] . language , KnownLanguage . csharp ) ;
426+ t . is ( result [ 0 ] . result , CacheStoreResult . Duplicate ) ;
427+ } ) ;
428+
429+ test ( "uploadDependencyCaches - skips upload if cache size is 0" , async ( t ) => {
430+ process . env [ "RUNNER_OS" ] = "Linux" ;
431+
432+ const codeql = createStubCodeQL ( { } ) ;
433+ const messages : LoggedMessage [ ] = [ ] ;
434+ const logger = getRecordingLogger ( messages ) ;
435+ const features = createFeatures ( [ ] ) ;
436+
437+ const mockHash = "abcdef" ;
438+ sinon . stub ( glob , "hashFiles" ) . resolves ( mockHash ) ;
439+
440+ const makePatternCheckStub = sinon . stub ( internal , "makePatternCheck" ) ;
441+ makePatternCheckStub
442+ . withArgs ( CSHARP_BASE_PATTERNS )
443+ . resolves ( CSHARP_BASE_PATTERNS ) ;
444+
445+ sinon . stub ( cachingUtils , "getTotalCacheSize" ) . resolves ( 0 ) ;
446+
447+ const config = createTestConfig ( {
448+ languages : [ KnownLanguage . csharp ] ,
449+ } ) ;
450+
451+ const result = await uploadDependencyCaches ( codeql , features , config , logger ) ;
452+ t . is ( result . length , 1 ) ;
453+ t . is ( result [ 0 ] . language , KnownLanguage . csharp ) ;
454+ t . is ( result [ 0 ] . result , CacheStoreResult . Empty ) ;
455+
456+ checkExpectedLogMessages ( t , messages , [
457+ "Skipping upload of dependency cache" ,
458+ ] ) ;
459+ } ) ;
460+
461+ test ( "uploadDependencyCaches - uploads caches when all requirements are met" , async ( t ) => {
462+ process . env [ "RUNNER_OS" ] = "Linux" ;
463+
464+ const codeql = createStubCodeQL ( { } ) ;
465+ const messages : LoggedMessage [ ] = [ ] ;
466+ const logger = getRecordingLogger ( messages ) ;
467+ const features = createFeatures ( [ ] ) ;
468+
469+ const mockHash = "abcdef" ;
470+ sinon . stub ( glob , "hashFiles" ) . resolves ( mockHash ) ;
471+
472+ const makePatternCheckStub = sinon . stub ( internal , "makePatternCheck" ) ;
473+ makePatternCheckStub
474+ . withArgs ( CSHARP_BASE_PATTERNS )
475+ . resolves ( CSHARP_BASE_PATTERNS ) ;
476+
477+ sinon . stub ( cachingUtils , "getTotalCacheSize" ) . resolves ( 1024 ) ;
478+ sinon . stub ( actionsCache , "saveCache" ) . resolves ( ) ;
479+
480+ const config = createTestConfig ( {
481+ languages : [ KnownLanguage . csharp ] ,
482+ } ) ;
483+
484+ const result = await uploadDependencyCaches ( codeql , features , config , logger ) ;
485+ t . is ( result . length , 1 ) ;
486+ t . is ( result [ 0 ] . language , KnownLanguage . csharp ) ;
487+ t . is ( result [ 0 ] . result , CacheStoreResult . Stored ) ;
488+ t . is ( result [ 0 ] . upload_size_bytes , 1024 ) ;
489+
490+ checkExpectedLogMessages ( t , messages , [ "Uploading cache of size" ] ) ;
491+ } ) ;
492+
493+ test ( "uploadDependencyCaches - catches `ReserveCacheError` exceptions" , async ( t ) => {
494+ process . env [ "RUNNER_OS" ] = "Linux" ;
495+
496+ const codeql = createStubCodeQL ( { } ) ;
497+ const messages : LoggedMessage [ ] = [ ] ;
498+ const logger = getRecordingLogger ( messages ) ;
499+ const features = createFeatures ( [ ] ) ;
500+
501+ const mockHash = "abcdef" ;
502+ sinon . stub ( glob , "hashFiles" ) . resolves ( mockHash ) ;
503+
504+ const makePatternCheckStub = sinon . stub ( internal , "makePatternCheck" ) ;
505+ makePatternCheckStub
506+ . withArgs ( CSHARP_BASE_PATTERNS )
507+ . resolves ( CSHARP_BASE_PATTERNS ) ;
508+
509+ sinon . stub ( cachingUtils , "getTotalCacheSize" ) . resolves ( 1024 ) ;
510+ sinon
511+ . stub ( actionsCache , "saveCache" )
512+ . throws ( new actionsCache . ReserveCacheError ( "Already in use" ) ) ;
513+
514+ const config = createTestConfig ( {
515+ languages : [ KnownLanguage . csharp ] ,
516+ } ) ;
517+
518+ await t . notThrowsAsync ( async ( ) => {
519+ const result = await uploadDependencyCaches (
520+ codeql ,
521+ features ,
522+ config ,
523+ logger ,
524+ ) ;
525+ t . is ( result . length , 1 ) ;
526+ t . is ( result [ 0 ] . language , KnownLanguage . csharp ) ;
527+ t . is ( result [ 0 ] . result , CacheStoreResult . Duplicate ) ;
528+
529+ checkExpectedLogMessages ( t , messages , [ "Not uploading cache for" ] ) ;
530+ } ) ;
531+ } ) ;
532+
533+ test ( "uploadDependencyCaches - throws other exceptions" , async ( t ) => {
534+ process . env [ "RUNNER_OS" ] = "Linux" ;
535+
536+ const codeql = createStubCodeQL ( { } ) ;
537+ const messages : LoggedMessage [ ] = [ ] ;
538+ const logger = getRecordingLogger ( messages ) ;
539+ const features = createFeatures ( [ ] ) ;
540+
541+ const mockHash = "abcdef" ;
542+ sinon . stub ( glob , "hashFiles" ) . resolves ( mockHash ) ;
543+
544+ const makePatternCheckStub = sinon . stub ( internal , "makePatternCheck" ) ;
545+ makePatternCheckStub
546+ . withArgs ( CSHARP_BASE_PATTERNS )
547+ . resolves ( CSHARP_BASE_PATTERNS ) ;
548+
549+ sinon . stub ( cachingUtils , "getTotalCacheSize" ) . resolves ( 1024 ) ;
550+ sinon . stub ( actionsCache , "saveCache" ) . throws ( ) ;
551+
552+ const config = createTestConfig ( {
553+ languages : [ KnownLanguage . csharp ] ,
554+ } ) ;
555+
556+ await t . throwsAsync ( async ( ) => {
557+ await uploadDependencyCaches ( codeql , features , config , logger ) ;
558+ } ) ;
559+ } ) ;
560+
352561test ( "getFeaturePrefix - returns empty string if no features are enabled" , async ( t ) => {
353562 const codeql = createStubCodeQL ( { } ) ;
354563 const features = createFeatures ( [ ] ) ;
0 commit comments