123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137 |
- #!/usr/bin/env node
- const { ContentId } = require('@joystream/types/storage')
- const { ApiPromise, WsProvider } = require('@polkadot/api')
- const { types } = require('@joystream/types')
- const fsPromises = require('fs/promises')
- const fs = require('fs')
- const Path = require('path')
- const {
- getActiveWorkersIds,
- getWorkerEndpoint,
- generateListOfDataObjectsToDownload,
- makeAssetUrl,
- downloadFile,
- clearFolder,
- computeMedian
- } = require('./utils')
- const { program } = require('commander')
- const TEMP_FOLDER = Path.resolve(__dirname, '../', 'temp')
- const PROVIDER_URL = 'wss://rome-rpc-endpoint.joystream.org:9944'
- const NR_DEFAULT_SMALL_ASSETS = 9
- const NR_BIG_ASSETS = 1
- async function main() {
- program
- .option('-w, --workers <workerId>', `the Worker id's to perform the tests, separated by comma. Ex: 4,5,6`)
- .option('-f, --asset-file [path]', 'a list of assets ids to download the same files for different providers')
- .option('-s, --nr-small-assets [number]', 'the number of small files to download', NR_DEFAULT_SMALL_ASSETS)
- .option('-b, --nr-big-assets [number]', 'the number of big files to download', NR_BIG_ASSETS)
- .parse()
- const provider = new WsProvider(process.env.PROVIDER_URL || PROVIDER_URL)
- const api = await ApiPromise.create({ provider, types })
- await api.isReady
- const args = program.opts()
- let dataObjectsIds = []
- const assetsFilePath = args.assetFile
- if (assetsFilePath) {
- try {
- await fsPromises.access(assetsFilePath, fs.constants.R_OK)
- } catch {
- console.error('Unable to read ' + assetsFilePath)
- process.exit(1)
- }
- const data = (await fsPromises.readFile(assetsFilePath, 'utf8')).toString()
- dataObjectsIds = data
- .split('\n')
- .filter((line) => line)
- .map((line) => ContentId.decode(api.registry, line))
- } else {
- dataObjectsIds = await generateListOfDataObjectsToDownload(api, args.nrSmallAssets, args.nrBigAssets)
- const writeStream = fs.createWriteStream(Path.join(__dirname, '..', 'assets.txt'))
- for (const id of dataObjectsIds) {
- writeStream.write(id.encode() + '\n')
- }
- writeStream.close()
- }
- const dataObjects = await Promise.all(
- dataObjectsIds.map(async (id) => {
- const dataObject = await api.query.dataDirectory.dataByContentId(id)
- dataObject.contentId = id
- return dataObject
- })
- )
- let workerIds = args.workers?.split(',')
- if (!workerIds) {
- workerIds = await getActiveWorkersIds(api)
- }
- let success = true
- try {
- for (const workerId of workerIds) {
- try {
- await testWorker(api, workerId, dataObjects)
- } catch (e) {
- console.error(e)
- }
- await clearFolder(TEMP_FOLDER)
- }
- } catch {
- success = false
- } finally {
- await api.disconnect()
- }
- if (!success) {
- process.exit(2)
- }
- }
- async function testWorker(api, workerId, dataObjects) {
- const endpoint = await getWorkerEndpoint(api, workerId)
- if (!endpoint) {
- throw new Error(`Worker ${workerId} doesn't have an endpoint defined`)
- }
- const promises = []
- const startRequests = process.hrtime.bigint()
- for (const dataObject of dataObjects) {
- const url = makeAssetUrl(dataObject.contentId, endpoint)
- promises.push(downloadFile(url, TEMP_FOLDER, dataObject.contentId.toString()))
- }
- try {
- const times = await Promise.all(promises)
- const endRequests = process.hrtime.bigint()
- const totalTime = Number((endRequests - startRequests) / BigInt(1000000))
- const totalSizeInMegas =
- dataObjects.reduce((accumulator, dataObject) => accumulator + Number(dataObject.size_in_bytes), 0) / 1024 / 1024
- const average = times.reduce((accumulator, time) => accumulator + time, 0) / times.length
- console.log(
- JSON.stringify({
- averageMs: Number(average.toFixed(2)),
- medianMs: Number(computeMedian(times).toFixed(2)),
- maxMs: Number(Math.max.apply(Math, times).toFixed(2)),
- minMs: Number(Math.min.apply(Math, times).toFixed(2)),
- totalTimeMs: totalTime,
- averageSpeedMBpS: Number((totalSizeInMegas / (totalTime / 100)).toFixed(3)),
- nrFilesDownloaded: times.length,
- workerId: workerId,
- })
- )
- } catch (e) {
- throw new Error('Fail to download files from worker')
- }
- }
- main()
|