Skip to content

Commit

Permalink
test: add ranged read test, performance test code cleanups (#2161)
Browse files Browse the repository at this point in the history
* test: add ranged read test to performance tests

* test: add ranged read test, performance test code cleanups

* use require for yargs since we do not have esModuleInterop set

* fix output type variable name

* clean up naming

* fix w1r3 directory

* use as const instead of enum

* only report last read for w1r3
  • Loading branch information
ddelgrosso1 authored Mar 9, 2023
1 parent 6b8a848 commit 0501127
Show file tree
Hide file tree
Showing 5 changed files with 326 additions and 186 deletions.
44 changes: 20 additions & 24 deletions internal-tooling/performApplicationPerformanceTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
*/

import yargs from 'yargs';
const yargs = require('yargs');
import {promises as fsp, rmSync} from 'fs';
import {
Bucket,
Expand All @@ -28,33 +28,24 @@ import {performance} from 'perf_hooks';
import {parentPort} from 'worker_threads';
import {
BLOCK_SIZE_IN_BYTES,
DEFAULT_PROJECT_ID,
DEFAULT_NUMBER_OF_OBJECTS,
DEFAULT_SMALL_FILE_SIZE_BYTES,
DEFAULT_LARGE_FILE_SIZE_BYTES,
NODE_DEFAULT_HIGHWATER_MARK_BYTES,
generateRandomDirectoryStructure,
getValidationType,
performanceTestSetup,
TestResult,
performanceTestCommand,
getLowHighFileSize,
PERFORMANCE_TEST_TYPES,
} from './performanceUtils';
import {TRANSFER_MANAGER_TEST_TYPES} from './performanceTest';

const TEST_NAME_STRING = 'nodejs-perf-metrics-application';
const DEFAULT_BUCKET_NAME = 'nodejs-perf-metrics-shaffeeullah';

let bucket: Bucket;

const checkType = getValidationType();

const argv = yargs(process.argv.slice(2))
.options({
bucket: {type: 'string', default: DEFAULT_BUCKET_NAME},
small: {type: 'number', default: DEFAULT_SMALL_FILE_SIZE_BYTES},
large: {type: 'number', default: DEFAULT_LARGE_FILE_SIZE_BYTES},
projectid: {type: 'string', default: DEFAULT_PROJECT_ID},
numobjects: {type: 'number', default: DEFAULT_NUMBER_OF_OBJECTS},
})
.command(performanceTestCommand)
.parseSync();

/**
Expand All @@ -74,15 +65,16 @@ async function main() {
cpuTimeUs: 0,
status: '[OK]',
chunkSize: 0,
workers: argv.workers,
};

({bucket} = await performanceTestSetup(argv.projectid, argv.bucket));
({bucket} = await performanceTestSetup(argv.project!, argv.bucket!));

switch (argv.testtype) {
case TRANSFER_MANAGER_TEST_TYPES.APPLICATION_UPLOAD_MULTIPLE_OBJECTS:
switch (argv.test_type) {
case PERFORMANCE_TEST_TYPES.APPLICATION_UPLOAD_MULTIPLE_OBJECTS:
result = await performWriteTest();
break;
case TRANSFER_MANAGER_TEST_TYPES.APPLICATION_DOWNLOAD_MULTIPLE_OBJECTS:
case PERFORMANCE_TEST_TYPES.APPLICATION_DOWNLOAD_MULTIPLE_OBJECTS:
result = await performReadTest();
break;
// case TRANSFER_MANAGER_TEST_TYPES.APPLICATION_LARGE_FILE_DOWNLOAD:
Expand Down Expand Up @@ -129,11 +121,12 @@ async function downloadInParallel(bucket: Bucket, options: DownloadOptions) {
async function performWriteTest(): Promise<TestResult> {
await bucket.deleteFiles(); //start clean

const fileSizeRange = getLowHighFileSize(argv.object_size);
const creationInfo = generateRandomDirectoryStructure(
argv.numobjects,
argv.num_objects,
TEST_NAME_STRING,
argv.small,
argv.large
fileSizeRange.low,
fileSizeRange.high
);

const start = performance.now();
Expand All @@ -155,6 +148,7 @@ async function performWriteTest(): Promise<TestResult> {
cpuTimeUs: -1,
status: '[OK]',
chunkSize: creationInfo.totalSizeInBytes,
workers: argv.workers,
};
return result;
}
Expand All @@ -165,12 +159,13 @@ async function performWriteTest(): Promise<TestResult> {
* @returns {Promise<TestResult>} Promise that resolves to an array of test results for the iteration.
*/
async function performReadTest(): Promise<TestResult> {
const fileSizeRange = getLowHighFileSize(argv.object_size);
await bucket.deleteFiles(); // start clean
const creationInfo = generateRandomDirectoryStructure(
argv.numobjects,
argv.num_objects,
TEST_NAME_STRING,
argv.small,
argv.large
fileSizeRange.low,
fileSizeRange.high
);
await uploadInParallel(bucket, creationInfo.paths, {validation: checkType});

Expand All @@ -190,6 +185,7 @@ async function performReadTest(): Promise<TestResult> {
cpuTimeUs: -1,
status: '[OK]',
chunkSize: creationInfo.totalSizeInBytes,
workers: argv.workers,
};

rmSync(TEST_NAME_STRING, {recursive: true, force: true});
Expand Down
136 changes: 104 additions & 32 deletions internal-tooling/performPerformanceTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,63 +14,133 @@
* limitations under the License.
*/

import yargs from 'yargs';
const yargs = require('yargs');
import {performance} from 'perf_hooks';
// eslint-disable-next-line node/no-unsupported-features/node-builtins
import {parentPort} from 'worker_threads';
import * as path from 'path';
import {
BLOCK_SIZE_IN_BYTES,
cleanupFile,
DEFAULT_LARGE_FILE_SIZE_BYTES,
DEFAULT_PROJECT_ID,
DEFAULT_SMALL_FILE_SIZE_BYTES,
generateRandomFile,
generateRandomFileName,
getLowHighFileSize,
getValidationType,
NODE_DEFAULT_HIGHWATER_MARK_BYTES,
performanceTestCommand,
performanceTestSetup,
PERFORMANCE_TEST_TYPES,
TestResult,
} from './performanceUtils';
import {Bucket} from '../src';
import {rmSync} from 'fs';

const TEST_NAME_STRING = 'nodejs-perf-metrics';
const DEFAULT_NUMBER_OF_WRITES = 1;
const DEFAULT_NUMBER_OF_READS = 3;
const DEFAULT_BUCKET_NAME = 'nodejs-perf-metrics';
const DEFAULT_RANGE_READS = 3;

let bucket: Bucket;
const checkType = getValidationType();

const argv = yargs(process.argv.slice(2))
.options({
bucket: {type: 'string', default: DEFAULT_BUCKET_NAME},
small: {type: 'number', default: DEFAULT_SMALL_FILE_SIZE_BYTES},
large: {type: 'number', default: DEFAULT_LARGE_FILE_SIZE_BYTES},
projectid: {type: 'string', default: DEFAULT_PROJECT_ID},
})
.command(performanceTestCommand)
.parseSync();

/**
* Main entry point. This function performs a test iteration and posts the message back
* to the parent thread.
*/
async function main() {
const results = await performWriteReadTest();
let results: TestResult[] = [];

({bucket} = await performanceTestSetup(argv.project!, argv.bucket!));

switch (argv.test_type) {
case PERFORMANCE_TEST_TYPES.WRITE_ONE_READ_THREE:
results = await performWriteReadTest();
break;
case PERFORMANCE_TEST_TYPES.RANGE_READ:
results = await performRangedReadTest();
break;
default:
break;
}

parentPort?.postMessage(results);
}

/**
* Performs an iteration of a ranged read test. Only the last result will be reported.
*
* @returns {Promise<TestResult[]>} Promise that resolves to an array of test results for the iteration.
*/
async function performRangedReadTest(): Promise<TestResult[]> {
const results: TestResult[] = [];
const fileSizeRange = getLowHighFileSize(argv.object_size);
const fileName = generateRandomFileName(TEST_NAME_STRING);
const sizeInBytes = generateRandomFile(
fileName,
fileSizeRange.low,
fileSizeRange.high,
__dirname
);
const file = bucket.file(`${fileName}`);
const destinationFileName = generateRandomFileName(TEST_NAME_STRING);
const destination = path.join(__dirname, destinationFileName);

const iterationResult: TestResult = {
op: 'READ',
objectSize: sizeInBytes,
appBufferSize: BLOCK_SIZE_IN_BYTES,
libBufferSize: NODE_DEFAULT_HIGHWATER_MARK_BYTES,
crc32Enabled: false,
md5Enabled: false,
apiName: 'JSON',
elapsedTimeUs: 0,
cpuTimeUs: -1,
status: '[OK]',
chunkSize: argv.range_read_size,
workers: argv.workers,
};

await bucket.upload(`${__dirname}/${fileName}`);
cleanupFile(fileName);

for (let i = 0; i < DEFAULT_RANGE_READS; i++) {
const start = performance.now();
await file.download({
start: 0,
end: argv.range_read_size,
destination,
});
const end = performance.now();
cleanupFile(destinationFileName);
iterationResult.elapsedTimeUs = Math.round((end - start) * 1000);
}

rmSync(TEST_NAME_STRING, {recursive: true, force: true});
await file.delete();
results.push(iterationResult);
return results;
}

/**
* Performs an iteration of the Write 1 / Read 3 performance measuring test.
*
* @returns {Promise<TestResult[]>} Promise that resolves to an array of test results for the iteration.
*/
async function performWriteReadTest(): Promise<TestResult[]> {
const results: TestResult[] = [];
const fileSizeRange = getLowHighFileSize(argv.object_size);
const fileName = generateRandomFileName(TEST_NAME_STRING);
const sizeInBytes = generateRandomFile(fileName, argv.small, argv.large);

({bucket} = await performanceTestSetup(argv.projectid, argv.bucket));
const file = bucket.file(`${fileName}`);
const sizeInBytes = generateRandomFile(
fileName,
fileSizeRange.low,
fileSizeRange.high,
__dirname
);

for (let j = 0; j < DEFAULT_NUMBER_OF_WRITES; j++) {
let start = 0;
Expand All @@ -88,6 +158,7 @@ async function performWriteReadTest(): Promise<TestResult[]> {
cpuTimeUs: -1,
status: '[OK]',
chunkSize: sizeInBytes,
workers: argv.workers,
};

start = performance.now();
Expand All @@ -98,23 +169,24 @@ async function performWriteReadTest(): Promise<TestResult[]> {
results.push(iterationResult);
}

const iterationResult: TestResult = {
op: 'READ',
objectSize: sizeInBytes,
appBufferSize: BLOCK_SIZE_IN_BYTES,
libBufferSize: NODE_DEFAULT_HIGHWATER_MARK_BYTES,
crc32Enabled: checkType === 'crc32c',
md5Enabled: checkType === 'md5',
apiName: 'JSON',
elapsedTimeUs: 0,
cpuTimeUs: -1,
status: '[OK]',
chunkSize: sizeInBytes,
workers: argv.workers,
};

for (let j = 0; j < DEFAULT_NUMBER_OF_READS; j++) {
let start = 0;
let end = 0;
const file = bucket.file(`${fileName}`);
const iterationResult: TestResult = {
op: `READ[${j}]`,
objectSize: sizeInBytes,
appBufferSize: BLOCK_SIZE_IN_BYTES,
libBufferSize: NODE_DEFAULT_HIGHWATER_MARK_BYTES,
crc32Enabled: checkType === 'crc32c',
md5Enabled: checkType === 'md5',
apiName: 'JSON',
elapsedTimeUs: 0,
cpuTimeUs: -1,
status: '[OK]',
chunkSize: sizeInBytes,
};

const destinationFileName = generateRandomFileName(TEST_NAME_STRING);
const destination = path.join(__dirname, destinationFileName);
Expand All @@ -125,11 +197,11 @@ async function performWriteReadTest(): Promise<TestResult[]> {

cleanupFile(destinationFileName);
iterationResult.elapsedTimeUs = Math.round((end - start) * 1000);
results.push(iterationResult);
}

cleanupFile(fileName);

rmSync(TEST_NAME_STRING, {recursive: true, force: true});
await file.delete();
results.push(iterationResult);
return results;
}

Expand Down
Loading

0 comments on commit 0501127

Please sign in to comment.