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