@@ -86,7 +86,9 @@ describe("Docker images", (): void => {
8686
8787 const assertSaveDockerImages = (
8888 cacheHit : boolean ,
89+ key : string ,
8990 readOnly = false ,
91+ prevSave = false ,
9092 ) : void => {
9193 expect ( core . getInput ) . nthCalledWith < [ string , InputOptions ] > ( 1 , "key" , {
9294 required : true ,
@@ -95,12 +97,20 @@ describe("Docker images", (): void => {
9597 if ( ! cacheHit ) {
9698 expect ( core . getInput ) . lastCalledWith ( "read-only" ) ;
9799 if ( ! readOnly ) {
98- expect ( core . getState ) . lastCalledWith ( docker . DOCKER_IMAGES_LIST ) ;
99- expect ( core . info ) . nthCalledWith < [ string ] > ( 1 , "Listing Docker images." ) ;
100- expect ( util . execBashCommand ) . nthCalledWith < [ string ] > (
101- 1 ,
102- 'docker image list --format "{{ .Repository }}:{{ .Tag }}"' ,
103- ) ;
100+ expect ( cache . restoreCache ) . lastCalledWith ( [ "" ] , key , [ ] , {
101+ lookupOnly : true ,
102+ } ) ;
103+ if ( ! prevSave ) {
104+ expect ( core . getState ) . lastCalledWith ( docker . DOCKER_IMAGES_LIST ) ;
105+ expect ( core . info ) . nthCalledWith < [ string ] > (
106+ 1 ,
107+ "Listing Docker images." ,
108+ ) ;
109+ expect ( util . execBashCommand ) . nthCalledWith < [ string ] > (
110+ 1 ,
111+ 'docker image list --format "{{ .Repository }}:{{ .Tag }}"' ,
112+ ) ;
113+ }
104114 }
105115 }
106116 } ;
@@ -109,6 +119,7 @@ describe("Docker images", (): void => {
109119 key : string ,
110120 cacheHit : boolean ,
111121 readOnly : boolean ,
122+ prevSave : boolean ,
112123 preexistingImages : string [ ] ,
113124 newImages : string [ ] ,
114125 ) : Promise < void > => {
@@ -117,14 +128,19 @@ describe("Docker images", (): void => {
117128 if ( ! cacheHit ) {
118129 core . getInput . mockReturnValueOnce ( readOnly . toString ( ) ) ;
119130 if ( ! readOnly ) {
120- core . getState . mockReturnValueOnce ( preexistingImages . join ( "\n" ) ) ;
121- const images = preexistingImages . concat ( newImages ) ;
122- util . execBashCommand . mockResolvedValueOnce ( images . join ( "\n" ) ) ;
131+ if ( prevSave ) {
132+ cache . restoreCache . mockResolvedValueOnce ( key ) ;
133+ } else {
134+ cache . restoreCache . mockResolvedValueOnce ( undefined ) ;
135+ core . getState . mockReturnValueOnce ( preexistingImages . join ( "\n" ) ) ;
136+ const images = preexistingImages . concat ( newImages ) ;
137+ util . execBashCommand . mockResolvedValueOnce ( images . join ( "\n" ) ) ;
138+ }
123139 }
124140 }
125141 await docker . saveDockerImages ( ) ;
126142
127- assertSaveDockerImages ( cacheHit , readOnly ) ;
143+ assertSaveDockerImages ( cacheHit , key , readOnly , prevSave ) ;
128144 } ;
129145
130146 const assertCacheNotSaved = ( ) : void => {
@@ -147,6 +163,16 @@ describe("Docker images", (): void => {
147163 assertCacheNotSaved ( ) ;
148164 } ;
149165
166+ const assertSavePrevSave = ( key : string ) : void => {
167+ expect ( core . info ) . lastCalledWith (
168+ "A cache miss occurred during the initial attempt to load Docker " +
169+ `images. Subsequently a cache with a matching key, ${ key } , was saved. ` +
170+ "This can occur when docker-cache is used by multiple jobs run in " +
171+ "parallel. Not saving cache." ,
172+ ) ;
173+ assertCacheNotSaved ( ) ;
174+ } ;
175+
150176 const assertNoNewImagesToSave = ( ) : void => {
151177 expect ( util . execBashCommand ) . toHaveBeenCalledTimes ( 1 ) ;
152178 expect ( core . info ) . lastCalledWith ( "No Docker images to save" ) ;
@@ -230,24 +256,28 @@ describe("Docker images", (): void => {
230256 ) ;
231257
232258 testProp (
233- "are saved unless cache hit, in read-only mode, or new Docker image list is empty" ,
259+ "are saved unless cache hit, in read-only mode, cache already saved, or " +
260+ "new Docker image list is empty" ,
234261 [
235262 fullUnicodeString ( ) ,
236263 boolean ( ) ,
237264 boolean ( ) ,
265+ boolean ( ) ,
238266 uniquePair ( dockerImages ( ) , dockerImages ( ) ) ,
239267 ] ,
240268 async (
241269 key : string ,
242270 cacheHit : boolean ,
243271 readOnly : boolean ,
272+ prevSave : boolean ,
244273 [ preexistingImages , newImages ] : [ string [ ] , string [ ] ] ,
245274 ) : Promise < void > => {
246275 jest . clearAllMocks ( ) ;
247276 await mockedSaveDockerImages (
248277 key ,
249278 cacheHit ,
250279 readOnly ,
280+ prevSave ,
251281 preexistingImages ,
252282 newImages ,
253283 ) ;
@@ -256,6 +286,8 @@ describe("Docker images", (): void => {
256286 assertSaveCacheHit ( key ) ;
257287 } else if ( readOnly ) {
258288 assertSaveReadOnly ( key ) ;
289+ } else if ( prevSave ) {
290+ assertSavePrevSave ( key ) ;
259291 } else if ( newImages . length === 0 ) {
260292 assertNoNewImagesToSave ( ) ;
261293 } else {
@@ -264,10 +296,11 @@ describe("Docker images", (): void => {
264296 } ,
265297 {
266298 examples : [
267- [ "my-key" , false , false , [ [ "preexisting-image" ] , [ "new-image" ] ] ] ,
268- [ "my-key" , false , false , [ [ "preexisting-image" ] , [ ] ] ] ,
269- [ "my-key" , false , true , [ [ "preexisting-image" ] , [ "new-image" ] ] ] ,
270- [ "my-key" , true , false , [ [ "preexisting-image" ] , [ "new-image" ] ] ] ,
299+ [ "my-key" , false , false , false , [ [ "preexisting-image" ] , [ "new-image" ] ] ] ,
300+ [ "my-key" , false , false , false , [ [ "preexisting-image" ] , [ ] ] ] ,
301+ [ "my-key" , false , true , false , [ [ "preexisting-image" ] , [ "new-image" ] ] ] ,
302+ [ "my-key" , true , false , false , [ [ "preexisting-image" ] , [ "new-image" ] ] ] ,
303+ [ "my-key" , false , false , true , [ [ "preexisting-image" ] , [ "new-image" ] ] ] ,
271304 ] ,
272305 } ,
273306 ) ;
0 commit comments