-
-
Save ning-yu/e9763e5ee5d6ae4dacab to your computer and use it in GitHub Desktop.
Stress test for Volumio2 library
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var libCrypto = require('crypto'); | |
var libBase64Url = require('base64-url'); | |
var libUtil = require('util'); | |
var nGenres = 7; // Change this number to adjust stress test magnitude | |
var nArtistsPerGenre = 50; | |
var nAlbumsPerArtist = 10; | |
var nTracksPerAlbum = 10; | |
var nServicesPerTrack = 3; | |
var nTotalItems = nGenres * nArtistsPerGenre * nAlbumsPerArtist * nTracksPerAlbum * nServicesPerTrack; | |
var arrayExtraArtistsPerTrack = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2]; | |
var arrayExtraAlbumsPerTrack = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]; | |
var arrayExtraGenresPerTrack = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]; | |
var timeStart; | |
console.log('Generating ' + nTotalItems + ' unique random items...'); | |
timeStart = Date.now(); | |
var arrayServices = new Array(); | |
for (i = 0; i < nServicesPerTrack; i++) { | |
arrayServices.push(randomValueBase64(randomInt(20,80))); | |
} | |
//console.log(arrayServices); | |
var objRandomTree = new Object(); | |
for (var i = 0; i < nGenres; i++) { | |
curGenre = randomValueBase64(randomInt(20,80)); | |
objRandomTree[curGenre] = new Object(); | |
for (var j = 0; j < nArtistsPerGenre; j++) { | |
curArtist = randomValueBase64(randomInt(20,80)); | |
objRandomTree[curGenre][curArtist] = new Object(); | |
for (var k = 0; k < nAlbumsPerArtist; k++) { | |
curAlbum = randomValueBase64(randomInt(20,80)); | |
objRandomTree[curGenre][curArtist][curAlbum] = new Object(); | |
} | |
} | |
} | |
var arrayGenres = new Array(); | |
var arrayArtists = new Array(); | |
var arrayAlbums = new Array(); | |
var arrayItems = new Array(); | |
var arrayTitles = new Array(); | |
var curGenreList = new Array(); | |
var curArtistList = new Array(); | |
var curAlbumList = new Array(); | |
var curTitle = ''; | |
var curGenre = ''; | |
var curArtist = ''; | |
var curAlbum = ''; | |
var curTrack = ''; | |
var curUri = ''; | |
var curService = ''; | |
var nExtraGenres = 0; | |
var nExtraArtists = 0; | |
var nExtraAlbums = 0; | |
var nCompletedItems = 0; | |
var timeLastUpdate = Date.now(); | |
arrayGenres = Object.keys(objRandomTree); | |
for (var i = 0; i < nGenres; i++) { | |
curGenre = arrayGenres[i]; | |
arrayArtists = Object.keys(objRandomTree[curGenre]); | |
for (var j = 0; j < nArtistsPerGenre; j++) { | |
curArtist = arrayArtists[j] | |
if (Date.now() - timeLastUpdate > 3000) { | |
console.log(' ' + (Math.round((nCompletedItems + 1) / nTotalItems * 1000) / 10) + '%'); | |
timeLastUpdate = Date.now(); | |
} | |
arrayAlbums = Object.keys(objRandomTree[curGenre][curArtist]); | |
for (var k = 0; k < nAlbumsPerArtist; k++) { | |
curAlbum = arrayAlbums[k]; | |
for (var m = 0; m < nTracksPerAlbum; m++) { | |
curTrack = randomValueBase64(randomInt(20,80)); | |
curGenreList = [curGenre]; | |
curArtistList = [curArtist]; | |
curAlbumList = [curAlbum]; | |
nExtraGenres = arrayExtraGenresPerTrack[randomInt(0, arrayExtraGenresPerTrack.length - 1)]; | |
nExtraArtists = arrayExtraArtistsPerTrack[randomInt(0, arrayExtraArtistsPerTrack.length - 1)]; | |
nExtraAlbums = arrayExtraAlbumsPerTrack[randomInt(0, arrayExtraAlbumsPerTrack.length - 1)]; | |
for (var p = 0; p < nExtraGenres; p++) { | |
// duplicates are possible, but we don't really care - library does not add duplicates | |
curGenreList = curGenreList.concat(arrayGenres[randomInt(0, nGenres - 1)]); | |
} | |
for (var p = 0; p < nExtraArtists; p++) { | |
// duplicates are possible, but we don't really care - library does not add duplicates | |
curArtistList = curArtistList.concat(arrayArtists[randomInt(0, nArtistsPerGenre - 1)]); | |
} | |
for (var p = 0; p < nExtraAlbums; p++) { | |
// duplicates are possible, but we don't really care - library does not add duplicates | |
curAlbumList = curAlbumList.concat(arrayAlbums[randomInt(0, nAlbumsPerArtist - 1)]); | |
} | |
for (var n = 0; n < nServicesPerTrack; n++) { | |
curUri = randomValueBase64(randomInt(20,80)); | |
curService = arrayServices[n]; | |
arrayItems.push({ | |
'service': curService, | |
'uri': curUri, | |
'metadata': { | |
'title': curTrack, | |
'genres': curGenreList, | |
'artists': curArtistList, | |
'albums': curAlbumList | |
} | |
}); | |
nCompletedItems ++; | |
} | |
} | |
} | |
} | |
} | |
console.log(' done in ' + (Date.now() - timeStart) + 'ms.'); | |
/* | |
for (var i = 0; i < 100; i++) { | |
console.log(libUtil.inspect(arrayItems[i], {'depth': null})); | |
} | |
*/ | |
console.log('Populating library...'); | |
timeStart = Date.now(); | |
var library = populateLibrary(arrayItems); | |
console.log(' done in ' + (Date.now() - timeStart) + 'ms.'); | |
console.log('Clearing random data...'); | |
arrayItems = new Array(); | |
console.log(' done.'); | |
console.log('tableGenres size: ' + Object.keys(library['genretable']).length); | |
console.log('tableArtists size: ' + Object.keys(library['artisttable']).length); | |
console.log('tableAlbums size: ' + Object.keys(library['albumtable']).length); | |
console.log('tableTracks size: ' + Object.keys(library['tracktable']).length); | |
console.log('tableItems size: ' + Object.keys(library['itemtable']).length); | |
console.log('\nShowing contents of genre key ' + Object.keys(library['genretable'])[0]); | |
console.log(library['genretable'][Object.keys(library['genretable'])[0]]); | |
console.log('\nShowing contents of artist key ' + Object.keys(library['artisttable'])[0]); | |
console.log(library['artisttable'][Object.keys(library['artisttable'])[0]]); | |
console.log('\nShowing contents of album key ' + Object.keys(library['albumtable'])[0]); | |
console.log(library['albumtable'][Object.keys(library['albumtable'])[0]]); | |
console.log('\nShowing contents of track key ' + Object.keys(library['tracktable'])[0]); | |
console.log(library['tracktable'][Object.keys(library['tracktable'])[0]]); | |
console.log('\nShowing contents of item key ' + Object.keys(library['itemtable'])[0]); | |
console.log(library['itemtable'][Object.keys(library['itemtable'])[0]]); | |
// Start reading from stdin so we don't exit. This gives the user time to check memory usage of the full populated library. | |
process.stdin.resume(); | |
// Functions below ------------------------------------------------ | |
function populateLibrary (arrayItems) { | |
var tableGenres = new Object(); | |
var tableArtists = new Object(); | |
var tableAlbums = new Object(); | |
var tableTracks = new Object(); | |
var tableItems = new Object(); | |
var objReturn = {'genretable': tableGenres, 'artisttable': tableArtists, 'albumtable': tableAlbums, 'tracktable': tableTracks, 'itemtable': tableItems}; | |
var timeLastUpdate = Date.now(); | |
var curAlbums = new Array(); | |
var curArtists = new Array(); | |
var curGenres = new Array(); | |
for (var iItem = 0; iItem < arrayItems.length; iItem++) { | |
if (Date.now() - timeLastUpdate > 3000) { | |
console.log(' ' + (Math.round((iItem + 1) / arrayItems.length * 1000) / 10) + '%'); | |
timeLastUpdate = Date.now(); | |
} | |
curItemObject = arrayItems[iItem]; | |
curItemKey = convertStringToHashkey(curItemObject['service'] + curItemObject['uri']); | |
tableItems[curItemKey] = curItemObject; | |
tableItems[curItemKey]['trackkey'] = new Object(); | |
curTrackKey = convertStringToHashkey(curItemObject['metadata']['title']); | |
if (!(curTrackKey in tableTracks)) { | |
tableTracks[curTrackKey] = new Object(); | |
tableTracks[curTrackKey]['itemkeys'] = new Object(); | |
tableTracks[curTrackKey]['albumkeys'] = new Object(); | |
tableTracks[curTrackKey]['metadata'] = new Object(); | |
tableTracks[curTrackKey]['metadata']['title'] = curItemObject['metadata']['title']; | |
} | |
tableTracks[curTrackKey]['itemkeys'][curItemKey] = null; | |
tableItems[curItemKey]['trackkey'][curTrackKey] = null; | |
curAlbums = curItemObject['metadata']['albums']; | |
for (var iAlbum = 0; iAlbum < curAlbums.length; iAlbum++) { | |
curAlbumKey = convertStringToHashkey(curAlbums[iAlbum]); | |
if (!(curAlbumKey in tableAlbums)) { | |
tableAlbums[curAlbumKey] = new Object(); | |
tableAlbums[curAlbumKey]['trackkeys'] = new Object(); | |
tableAlbums[curAlbumKey]['artistkeys'] = new Object(); | |
tableAlbums[curAlbumKey]['metadata'] = new Object(); | |
tableAlbums[curAlbumKey]['metadata']['title'] = curAlbums[iAlbum]; | |
} | |
tableAlbums[curAlbumKey]['trackkeys'][curTrackKey] = null; | |
tableTracks[curTrackKey]['albumkeys'][curAlbumKey] = null; | |
curArtists = curItemObject['metadata']['artists']; | |
for (var iArtist = 0; iArtist < curArtists.length; iArtist++) { | |
curArtistKey = convertStringToHashkey(curArtists[iArtist]); | |
if (!(curArtistKey in tableArtists)) { | |
tableArtists[curArtistKey] = new Object(); | |
tableArtists[curArtistKey]['albumkeys'] = new Object(); | |
tableArtists[curArtistKey]['genrekeys'] = new Object(); | |
tableArtists[curArtistKey]['metadata'] = new Object(); | |
tableArtists[curArtistKey]['metadata']['name'] = curArtists[iArtist]; | |
} | |
tableArtists[curArtistKey]['albumkeys'][curAlbumKey] = null; | |
tableAlbums[curAlbumKey]['artistkeys'][curArtistKey] = null; | |
curGenres = curItemObject['metadata']['genres']; | |
for (var iGenre = 0; iGenre < curGenres.length; iGenre++) { | |
curGenreKey = convertStringToHashkey(curGenres[iGenre]); | |
if (!(curGenreKey in tableGenres)) { | |
tableGenres[curGenreKey] = new Object(); | |
tableGenres[curGenreKey]['artistkeys'] = new Object(); | |
tableGenres[curGenreKey]['metadata'] = new Object(); | |
tableGenres[curGenreKey]['metadata']['name'] = curGenres[iGenre]; | |
} | |
tableGenres[curGenreKey]['artistkeys'][curArtistKey] = null; | |
tableArtists[curArtistKey]['genrekeys'][curGenreKey] = null; | |
} | |
} | |
} | |
} | |
return objReturn; | |
} | |
function convertStringToHashkey (input) { | |
return libBase64Url.escape(libCrypto.createHash('sha256').update(input, 'utf8').digest('base64')); | |
} | |
function randomInt (low, high) { | |
return Math.floor(Math.random() * (high - low) + low); | |
} | |
function randomValueBase64 (len) { | |
return libCrypto.randomBytes(Math.ceil(len * 3 / 4)) | |
.toString('base64') // convert to base64 format | |
.slice(0, len) // return required number of characters | |
.replace(/\+/g, '0') // replace '+' with '0' | |
.replace(/\//g, '0'); // replace '/' with '0' | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment