From c6e3b10cda65b9142f3c531ef61d76fc2ed10bde Mon Sep 17 00:00:00 2001 From: Eric Jizba Date: Mon, 29 Jan 2024 17:21:04 -0800 Subject: [PATCH 1/5] Http stream end to end tests --- .eslintrc.json | 1 + app/v3/httpTriggerRandomDelay/function.json | 20 ++++ app/v3/httpTriggerRandomDelay/index.ts | 19 ++++ app/v3/utils/delay.ts | 13 +++ app/v3/utils/getRandomTestData.ts | 32 ++++++ app/v4-oldConfig/src/setup.ts | 6 ++ app/v4/azure-functions-4.1.0.tgz | Bin 0 -> 74842 bytes app/v4/package-lock.json | 18 +++- app/v4/package.json | 10 +- .../src/functions/httpTriggerRandomDelay.ts | 24 +++++ .../src/functions/httpTriggerReceiveStream.ts | 22 ++++ app/v4/src/functions/httpTriggerSendStream.ts | 22 ++++ app/v4/src/setup.ts | 6 ++ app/v4/src/utils/delay.ts | 13 +++ app/v4/src/utils/getRandomTestData.ts | 32 ++++++ app/v4/src/utils/streamHttp.ts | 57 +++++++++++ azure-pipelines/test.yml | 14 +-- src/global.test.ts | 11 +- src/http.test.ts | 94 +++++++++++++++++- src/utils/delay.ts | 7 ++ src/utils/getRandomTestData.ts | 19 +++- src/utils/streamHttp.ts | 57 +++++++++++ 22 files changed, 476 insertions(+), 21 deletions(-) create mode 100644 app/v3/httpTriggerRandomDelay/function.json create mode 100644 app/v3/httpTriggerRandomDelay/index.ts create mode 100644 app/v3/utils/delay.ts create mode 100644 app/v3/utils/getRandomTestData.ts create mode 100644 app/v4-oldConfig/src/setup.ts create mode 100644 app/v4/azure-functions-4.1.0.tgz create mode 100644 app/v4/src/functions/httpTriggerRandomDelay.ts create mode 100644 app/v4/src/functions/httpTriggerReceiveStream.ts create mode 100644 app/v4/src/functions/httpTriggerSendStream.ts create mode 100644 app/v4/src/setup.ts create mode 100644 app/v4/src/utils/delay.ts create mode 100644 app/v4/src/utils/getRandomTestData.ts create mode 100644 app/v4/src/utils/streamHttp.ts create mode 100644 src/utils/streamHttp.ts diff --git a/.eslintrc.json b/.eslintrc.json index e881d63..93b619d 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -29,6 +29,7 @@ ], "deprecation/deprecation": "error", "@typescript-eslint/no-empty-interface": "off", + "@typescript-eslint/no-empty-function": "off", "@typescript-eslint/no-explicit-any": "off", "@typescript-eslint/no-namespace": "off", "@typescript-eslint/no-unused-vars": ["error", { "argsIgnorePattern": "^_" }], diff --git a/app/v3/httpTriggerRandomDelay/function.json b/app/v3/httpTriggerRandomDelay/function.json new file mode 100644 index 0000000..0830e3c --- /dev/null +++ b/app/v3/httpTriggerRandomDelay/function.json @@ -0,0 +1,20 @@ +{ + "bindings": [ + { + "authLevel": "anonymous", + "type": "httpTrigger", + "direction": "in", + "name": "req", + "methods": [ + "get", + "post" + ] + }, + { + "type": "http", + "direction": "out", + "name": "res" + } + ], + "scriptFile": "../dist/httpTriggerRandomDelay/index.js" +} \ No newline at end of file diff --git a/app/v3/httpTriggerRandomDelay/index.ts b/app/v3/httpTriggerRandomDelay/index.ts new file mode 100644 index 0000000..7157cbf --- /dev/null +++ b/app/v3/httpTriggerRandomDelay/index.ts @@ -0,0 +1,19 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the MIT License. + +import { AzureFunction, Context, HttpRequest } from '@azure/functions'; +import { addRandomDelay } from '../utils/getRandomTestData'; + +const httpTrigger: AzureFunction = async function (context: Context, req: HttpRequest): Promise { + context.log(`Http function processed request for url "${req.url}"`); + + await addRandomDelay(); + + const name = req.query.name || req.body || 'world'; + + context.res = { + body: `Hello, ${name}!`, + }; +}; + +export default httpTrigger; diff --git a/app/v3/utils/delay.ts b/app/v3/utils/delay.ts new file mode 100644 index 0000000..7b7a884 --- /dev/null +++ b/app/v3/utils/delay.ts @@ -0,0 +1,13 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the MIT License. + +export async function delay(ms: number): Promise { + await new Promise((resolve) => setTimeout(resolve, ms)); +} + +export function delaySync(ms: number): void { + const endTime = Date.now() + ms; + while (Date.now() < endTime) { + // wait + } +} diff --git a/app/v3/utils/getRandomTestData.ts b/app/v3/utils/getRandomTestData.ts new file mode 100644 index 0000000..4bac3a6 --- /dev/null +++ b/app/v3/utils/getRandomTestData.ts @@ -0,0 +1,32 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the MIT License. + +import * as crypto from 'crypto'; +import { delay, delaySync } from './delay'; + +export function getRandomTestData(): string { + // This should start with non-numeric data to prevent this bug from causing a test failure + // https://github.com/Azure/azure-functions-nodejs-library/issues/90 + return `testData${getRandomHexString()}`; +} + +export function getRandomHexString(length = 10): string { + const buffer: Buffer = crypto.randomBytes(Math.ceil(length / 2)); + return buffer.toString('hex').slice(0, length); +} + +export function getRandomInt(min: number, max: number): number { + return Math.floor(Math.random() * (max - min) + min); +} + +export function getRandomBoolean(percentTrue: number): boolean { + return Math.random() * 100 > percentTrue; +} + +export async function addRandomDelay(): Promise { + if (getRandomBoolean(95)) { + await delay(getRandomInt(0, 250)); + } else { + delaySync(getRandomInt(0, 10)); + } +} diff --git a/app/v4-oldConfig/src/setup.ts b/app/v4-oldConfig/src/setup.ts new file mode 100644 index 0000000..ed6a2ae --- /dev/null +++ b/app/v4-oldConfig/src/setup.ts @@ -0,0 +1,6 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the MIT License. + +import { app } from '@azure/functions'; + +app.setup({ enableHttpStream: false }); diff --git a/app/v4/azure-functions-4.1.0.tgz b/app/v4/azure-functions-4.1.0.tgz new file mode 100644 index 0000000000000000000000000000000000000000..be640fcfff99b8e6a985ea0ac4ab0a2b77acdb81 GIT binary patch literal 74842 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 literal 0 HcmV?d00001 diff --git a/app/v4/package-lock.json b/app/v4/package-lock.json index 9020d3b..584f7e7 100644 --- a/app/v4/package-lock.json +++ b/app/v4/package-lock.json @@ -8,7 +8,7 @@ "name": "v4", "version": "1.0.0", "dependencies": { - "@azure/functions": "^4.0.0" + "@azure/functions": "file:azure-functions-4.1.0.tgz" }, "devDependencies": { "@types/long": "^4.0.0", @@ -18,10 +18,12 @@ } }, "node_modules/@azure/functions": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@azure/functions/-/functions-4.0.1.tgz", - "integrity": "sha512-Ol38b4XOlu6IDkLnO91HaYeo2utMixG0LIA1NR9Qehu17U/cGjNx+bAcOEdNlSJWNYh5ChhzjxA/uFB5dQJtmg==", + "version": "4.1.0", + "resolved": "file:azure-functions-4.1.0.tgz", + "integrity": "sha512-VPKQ7mayn8Ke7aebmTfi7GttNW9LhgVGBDNcmApGXWTQialw3Egs8eMtk9cUHP8lQYnWIJiMCdeYCKWnZhmxLQ==", + "license": "MIT", "dependencies": { + "cookie": "^0.6.0", "long": "^4.0.0", "undici": "^5.13.0" }, @@ -133,6 +135,14 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "node_modules/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", diff --git a/app/v4/package.json b/app/v4/package.json index b9f95ff..18d7b0c 100644 --- a/app/v4/package.json +++ b/app/v4/package.json @@ -12,13 +12,13 @@ "test": "echo \"No tests yet...\"" }, "dependencies": { - "@azure/functions": "^4.0.0" + "@azure/functions": "file:azure-functions-4.1.0.tgz" }, "devDependencies": { "@types/long": "^4.0.0", "@types/node": "^18.x", - "typescript": "^4.0.0", - "rimraf": "^5.0.0" + "rimraf": "^5.0.0", + "typescript": "^4.0.0" }, - "main": "dist/src/{index.js,functions/*.js}" -} \ No newline at end of file + "main": "dist/src/{index.js,setup.js,functions/*.js}" +} diff --git a/app/v4/src/functions/httpTriggerRandomDelay.ts b/app/v4/src/functions/httpTriggerRandomDelay.ts new file mode 100644 index 0000000..80516d2 --- /dev/null +++ b/app/v4/src/functions/httpTriggerRandomDelay.ts @@ -0,0 +1,24 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the MIT License. + +import { app, HttpRequest, HttpResponseInit, InvocationContext } from '@azure/functions'; +import { addRandomDelay } from '../utils/getRandomTestData'; + +export async function httpTriggerRandomDelay( + request: HttpRequest, + context: InvocationContext +): Promise { + context.log(`Http function processed request for url "${request.url}"`); + + await addRandomDelay(); + + const name = request.query.get('name') || (await request.text()) || 'world'; + + return { body: `Hello, ${name}!` }; +} + +app.http('httpTriggerRandomDelay', { + methods: ['GET', 'POST'], + authLevel: 'anonymous', + handler: httpTriggerRandomDelay, +}); diff --git a/app/v4/src/functions/httpTriggerReceiveStream.ts b/app/v4/src/functions/httpTriggerReceiveStream.ts new file mode 100644 index 0000000..43b55e1 --- /dev/null +++ b/app/v4/src/functions/httpTriggerReceiveStream.ts @@ -0,0 +1,22 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the MIT License. + +import { app, HttpRequest, HttpResponseInit, InvocationContext } from '@azure/functions'; +import { receiveStreamWithProgress } from '../utils/streamHttp'; + +export async function httpTriggerReceiveStream( + request: HttpRequest, + context: InvocationContext +): Promise { + context.log(`Http function processed request for url "${request.url}"`); + + const bytesReceived = await receiveStreamWithProgress(request.body); + + return { body: `Bytes received: ${bytesReceived}` }; +} + +app.http('httpTriggerReceiveStream', { + methods: ['GET', 'POST'], + authLevel: 'anonymous', + handler: httpTriggerReceiveStream, +}); diff --git a/app/v4/src/functions/httpTriggerSendStream.ts b/app/v4/src/functions/httpTriggerSendStream.ts new file mode 100644 index 0000000..8da1c2f --- /dev/null +++ b/app/v4/src/functions/httpTriggerSendStream.ts @@ -0,0 +1,22 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the MIT License. + +import { app, HttpRequest, HttpResponseInit, InvocationContext } from '@azure/functions'; +import { createRandomStream } from '../utils/streamHttp'; + +export async function httpTriggerSendStream( + request: HttpRequest, + context: InvocationContext +): Promise { + context.log(`Http function processed request for url "${request.url}"`); + + const lengthInMb = request.query.get('lengthInMb'); + const stream = createRandomStream(Number(lengthInMb)); + return { body: stream }; +} + +app.http('httpTriggerSendStream', { + methods: ['GET', 'POST'], + authLevel: 'anonymous', + handler: httpTriggerSendStream, +}); diff --git a/app/v4/src/setup.ts b/app/v4/src/setup.ts new file mode 100644 index 0000000..7671d82 --- /dev/null +++ b/app/v4/src/setup.ts @@ -0,0 +1,6 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the MIT License. + +import { app } from '@azure/functions'; + +app.setup({ enableHttpStream: true }); diff --git a/app/v4/src/utils/delay.ts b/app/v4/src/utils/delay.ts new file mode 100644 index 0000000..7b7a884 --- /dev/null +++ b/app/v4/src/utils/delay.ts @@ -0,0 +1,13 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the MIT License. + +export async function delay(ms: number): Promise { + await new Promise((resolve) => setTimeout(resolve, ms)); +} + +export function delaySync(ms: number): void { + const endTime = Date.now() + ms; + while (Date.now() < endTime) { + // wait + } +} diff --git a/app/v4/src/utils/getRandomTestData.ts b/app/v4/src/utils/getRandomTestData.ts new file mode 100644 index 0000000..4bac3a6 --- /dev/null +++ b/app/v4/src/utils/getRandomTestData.ts @@ -0,0 +1,32 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the MIT License. + +import * as crypto from 'crypto'; +import { delay, delaySync } from './delay'; + +export function getRandomTestData(): string { + // This should start with non-numeric data to prevent this bug from causing a test failure + // https://github.com/Azure/azure-functions-nodejs-library/issues/90 + return `testData${getRandomHexString()}`; +} + +export function getRandomHexString(length = 10): string { + const buffer: Buffer = crypto.randomBytes(Math.ceil(length / 2)); + return buffer.toString('hex').slice(0, length); +} + +export function getRandomInt(min: number, max: number): number { + return Math.floor(Math.random() * (max - min) + min); +} + +export function getRandomBoolean(percentTrue: number): boolean { + return Math.random() * 100 > percentTrue; +} + +export async function addRandomDelay(): Promise { + if (getRandomBoolean(95)) { + await delay(getRandomInt(0, 250)); + } else { + delaySync(getRandomInt(0, 10)); + } +} diff --git a/app/v4/src/utils/streamHttp.ts b/app/v4/src/utils/streamHttp.ts new file mode 100644 index 0000000..84e751e --- /dev/null +++ b/app/v4/src/utils/streamHttp.ts @@ -0,0 +1,57 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the MIT License. + +import * as crypto from 'crypto'; +import { Readable } from 'stream'; +import { delay } from './delay'; + +export function createRandomStream(lengthInMb: number): Readable { + const stream = new Readable(); + stream._read = () => {}; + setTimeout(() => { + void sendRandomData(stream, lengthInMb); + }, 5); + return stream; +} + +async function sendRandomData(stream: Readable, lengthInMb: number): Promise { + const maxChunkSize = oneMb; + let remainingBytes = convertMbToB(lengthInMb); + do { + if (stream.readableLength > maxChunkSize) { + await delay(5); + } else { + const chunkSize = Math.min(maxChunkSize, remainingBytes); + stream.push(crypto.randomBytes(chunkSize)); + remainingBytes -= chunkSize; + } + } while (remainingBytes > 0); + stream.push(null); +} + +export async function receiveStreamWithProgress(stream: { + [Symbol.asyncIterator](): AsyncIterableIterator; +}): Promise { + let bytesReceived = 0; + const logInterval = 500; + let nextLogTime = Date.now(); + for await (const chunk of stream) { + if (Date.now() > nextLogTime) { + nextLogTime = Date.now() + logInterval; + console.log(`Progress: ${convertBToMb(bytesReceived)}mb`); + } + + bytesReceived += chunk.length; + } + return bytesReceived; +} + +const oneMb = 1024 * 1024; + +export function convertMbToB(mb: number): number { + return mb * oneMb; +} + +function convertBToMb(bytes: number) { + return Math.round(bytes / oneMb); +} diff --git a/azure-pipelines/test.yml b/azure-pipelines/test.yml index 13ec506..a04d8c4 100644 --- a/azure-pipelines/test.yml +++ b/azure-pipelines/test.yml @@ -89,9 +89,10 @@ jobs: - script: mv *.tgz package.tgz displayName: 'Rename v4 tgz file' # because the publish command below requires an exact path workingDirectory: '$(Pipeline.Workspace)/nodeLibraryV4/drop' - - script: npm install "$(Pipeline.Workspace)/nodeLibraryV4/drop/package.tgz" - displayName: 'install latest v4 library' - workingDirectory: 'app/v4' + # TODO: Temporary change until actual v4 drop exists with http stream changes + #- script: npm install "$(Pipeline.Workspace)/nodeLibraryV4/drop/package.tgz" + # displayName: 'install latest v4 library' + # workingDirectory: 'app/v4' - script: npm run build displayName: 'build v4 app' workingDirectory: 'app/v4' @@ -117,9 +118,10 @@ jobs: - script: npm ci displayName: 'install deps v4 app (oldConfig)' workingDirectory: 'app/combined/v4-oldConfig' - - script: npm install "$(Pipeline.Workspace)/nodeLibraryV4/drop/package.tgz" - displayName: 'install latest v4 library (oldConfig)' - workingDirectory: 'app/combined/v4-oldConfig' + # TODO: Temporary change until actual v4 drop exists with http stream changes + #- script: npm install "$(Pipeline.Workspace)/nodeLibraryV4/drop/package.tgz" + # displayName: 'install latest v4 library (oldConfig)' + # workingDirectory: 'app/combined/v4-oldConfig' - script: npm run build displayName: 'build v4 app (oldConfig)' workingDirectory: 'app/combined/v4-oldConfig' diff --git a/src/global.test.ts b/src/global.test.ts index f81723f..f8329c7 100644 --- a/src/global.test.ts +++ b/src/global.test.ts @@ -25,6 +25,12 @@ export let isOldConfig: boolean; let childProc: cp.ChildProcess | undefined; let testsDone = false; +interface FuncCliSettings { + hideOutput?: boolean; +} + +export const funcCliSettings: FuncCliSettings = {}; + before(async function (this: Mocha.Context): Promise { model = getModelArg(); if (model === 'v4' && semver.lt(process.versions.node, '18.0.0')) { @@ -108,6 +114,7 @@ async function startFuncProcess(appPath: string): Promise { [EnvVarNames.cosmosDB]: cosmosDBConnectionString, [EnvVarNames.serviceBus]: serviceBusConnectionString, [EnvVarNames.sql]: sqlConnectionString, + FUNCTIONS_REQUEST_BODY_SIZE_LIMIT: '4294967296', }, }, null, @@ -123,7 +130,9 @@ async function startFuncProcess(appPath: string): Promise { childProc.stdout?.on('data', (data: string | Buffer) => { data = data.toString(); - process.stdout.write(data); + if (!funcCliSettings.hideOutput) { + process.stdout.write(data); + } perTestFuncOutput += data; fullFuncOutput += data; }); diff --git a/src/http.test.ts b/src/http.test.ts index c9293bb..e39bfef 100644 --- a/src/http.test.ts +++ b/src/http.test.ts @@ -5,9 +5,12 @@ import { expect } from 'chai'; import { encode } from 'iconv-lite'; // Node.js core added support for fetch in v18, but while we're testing versions <18 we'll use "node-fetch" import { default as fetch, HeadersInit } from 'node-fetch'; +import { Readable } from 'stream'; import util from 'util'; import { getFuncUrl } from './constants'; -import { model } from './global.test'; +import { funcCliSettings, isOldConfig, model } from './global.test'; +import { addRandomDelay, getRandomTestData } from './utils/getRandomTestData'; +import { convertMbToB, createRandomStream, receiveStreamWithProgress } from './utils/streamHttp'; const helloWorldUrl = getFuncUrl('helloWorld'); const httpRawBodyUrl = getFuncUrl('httpRawBody'); @@ -23,6 +26,10 @@ const multipartFormHeaders = getContentTypeHeaders('multipart/form'); const textPlainHeaders = getContentTypeHeaders('text/plain'); describe('http', () => { + afterEach(() => { + funcCliSettings.hideOutput = false; + }); + it('hello world', async () => { const response = await fetch(helloWorldUrl); const body = await response.text(); @@ -57,9 +64,88 @@ describe('http', () => { expect(body).to.equal(''); expect(response.status).to.equal(200); const cookies = response.headers.get('Set-Cookie'); - expect(cookies).to.equal( - 'mycookie=myvalue; max-age=200000; path=/, mycookie2=myvalue; max-age=200000; path=/, mycookie3-expires=myvalue3-expires; max-age=0; path=/, mycookie4-samesite-lax=myvalue; path=/; samesite=lax, mycookie5-samesite-strict=myvalue; path=/; samesite=strict' - ); + if (isOldConfig || model === 'v3') { + expect(cookies).to.equal( + 'mycookie=myvalue; max-age=200000; path=/, mycookie2=myvalue; max-age=200000; path=/, mycookie3-expires=myvalue3-expires; max-age=0; path=/, mycookie4-samesite-lax=myvalue; path=/; samesite=lax, mycookie5-samesite-strict=myvalue; path=/; samesite=strict' + ); + } else { + expect(cookies?.toLowerCase()).to.equal( + 'mycookie=myvalue; max-age=200000, mycookie2=myvalue; max-age=200000; path=/, mycookie3-expires=myvalue3-expires; max-age=0, mycookie4-samesite-lax=myvalue; samesite=lax, mycookie5-samesite-strict=myvalue; samesite=strict' + ); + } + }); + + async function validateIndividualRequest(url: string): Promise { + const data = getRandomTestData(); + await addRandomDelay(); + const response = await fetch(url, { method: 'POST', body: data }); + const body = await response.text(); + expect(body).to.equal(`Hello, ${data}!`); + } + + it('http trigger concurrent requests', async function (this: Mocha.Context) { + funcCliSettings.hideOutput = true; // because this test is too noisy + const url = getFuncUrl('httpTriggerRandomDelay'); + + const reqs: Promise[] = []; + const numReqs = 256; + for (let i = 0; i < numReqs; i++) { + reqs.push(validateIndividualRequest(url)); + } + let countFailed = 0; + let countSucceeded = 0; + const results = await Promise.allSettled(reqs); + for (const result of results) { + if (result.status === 'rejected') { + console.error(result.reason); + countFailed += 1; + } else { + countSucceeded += 1; + } + } + if (countFailed > 0) { + throw new Error(`${countFailed} request(s) failed, ${countSucceeded} succeeded`); + } + }); + + describe('stream', () => { + before(function (this: Mocha.Context) { + if (isOldConfig || model === 'v3') { + this.skip(); + } + }); + + it('hello world stream', async () => { + const body = new Readable(); + body._read = () => {}; + body.push('testName-chunked'); + body.push(null); + + const response = await fetch(helloWorldUrl, { method: 'POST', body }); + const resBody = await response.text(); + expect(resBody).to.equal('Hello, testName-chunked!'); + expect(response.status).to.equal(200); + }); + + for (const lengthInMb of [32, 128, 512, 2048]) { + it(`send stream ${lengthInMb}mb`, async () => { + const funcUrl = getFuncUrl('httpTriggerReceiveStream'); + const randomStream = createRandomStream(lengthInMb); + const response = await fetch(funcUrl, { method: 'POST', body: randomStream }); + const resBody = await response.text(); + expect(resBody).to.equal(`Bytes received: ${convertMbToB(lengthInMb)}`); + expect(response.status).to.equal(200); + }); + + it(`receive stream ${lengthInMb}mb`, async () => { + const funcUrl = getFuncUrl('httpTriggerSendStream'); + const response = await fetch(`${funcUrl}?lengthInMb=${lengthInMb}`, { method: 'GET' }); + + const bytesReceived = await receiveStreamWithProgress(response.body); + expect(bytesReceived).to.equal(convertMbToB(lengthInMb)); + expect(response.status).to.equal(200); + }); + } }); describe('v3 only', () => { diff --git a/src/utils/delay.ts b/src/utils/delay.ts index 297eb21..7b7a884 100644 --- a/src/utils/delay.ts +++ b/src/utils/delay.ts @@ -4,3 +4,10 @@ export async function delay(ms: number): Promise { await new Promise((resolve) => setTimeout(resolve, ms)); } + +export function delaySync(ms: number): void { + const endTime = Date.now() + ms; + while (Date.now() < endTime) { + // wait + } +} diff --git a/src/utils/getRandomTestData.ts b/src/utils/getRandomTestData.ts index 87170f5..4bac3a6 100644 --- a/src/utils/getRandomTestData.ts +++ b/src/utils/getRandomTestData.ts @@ -1,7 +1,8 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the MIT License. -import crypto from 'crypto'; +import * as crypto from 'crypto'; +import { delay, delaySync } from './delay'; export function getRandomTestData(): string { // This should start with non-numeric data to prevent this bug from causing a test failure @@ -13,3 +14,19 @@ export function getRandomHexString(length = 10): string { const buffer: Buffer = crypto.randomBytes(Math.ceil(length / 2)); return buffer.toString('hex').slice(0, length); } + +export function getRandomInt(min: number, max: number): number { + return Math.floor(Math.random() * (max - min) + min); +} + +export function getRandomBoolean(percentTrue: number): boolean { + return Math.random() * 100 > percentTrue; +} + +export async function addRandomDelay(): Promise { + if (getRandomBoolean(95)) { + await delay(getRandomInt(0, 250)); + } else { + delaySync(getRandomInt(0, 10)); + } +} diff --git a/src/utils/streamHttp.ts b/src/utils/streamHttp.ts new file mode 100644 index 0000000..84e751e --- /dev/null +++ b/src/utils/streamHttp.ts @@ -0,0 +1,57 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the MIT License. + +import * as crypto from 'crypto'; +import { Readable } from 'stream'; +import { delay } from './delay'; + +export function createRandomStream(lengthInMb: number): Readable { + const stream = new Readable(); + stream._read = () => {}; + setTimeout(() => { + void sendRandomData(stream, lengthInMb); + }, 5); + return stream; +} + +async function sendRandomData(stream: Readable, lengthInMb: number): Promise { + const maxChunkSize = oneMb; + let remainingBytes = convertMbToB(lengthInMb); + do { + if (stream.readableLength > maxChunkSize) { + await delay(5); + } else { + const chunkSize = Math.min(maxChunkSize, remainingBytes); + stream.push(crypto.randomBytes(chunkSize)); + remainingBytes -= chunkSize; + } + } while (remainingBytes > 0); + stream.push(null); +} + +export async function receiveStreamWithProgress(stream: { + [Symbol.asyncIterator](): AsyncIterableIterator; +}): Promise { + let bytesReceived = 0; + const logInterval = 500; + let nextLogTime = Date.now(); + for await (const chunk of stream) { + if (Date.now() > nextLogTime) { + nextLogTime = Date.now() + logInterval; + console.log(`Progress: ${convertBToMb(bytesReceived)}mb`); + } + + bytesReceived += chunk.length; + } + return bytesReceived; +} + +const oneMb = 1024 * 1024; + +export function convertMbToB(mb: number): number { + return mb * oneMb; +} + +function convertBToMb(bytes: number) { + return Math.round(bytes / oneMb); +} From 67a7d6f99c628cfad9650ffb4558831e03349c31 Mon Sep 17 00:00:00 2001 From: Eric Jizba Date: Thu, 1 Feb 2024 12:48:23 -0800 Subject: [PATCH 2/5] revert temp changes now that library pr is merged --- app/v4/azure-functions-4.1.0.tgz | Bin 74842 -> 0 bytes app/v4/package-lock.json | 18 ++++-------------- app/v4/package.json | 2 +- azure-pipelines/test.yml | 14 ++++++-------- 4 files changed, 11 insertions(+), 23 deletions(-) delete mode 100644 app/v4/azure-functions-4.1.0.tgz diff --git a/app/v4/azure-functions-4.1.0.tgz b/app/v4/azure-functions-4.1.0.tgz deleted file mode 100644 index be640fcfff99b8e6a985ea0ac4ab0a2b77acdb81..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 74842 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 diff --git a/app/v4/package-lock.json b/app/v4/package-lock.json index 584f7e7..3b8a7f3 100644 --- a/app/v4/package-lock.json +++ b/app/v4/package-lock.json @@ -8,7 +8,7 @@ "name": "v4", "version": "1.0.0", "dependencies": { - "@azure/functions": "file:azure-functions-4.1.0.tgz" + "@azure/functions": "^4.2.0" }, "devDependencies": { "@types/long": "^4.0.0", @@ -18,12 +18,10 @@ } }, "node_modules/@azure/functions": { - "version": "4.1.0", - "resolved": "file:azure-functions-4.1.0.tgz", - "integrity": "sha512-VPKQ7mayn8Ke7aebmTfi7GttNW9LhgVGBDNcmApGXWTQialw3Egs8eMtk9cUHP8lQYnWIJiMCdeYCKWnZhmxLQ==", - "license": "MIT", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@azure/functions/-/functions-4.2.0.tgz", + "integrity": "sha512-RSECLoje4jGVpsVRjEzkna9KvmQOVeB96cg8J5J2g41QQpMWCzD1QTPI5+yI0uvOidGRLYElV1zHZjdvsGf9Nw==", "dependencies": { - "cookie": "^0.6.0", "long": "^4.0.0", "undici": "^5.13.0" }, @@ -135,14 +133,6 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "node_modules/cookie": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", - "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", - "engines": { - "node": ">= 0.6" - } - }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", diff --git a/app/v4/package.json b/app/v4/package.json index 18d7b0c..562364c 100644 --- a/app/v4/package.json +++ b/app/v4/package.json @@ -12,7 +12,7 @@ "test": "echo \"No tests yet...\"" }, "dependencies": { - "@azure/functions": "file:azure-functions-4.1.0.tgz" + "@azure/functions": "^4.2.0" }, "devDependencies": { "@types/long": "^4.0.0", diff --git a/azure-pipelines/test.yml b/azure-pipelines/test.yml index a04d8c4..13ec506 100644 --- a/azure-pipelines/test.yml +++ b/azure-pipelines/test.yml @@ -89,10 +89,9 @@ jobs: - script: mv *.tgz package.tgz displayName: 'Rename v4 tgz file' # because the publish command below requires an exact path workingDirectory: '$(Pipeline.Workspace)/nodeLibraryV4/drop' - # TODO: Temporary change until actual v4 drop exists with http stream changes - #- script: npm install "$(Pipeline.Workspace)/nodeLibraryV4/drop/package.tgz" - # displayName: 'install latest v4 library' - # workingDirectory: 'app/v4' + - script: npm install "$(Pipeline.Workspace)/nodeLibraryV4/drop/package.tgz" + displayName: 'install latest v4 library' + workingDirectory: 'app/v4' - script: npm run build displayName: 'build v4 app' workingDirectory: 'app/v4' @@ -118,10 +117,9 @@ jobs: - script: npm ci displayName: 'install deps v4 app (oldConfig)' workingDirectory: 'app/combined/v4-oldConfig' - # TODO: Temporary change until actual v4 drop exists with http stream changes - #- script: npm install "$(Pipeline.Workspace)/nodeLibraryV4/drop/package.tgz" - # displayName: 'install latest v4 library (oldConfig)' - # workingDirectory: 'app/combined/v4-oldConfig' + - script: npm install "$(Pipeline.Workspace)/nodeLibraryV4/drop/package.tgz" + displayName: 'install latest v4 library (oldConfig)' + workingDirectory: 'app/combined/v4-oldConfig' - script: npm run build displayName: 'build v4 app (oldConfig)' workingDirectory: 'app/combined/v4-oldConfig' From ad584faabb7b242b15a1948ed57198b084a89658 Mon Sep 17 00:00:00 2001 From: Eric Jizba Date: Fri, 2 Feb 2024 11:35:54 -0800 Subject: [PATCH 3/5] addRandomAsyncOrSyncDelay --- app/v3/httpTriggerRandomDelay/index.ts | 4 ++-- app/v3/utils/getRandomTestData.ts | 2 +- app/v4/src/functions/httpTriggerRandomDelay.ts | 4 ++-- app/v4/src/utils/getRandomTestData.ts | 2 +- src/http.test.ts | 6 +++--- src/utils/getRandomTestData.ts | 2 +- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/app/v3/httpTriggerRandomDelay/index.ts b/app/v3/httpTriggerRandomDelay/index.ts index 7157cbf..cab6c34 100644 --- a/app/v3/httpTriggerRandomDelay/index.ts +++ b/app/v3/httpTriggerRandomDelay/index.ts @@ -2,12 +2,12 @@ // Licensed under the MIT License. import { AzureFunction, Context, HttpRequest } from '@azure/functions'; -import { addRandomDelay } from '../utils/getRandomTestData'; +import { addRandomAsyncOrSyncDelay } from '../utils/getRandomTestData'; const httpTrigger: AzureFunction = async function (context: Context, req: HttpRequest): Promise { context.log(`Http function processed request for url "${req.url}"`); - await addRandomDelay(); + await addRandomAsyncOrSyncDelay(); const name = req.query.name || req.body || 'world'; diff --git a/app/v3/utils/getRandomTestData.ts b/app/v3/utils/getRandomTestData.ts index 4bac3a6..618f46d 100644 --- a/app/v3/utils/getRandomTestData.ts +++ b/app/v3/utils/getRandomTestData.ts @@ -23,7 +23,7 @@ export function getRandomBoolean(percentTrue: number): boolean { return Math.random() * 100 > percentTrue; } -export async function addRandomDelay(): Promise { +export async function addRandomAsyncOrSyncDelay(): Promise { if (getRandomBoolean(95)) { await delay(getRandomInt(0, 250)); } else { diff --git a/app/v4/src/functions/httpTriggerRandomDelay.ts b/app/v4/src/functions/httpTriggerRandomDelay.ts index 80516d2..ae886a6 100644 --- a/app/v4/src/functions/httpTriggerRandomDelay.ts +++ b/app/v4/src/functions/httpTriggerRandomDelay.ts @@ -2,7 +2,7 @@ // Licensed under the MIT License. import { app, HttpRequest, HttpResponseInit, InvocationContext } from '@azure/functions'; -import { addRandomDelay } from '../utils/getRandomTestData'; +import { addRandomAsyncOrSyncDelay } from '../utils/getRandomTestData'; export async function httpTriggerRandomDelay( request: HttpRequest, @@ -10,7 +10,7 @@ export async function httpTriggerRandomDelay( ): Promise { context.log(`Http function processed request for url "${request.url}"`); - await addRandomDelay(); + await addRandomAsyncOrSyncDelay(); const name = request.query.get('name') || (await request.text()) || 'world'; diff --git a/app/v4/src/utils/getRandomTestData.ts b/app/v4/src/utils/getRandomTestData.ts index 4bac3a6..618f46d 100644 --- a/app/v4/src/utils/getRandomTestData.ts +++ b/app/v4/src/utils/getRandomTestData.ts @@ -23,7 +23,7 @@ export function getRandomBoolean(percentTrue: number): boolean { return Math.random() * 100 > percentTrue; } -export async function addRandomDelay(): Promise { +export async function addRandomAsyncOrSyncDelay(): Promise { if (getRandomBoolean(95)) { await delay(getRandomInt(0, 250)); } else { diff --git a/src/http.test.ts b/src/http.test.ts index e39bfef..80e1433 100644 --- a/src/http.test.ts +++ b/src/http.test.ts @@ -9,7 +9,7 @@ import { Readable } from 'stream'; import util from 'util'; import { getFuncUrl } from './constants'; import { funcCliSettings, isOldConfig, model } from './global.test'; -import { addRandomDelay, getRandomTestData } from './utils/getRandomTestData'; +import { addRandomAsyncOrSyncDelay, getRandomTestData } from './utils/getRandomTestData'; import { convertMbToB, createRandomStream, receiveStreamWithProgress } from './utils/streamHttp'; const helloWorldUrl = getFuncUrl('helloWorld'); @@ -77,7 +77,7 @@ describe('http', () => { async function validateIndividualRequest(url: string): Promise { const data = getRandomTestData(); - await addRandomDelay(); + await addRandomAsyncOrSyncDelay(); const response = await fetch(url, { method: 'POST', body: data }); const body = await response.text(); expect(body).to.equal(`Hello, ${data}!`); @@ -117,7 +117,7 @@ describe('http', () => { it('hello world stream', async () => { const body = new Readable(); - body._read = () => {}; + body._read = () => { }; body.push('testName-chunked'); body.push(null); diff --git a/src/utils/getRandomTestData.ts b/src/utils/getRandomTestData.ts index 4bac3a6..618f46d 100644 --- a/src/utils/getRandomTestData.ts +++ b/src/utils/getRandomTestData.ts @@ -23,7 +23,7 @@ export function getRandomBoolean(percentTrue: number): boolean { return Math.random() * 100 > percentTrue; } -export async function addRandomDelay(): Promise { +export async function addRandomAsyncOrSyncDelay(): Promise { if (getRandomBoolean(95)) { await delay(getRandomInt(0, 250)); } else { From 1c313c4205b61af410f6162a25c4d4cd6907d94c Mon Sep 17 00:00:00 2001 From: Eric Jizba Date: Fri, 2 Feb 2024 16:02:03 -0800 Subject: [PATCH 4/5] fixes for test flakiness, especially the mac agent --- .vscode/settings.json | 2 +- package-lock.json | 28 ++++++++++++++++++++++++---- package.json | 5 +++-- src/http.test.ts | 32 +++++++++++++++++++++++++------- 4 files changed, 53 insertions(+), 14 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 6827c6d..ca70865 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,6 @@ { "azureFunctions.showProjectWarning": false, - "editor.formatOnSave": true, + "editor.formatOnSave": false, "editor.codeActionsOnSave": ["source.fixAll"], "typescript.tsdk": "node_modules/typescript/lib", "typescript.preferences.importModuleSpecifier": "relative", diff --git a/package-lock.json b/package-lock.json index f2dc7c5..0a102a5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -32,6 +32,7 @@ "@types/uuid": "^9.0.4", "@typescript-eslint/eslint-plugin": "^5.12.1", "@typescript-eslint/parser": "^5.12.1", + "agentkeepalive": "^4.5.0", "chai": "^4.2.0", "chai-as-promised": "^7.1.1", "eslint": "^7.32.0", @@ -49,7 +50,7 @@ "mocha-junit-reporter": "^2.0.2", "mocha-multi-reporters": "^1.5.1", "mssql": "^9.1.0", - "node-fetch": "^2.0.0", + "node-fetch": "2.6.7", "p-retry": "^4.0.0", "prettier": "^2.4.1", "rimraf": "^5.0.0", @@ -1526,6 +1527,17 @@ "node": ">= 6.0.0" } }, + "node_modules/agentkeepalive": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.5.0.tgz", + "integrity": "sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==", + "dependencies": { + "humanize-ms": "^1.2.1" + }, + "engines": { + "node": ">= 8.0.0" + } + }, "node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -3296,6 +3308,14 @@ "node": ">= 6" } }, + "node_modules/humanize-ms": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", + "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", + "dependencies": { + "ms": "^2.0.0" + } + }, "node_modules/iconv-lite": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", @@ -4325,9 +4345,9 @@ "integrity": "sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==" }, "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==", + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", "dependencies": { "whatwg-url": "^5.0.0" }, diff --git a/package.json b/package.json index 65ee8f4..d960777 100644 --- a/package.json +++ b/package.json @@ -59,6 +59,7 @@ "@types/uuid": "^9.0.4", "@typescript-eslint/eslint-plugin": "^5.12.1", "@typescript-eslint/parser": "^5.12.1", + "agentkeepalive": "^4.5.0", "chai": "^4.2.0", "chai-as-promised": "^7.1.1", "eslint": "^7.32.0", @@ -76,7 +77,7 @@ "mocha-junit-reporter": "^2.0.2", "mocha-multi-reporters": "^1.5.1", "mssql": "^9.1.0", - "node-fetch": "^2.0.0", + "node-fetch": "2.6.7", "p-retry": "^4.0.0", "prettier": "^2.4.1", "rimraf": "^5.0.0", @@ -86,4 +87,4 @@ "typescript": "^4.5.5", "uuid": "^9.0.1" } -} \ No newline at end of file +} diff --git a/src/http.test.ts b/src/http.test.ts index 80e1433..ff6c06c 100644 --- a/src/http.test.ts +++ b/src/http.test.ts @@ -1,6 +1,7 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the MIT License. +import Agent from 'agentkeepalive'; import { expect } from 'chai'; import { encode } from 'iconv-lite'; // Node.js core added support for fetch in v18, but while we're testing versions <18 we'll use "node-fetch" @@ -75,10 +76,20 @@ describe('http', () => { } }); + // Use a connection pool to avoid flaky test failures due to various connection limits (Mac in particular seems to have a low limit) + // NOTE: The node-fetch package has a bug starting in 2.6.8 related to keep alive agents, so we have to use 2.6.7 + // https://github.com/node-fetch/node-fetch/issues/1767 + const keepaliveAgent = new Agent({ maxSockets: 128, maxFreeSockets: 64 }); + async function validateIndividualRequest(url: string): Promise { const data = getRandomTestData(); await addRandomAsyncOrSyncDelay(); - const response = await fetch(url, { method: 'POST', body: data }); + const response = await fetch(url, { + method: 'POST', + body: data, + timeout: 40 * 1000, + agent: keepaliveAgent, + }); const body = await response.text(); expect(body).to.equal(`Hello, ${data}!`); } @@ -88,23 +99,30 @@ describe('http', () => { const url = getFuncUrl('httpTriggerRandomDelay'); const reqs: Promise[] = []; - const numReqs = 256; + const numReqs = 1024; for (let i = 0; i < numReqs; i++) { reqs.push(validateIndividualRequest(url)); } let countFailed = 0; + let countTimedOut = 0; let countSucceeded = 0; const results = await Promise.allSettled(reqs); for (const result of results) { if (result.status === 'rejected') { - console.error(result.reason); - countFailed += 1; + if (typeof result.reason?.message === 'string' && /timeout/i.test(result.reason.message)) { + countTimedOut += 1; + } else { + console.error(result.reason); + countFailed += 1; + } } else { countSucceeded += 1; } } - if (countFailed > 0) { - throw new Error(`${countFailed} request(s) failed, ${countSucceeded} succeeded`); + if (countFailed > 0 || countTimedOut > 0) { + throw new Error( + `${countFailed} request(s) failed, ${countTimedOut} timed out, ${countSucceeded} succeeded` + ); } }); @@ -117,7 +135,7 @@ describe('http', () => { it('hello world stream', async () => { const body = new Readable(); - body._read = () => { }; + body._read = () => {}; body.push('testName-chunked'); body.push(null); From 9cfae912732b4630c9d5989a65d8e62e36347c97 Mon Sep 17 00:00:00 2001 From: Eric Jizba Date: Mon, 5 Feb 2024 14:55:25 -0800 Subject: [PATCH 5/5] feedback --- app/v4/src/utils/streamHttp.ts | 4 ++-- src/http.test.ts | 3 +++ src/utils/streamHttp.ts | 4 ++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/app/v4/src/utils/streamHttp.ts b/app/v4/src/utils/streamHttp.ts index 84e751e..68760d8 100644 --- a/app/v4/src/utils/streamHttp.ts +++ b/app/v4/src/utils/streamHttp.ts @@ -5,6 +5,8 @@ import * as crypto from 'crypto'; import { Readable } from 'stream'; import { delay } from './delay'; +const oneMb = 1024 * 1024; + export function createRandomStream(lengthInMb: number): Readable { const stream = new Readable(); stream._read = () => {}; @@ -46,8 +48,6 @@ export async function receiveStreamWithProgress(stream: { return bytesReceived; } -const oneMb = 1024 * 1024; - export function convertMbToB(mb: number): number { return mb * oneMb; } diff --git a/src/http.test.ts b/src/http.test.ts index ff6c06c..1a7c349 100644 --- a/src/http.test.ts +++ b/src/http.test.ts @@ -65,6 +65,9 @@ describe('http', () => { expect(body).to.equal(''); expect(response.status).to.equal(200); const cookies = response.headers.get('Set-Cookie'); + + // Cookie logic changed slightly with the http streaming feature, although it should be functionally the same + // The old logic adds the default "path=/" to every cookie and the new logic only adds the path if it's explicitly specified if (isOldConfig || model === 'v3') { expect(cookies).to.equal( 'mycookie=myvalue; max-age=200000; path=/, mycookie2=myvalue; max-age=200000; path=/, mycookie3-expires=myvalue3-expires; max-age=0; path=/, mycookie4-samesite-lax=myvalue; path=/; samesite=lax, mycookie5-samesite-strict=myvalue; path=/; samesite=strict' diff --git a/src/utils/streamHttp.ts b/src/utils/streamHttp.ts index 84e751e..68760d8 100644 --- a/src/utils/streamHttp.ts +++ b/src/utils/streamHttp.ts @@ -5,6 +5,8 @@ import * as crypto from 'crypto'; import { Readable } from 'stream'; import { delay } from './delay'; +const oneMb = 1024 * 1024; + export function createRandomStream(lengthInMb: number): Readable { const stream = new Readable(); stream._read = () => {}; @@ -46,8 +48,6 @@ export async function receiveStreamWithProgress(stream: { return bytesReceived; } -const oneMb = 1024 * 1024; - export function convertMbToB(mb: number): number { return mb * oneMb; }