Skip to content

Instantly share code, notes, and snippets.

@ning-yu
Last active August 29, 2015 14:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ning-yu/e9763e5ee5d6ae4dacab to your computer and use it in GitHub Desktop.
Save ning-yu/e9763e5ee5d6ae4dacab to your computer and use it in GitHub Desktop.
Stress test for Volumio2 library
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