1
0
Fork 0

adding network tests

vmjoseph/ts-network-tests
Vallie Joseph 2023-12-19 06:40:01 +00:00
parent 68f22927e7
commit 123bccb3d9
5 changed files with 161 additions and 17 deletions

View File

@ -21,6 +21,7 @@
"archiver": "^5.3.1", "archiver": "^5.3.1",
"crypto": "^1.0.1", "crypto": "^1.0.1",
"jwt-decode": "^3.1.2", "jwt-decode": "^3.1.2",
"nock": "^13.4.0",
"twirp-ts": "^2.5.0", "twirp-ts": "^2.5.0",
"unzip-stream": "^0.3.1" "unzip-stream": "^0.3.1"
}, },
@ -108,6 +109,25 @@
"node": ">=14.0.0" "node": ">=14.0.0"
} }
}, },
"node_modules/@azure/core-http/node_modules/node-fetch": {
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
"integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
"dependencies": {
"whatwg-url": "^5.0.0"
},
"engines": {
"node": "4.x || >=6.0.0"
},
"peerDependencies": {
"encoding": "^0.1.0"
},
"peerDependenciesMeta": {
"encoding": {
"optional": true
}
}
},
"node_modules/@azure/core-lro": { "node_modules/@azure/core-lro": {
"version": "2.5.4", "version": "2.5.4",
"resolved": "https://registry.npmjs.org/@azure/core-lro/-/core-lro-2.5.4.tgz", "resolved": "https://registry.npmjs.org/@azure/core-lro/-/core-lro-2.5.4.tgz",
@ -332,6 +352,25 @@
"once": "^1.4.0" "once": "^1.4.0"
} }
}, },
"node_modules/@octokit/request/node_modules/node-fetch": {
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
"integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
"dependencies": {
"whatwg-url": "^5.0.0"
},
"engines": {
"node": "4.x || >=6.0.0"
},
"peerDependencies": {
"encoding": "^0.1.0"
},
"peerDependenciesMeta": {
"encoding": {
"optional": true
}
}
},
"node_modules/@octokit/types": { "node_modules/@octokit/types": {
"version": "6.41.0", "version": "6.41.0",
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.41.0.tgz", "resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.41.0.tgz",
@ -756,6 +795,22 @@
"integrity": "sha512-VxBKmeNcqQdiUQUW2Tzq0t377b54N2bMtXO/qiLa+6eRRmmC4qT3D4OnTGoT/U6O9aklQ/jTwbOtRMTTY8G0Ig==", "integrity": "sha512-VxBKmeNcqQdiUQUW2Tzq0t377b54N2bMtXO/qiLa+6eRRmmC4qT3D4OnTGoT/U6O9aklQ/jTwbOtRMTTY8G0Ig==",
"deprecated": "This package is no longer supported. It's now a built-in Node module. If you've depended on crypto, you should switch to the one that's built-in." "deprecated": "This package is no longer supported. It's now a built-in Node module. If you've depended on crypto, you should switch to the one that's built-in."
}, },
"node_modules/debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
"dependencies": {
"ms": "2.1.2"
},
"engines": {
"node": ">=6.0"
},
"peerDependenciesMeta": {
"supports-color": {
"optional": true
}
}
},
"node_modules/delayed-stream": { "node_modules/delayed-stream": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
@ -911,6 +966,11 @@
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
"integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="
}, },
"node_modules/json-stringify-safe": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
"integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA=="
},
"node_modules/jsonc-parser": { "node_modules/jsonc-parser": {
"version": "3.2.0", "version": "3.2.0",
"resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz",
@ -1065,6 +1125,11 @@
"mkdirp": "bin/cmd.js" "mkdirp": "bin/cmd.js"
} }
}, },
"node_modules/ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
},
"node_modules/neo-async": { "node_modules/neo-async": {
"version": "2.6.2", "version": "2.6.2",
"resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
@ -1080,23 +1145,17 @@
"tslib": "^2.0.3" "tslib": "^2.0.3"
} }
}, },
"node_modules/node-fetch": { "node_modules/nock": {
"version": "2.6.12", "version": "13.4.0",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.12.tgz", "resolved": "https://registry.npmjs.org/nock/-/nock-13.4.0.tgz",
"integrity": "sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g==", "integrity": "sha512-W8NVHjO/LCTNA64yxAPHV/K47LpGYcVzgKd3Q0n6owhwvD0Dgoterc25R4rnZbckJEb6Loxz1f5QMuJpJnbSyQ==",
"dependencies": { "dependencies": {
"whatwg-url": "^5.0.0" "debug": "^4.1.0",
"json-stringify-safe": "^5.0.1",
"propagate": "^2.0.0"
}, },
"engines": { "engines": {
"node": "4.x || >=6.0.0" "node": ">= 10.13"
},
"peerDependencies": {
"encoding": "^0.1.0"
},
"peerDependenciesMeta": {
"encoding": {
"optional": true
}
} }
}, },
"node_modules/normalize-path": { "node_modules/normalize-path": {
@ -1164,6 +1223,14 @@
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
}, },
"node_modules/propagate": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/propagate/-/propagate-2.0.1.tgz",
"integrity": "sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==",
"engines": {
"node": ">= 8"
}
},
"node_modules/readable-stream": { "node_modules/readable-stream": {
"version": "3.6.2", "version": "3.6.2",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",

View File

@ -52,6 +52,7 @@
"archiver": "^5.3.1", "archiver": "^5.3.1",
"crypto": "^1.0.1", "crypto": "^1.0.1",
"jwt-decode": "^3.1.2", "jwt-decode": "^3.1.2",
"nock": "^13.4.0",
"twirp-ts": "^2.5.0", "twirp-ts": "^2.5.0",
"unzip-stream": "^0.3.1" "unzip-stream": "^0.3.1"
}, },

View File

@ -45,6 +45,21 @@ export interface UploadArtifactOptions {
* For large files that are not easily compressed, a value of 0 is recommended for significantly faster uploads. * For large files that are not easily compressed, a value of 0 is recommended for significantly faster uploads.
*/ */
compressionLevel?: number compressionLevel?: number
/**
* The simulated network error we'll temporarily use to test the azure blob
* client behavior.
* The value can range from 0 to 6
* 0 - fetchError
* 1 - abortError
* 2 - networkError
* 3 - securityError
* 4 - notAllowedError
* 5 - quotaExceededError
* 6 - random
* 7 - none
*
*/
simulateError?: number
} }
/** /**

View File

@ -5,8 +5,17 @@ import {getUploadChunkSize, getConcurrency} from '../shared/config'
import * as core from '@actions/core' import * as core from '@actions/core'
import * as crypto from 'crypto' import * as crypto from 'crypto'
import * as stream from 'stream' import * as stream from 'stream'
import nock from 'nock'
import {NetworkError} from '../shared/errors' import {NetworkError} from '../shared/errors'
export const DEFAULT_ERROR_NUMBER = 7
export const ERROR_TYPES = [
'fetchError',
'abortError',
'securityError',
'notAllowedError',
'quotaExceededError'
]
export interface BlobUploadResponse { export interface BlobUploadResponse {
/** /**
* The total reported upload size in bytes. Empty if the upload failed * The total reported upload size in bytes. Empty if the upload failed
@ -18,10 +27,58 @@ export interface BlobUploadResponse {
*/ */
sha256Hash?: string sha256Hash?: string
} }
export async function sendSimulatedError(
simulatedError: number,
authenticatedUploadURL: string
): Promise<void> {
switch (simulatedError) {
case 0: {
nock(authenticatedUploadURL).get('/').replyWithError({
code: 'ECONNRESET',
message: 'socket hang up'
})
break
}
case 1: {
const controller = new AbortController()
controller.abort()
break
}
case 2: {
nock(authenticatedUploadURL).get('/').replyWithError({
code: 'ETIMEDOUT'
})
break
}
case 3: {
nock(authenticatedUploadURL).get('/').reply(403)
break
}
case 4: {
nock(authenticatedUploadURL).get('/').reply(405)
break
}
case 5: {
nock(authenticatedUploadURL).get('/').reply(429)
break
}
case 6: {
const rand = Math.floor(Math.random() * ERROR_TYPES.length)
sendSimulatedError(rand, authenticatedUploadURL)
break
}
case 7: {
core.info('no error selected')
break
}
default:
core.error('something went wrong')
}
}
export async function uploadZipToBlobStorage( export async function uploadZipToBlobStorage(
authenticatedUploadURL: string, authenticatedUploadURL: string,
zipUploadStream: ZipUploadStream zipUploadStream: ZipUploadStream,
simulatedError: number = DEFAULT_ERROR_NUMBER
): Promise<BlobUploadResponse> { ): Promise<BlobUploadResponse> {
let uploadByteCount = 0 let uploadByteCount = 0
@ -36,6 +93,9 @@ export async function uploadZipToBlobStorage(
const uploadCallback = (progress: TransferProgressEvent): void => { const uploadCallback = (progress: TransferProgressEvent): void => {
core.info(`Uploaded bytes ${progress.loadedBytes}`) core.info(`Uploaded bytes ${progress.loadedBytes}`)
if (progress.loadedBytes > 1) {
sendSimulatedError(simulatedError, authenticatedUploadURL)
}
uploadByteCount = progress.loadedBytes uploadByteCount = progress.loadedBytes
} }

View File

@ -76,7 +76,8 @@ export async function uploadArtifact(
// Upload zip to blob storage // Upload zip to blob storage
const uploadResult = await uploadZipToBlobStorage( const uploadResult = await uploadZipToBlobStorage(
createArtifactResp.signedUploadUrl, createArtifactResp.signedUploadUrl,
zipUploadStream zipUploadStream,
options?.simulateError
) )
// finalize the artifact // finalize the artifact