diff --git a/packages/cache/__tests__/restoreCacheV2.test.ts b/packages/cache/__tests__/restoreCacheV2.test.ts index cc4f9e3c..365afdf0 100644 --- a/packages/cache/__tests__/restoreCacheV2.test.ts +++ b/packages/cache/__tests__/restoreCacheV2.test.ts @@ -3,11 +3,11 @@ import * as path from 'path' import * as tar from '../src/internal/tar' import * as config from '../src/internal/config' import * as cacheUtils from '../src/internal/cacheUtils' -import * as downloadCacheModule from '../src/internal/blob/download-cache' +import * as downloadUtils from '../src/internal/downloadUtils' import {restoreCache} from '../src/cache' import {CacheFilename, CompressionMethod} from '../src/internal/constants' import {CacheServiceClientJSON} from '../src/generated/results/api/v1/cache.twirp' -import {BlobDownloadResponseParsed} from '@azure/storage-blob' +import {DownloadOptions} from '../src/options' jest.mock('../src/internal/cacheHttpClient') jest.mock('../src/internal/cacheUtils') @@ -142,6 +142,7 @@ test('restore with gzip compressed cache found', async () => { const signedDownloadUrl = 'https://blob-storage.local?signed=true' const cacheVersion = 'd90f107aaeb22920dba0c637a23c37b5bc497b4dfa3b07fe3f79bf88a273c11b' + const options: DownloadOptions = {timeoutInMs: 30000} const getCacheVersionMock = jest.spyOn(cacheUtils, 'getCacheVersion') getCacheVersionMock.mockReturnValue(cacheVersion) @@ -169,17 +170,11 @@ test('restore with gzip compressed cache found', async () => { }) const archivePath = path.join(tempPath, CacheFilename.Gzip) - const downloadCacheFileMock = jest.spyOn( - downloadCacheModule, - 'downloadCacheFile' - ) - downloadCacheFileMock.mockReturnValue( - Promise.resolve({ - _response: { - status: 200 - } - } as BlobDownloadResponseParsed) + const downloadCacheStorageSDKMock = jest.spyOn( + downloadUtils, + 'downloadCacheStorageSDK' ) + downloadCacheStorageSDKMock.mockReturnValue(Promise.resolve()) const fileSize = 142 const getArchiveFileSizeInBytesMock = jest @@ -203,9 +198,10 @@ test('restore with gzip compressed cache found', async () => { version: cacheVersion }) expect(createTempDirectoryMock).toHaveBeenCalledTimes(1) - expect(downloadCacheFileMock).toHaveBeenCalledWith( + expect(downloadCacheStorageSDKMock).toHaveBeenCalledWith( signedDownloadUrl, - archivePath + archivePath, + options ) expect(getArchiveFileSizeInBytesMock).toHaveBeenCalledWith(archivePath) expect(logInfoMock).toHaveBeenCalledWith(`Cache Size: ~0 MB (142 B)`) @@ -226,6 +222,7 @@ test('restore with zstd compressed cache found', async () => { const signedDownloadUrl = 'https://blob-storage.local?signed=true' const cacheVersion = '8e2e96a184cb0cd6b48285b176c06a418f3d7fce14c29d9886fd1bb4f05c513d' + const options: DownloadOptions = {timeoutInMs: 30000} const getCacheVersionMock = jest.spyOn(cacheUtils, 'getCacheVersion') getCacheVersionMock.mockReturnValue(cacheVersion) @@ -253,17 +250,11 @@ test('restore with zstd compressed cache found', async () => { }) const archivePath = path.join(tempPath, CacheFilename.Zstd) - const downloadCacheFileMock = jest.spyOn( - downloadCacheModule, - 'downloadCacheFile' - ) - downloadCacheFileMock.mockReturnValue( - Promise.resolve({ - _response: { - status: 200 - } - } as BlobDownloadResponseParsed) + const downloadCacheStorageSDKMock = jest.spyOn( + downloadUtils, + 'downloadCacheStorageSDK' ) + downloadCacheStorageSDKMock.mockReturnValue(Promise.resolve()) const fileSize = 62915000 const getArchiveFileSizeInBytesMock = jest @@ -287,9 +278,10 @@ test('restore with zstd compressed cache found', async () => { version: cacheVersion }) expect(createTempDirectoryMock).toHaveBeenCalledTimes(1) - expect(downloadCacheFileMock).toHaveBeenCalledWith( + expect(downloadCacheStorageSDKMock).toHaveBeenCalledWith( signedDownloadUrl, - archivePath + archivePath, + options ) expect(getArchiveFileSizeInBytesMock).toHaveBeenCalledWith(archivePath) expect(logInfoMock).toHaveBeenCalledWith(`Cache Size: ~60 MB (62915000 B)`) @@ -311,6 +303,7 @@ test('restore with cache found for restore key', async () => { const signedDownloadUrl = 'https://blob-storage.local?signed=true' const cacheVersion = 'b8b58e9bd7b1e8f83d9f05c7e06ea865ba44a0330e07a14db74ac74386677bed' + const options: DownloadOptions = {timeoutInMs: 30000} const getCacheVersionMock = jest.spyOn(cacheUtils, 'getCacheVersion') getCacheVersionMock.mockReturnValue(cacheVersion) @@ -338,17 +331,11 @@ test('restore with cache found for restore key', async () => { }) const archivePath = path.join(tempPath, CacheFilename.Gzip) - const downloadCacheFileMock = jest.spyOn( - downloadCacheModule, - 'downloadCacheFile' - ) - downloadCacheFileMock.mockReturnValue( - Promise.resolve({ - _response: { - status: 200 - } - } as BlobDownloadResponseParsed) + const downloadCacheStorageSDKMock = jest.spyOn( + downloadUtils, + 'downloadCacheStorageSDK' ) + downloadCacheStorageSDKMock.mockReturnValue(Promise.resolve()) const fileSize = 142 const getArchiveFileSizeInBytesMock = jest @@ -372,9 +359,10 @@ test('restore with cache found for restore key', async () => { version: cacheVersion }) expect(createTempDirectoryMock).toHaveBeenCalledTimes(1) - expect(downloadCacheFileMock).toHaveBeenCalledWith( + expect(downloadCacheStorageSDKMock).toHaveBeenCalledWith( signedDownloadUrl, - archivePath + archivePath, + options ) expect(getArchiveFileSizeInBytesMock).toHaveBeenCalledWith(archivePath) expect(logInfoMock).toHaveBeenCalledWith(`Cache Size: ~0 MB (142 B)`) @@ -391,11 +379,11 @@ test('restore with cache found for restore key', async () => { test('restore with dry run', async () => { const paths = ['node_modules'] const key = 'node-test' - const options = {lookupOnly: true} const compressionMethod = CompressionMethod.Gzip const signedDownloadUrl = 'https://blob-storage.local?signed=true' const cacheVersion = 'd90f107aaeb22920dba0c637a23c37b5bc497b4dfa3b07fe3f79bf88a273c11b' + const options: DownloadOptions = {lookupOnly: true, timeoutInMs: 30000} const getCacheVersionMock = jest.spyOn(cacheUtils, 'getCacheVersion') getCacheVersionMock.mockReturnValue(cacheVersion) @@ -416,10 +404,11 @@ test('restore with dry run', async () => { ) const createTempDirectoryMock = jest.spyOn(cacheUtils, 'createTempDirectory') - const downloadCacheFileMock = jest.spyOn( - downloadCacheModule, - 'downloadCacheFile' + const downloadCacheStorageSDKMock = jest.spyOn( + downloadUtils, + 'downloadCacheStorageSDK' ) + downloadCacheStorageSDKMock.mockReturnValue(Promise.resolve()) const cacheKey = await restoreCache(paths, key, undefined, options) @@ -438,5 +427,5 @@ test('restore with dry run', async () => { // creating a tempDir and downloading the cache are skipped expect(createTempDirectoryMock).toHaveBeenCalledTimes(0) - expect(downloadCacheFileMock).toHaveBeenCalledTimes(0) + expect(downloadCacheStorageSDKMock).toHaveBeenCalledTimes(0) }) diff --git a/packages/cache/src/cache.ts b/packages/cache/src/cache.ts index 0a73059a..0e17e3af 100644 --- a/packages/cache/src/cache.ts +++ b/packages/cache/src/cache.ts @@ -3,6 +3,7 @@ import * as path from 'path' import * as utils from './internal/cacheUtils' import * as cacheHttpClient from './internal/cacheHttpClient' import * as cacheTwirpClient from './internal/shared/cacheTwirpClient' +import {downloadCacheStorageSDK} from './internal/downloadUtils' import {getCacheServiceVersion, isGhes} from './internal/config' import {DownloadOptions, UploadOptions} from './options' import {createTar, extractTar, listTar} from './internal/tar' @@ -14,7 +15,6 @@ import { } from './generated/results/api/v1/cache' import {CacheFileSizeLimit} from './internal/constants' import {uploadCacheFile} from './internal/blob/upload-cache' -import {downloadCacheFile} from './internal/blob/download-cache' export class ValidationError extends Error { constructor(message: string) { super(message) @@ -161,11 +161,14 @@ async function restoreCacheV1( ) core.debug(`Archive Path: ${archivePath}`) - // Download the cache from the cache entry + // Download the cache archive from from blob storage await cacheHttpClient.downloadCache( cacheEntry.archiveLocation, archivePath, - options + options || + ({ + timeoutInMs: 30000 + } as DownloadOptions) ) if (core.isDebug()) { @@ -271,11 +274,14 @@ async function restoreCacheV2( core.debug(`Archive path: ${archivePath}`) core.debug(`Starting download of archive to: ${archivePath}`) - const downloadResponse = await downloadCacheFile( + await downloadCacheStorageSDK( response.signedDownloadUrl, - archivePath + archivePath, + options || + ({ + timeoutInMs: 30000 + } as DownloadOptions) ) - core.debug(`Download response status: ${downloadResponse._response.status}`) const archiveFileSize = utils.getArchiveFileSizeInBytes(archivePath) core.info( diff --git a/packages/cache/src/internal/blob/download-cache.ts b/packages/cache/src/internal/blob/download-cache.ts index e974cb2f..38384b10 100644 --- a/packages/cache/src/internal/blob/download-cache.ts +++ b/packages/cache/src/internal/blob/download-cache.ts @@ -22,10 +22,24 @@ export async function downloadCacheFile( `BlobClient: ${blobClient.name}:${blobClient.accountName}:${blobClient.containerName}` ) - return blockBlobClient.downloadToFile( + const response = await blockBlobClient.downloadToFile( archivePath, 0, undefined, downloadOptions ) + + switch (response._response.status) { + case 200: + core.info(`Cache downloaded from "${signedUploadURL}"`) + break + case 304: + core.info(`Cache not found at "${signedUploadURL}"`) + break + default: + core.info(`Unexpected HTTP response: ${response._response.status}`) + break + } + + return response }