Skip to content

Commit

Permalink
Add scripts to run performance tests (#1015)
Browse files Browse the repository at this point in the history
  • Loading branch information
jcague authored Aug 29, 2017
1 parent adcf2f5 commit d940617
Show file tree
Hide file tree
Showing 9 changed files with 650 additions and 9 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,6 @@ erizo_controller/erizoAgent/erizo-*.log
.project
.cproject
spine/erizofc.js
spine/testResult.json
extras/basic_example/public/assets/
rtp_media_config.js
10 changes: 4 additions & 6 deletions spine/runSpineClients.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ const Spine = require('./Spine.js');

const getopt = new Getopt([
['s', 'stream-config=ARG', 'file containing the stream config JSON (default is spineClientsConfig.json)'],
['i', 'interval=ARG', 'interval time to show stats (default 10 seconds)'],
['t', 'total-intervals=ARG', 'total test intervals (default 10 intervals)'],
['t', 'interval=ARG', 'interval time to show stats (default 10 seconds)'],
['i', 'total-intervals=ARG', 'total test intervals (default 10 intervals)'],
['o', 'output=ARG', 'output file for the stat digest (default is testResult.json)'],
['h', 'help', 'display this help'],
]);
Expand All @@ -30,7 +30,7 @@ optionKeys.forEach((key) => {
case 'interval':
statsIntervalTime = value * 1000;
break;
case 'totalIntervals':
case 'total-intervals':
totalStatsIntervals = value;
break;
case 'output':
Expand Down Expand Up @@ -100,9 +100,7 @@ const gatherStatuses = () => {
};

const writeJsonToFile = (result) => {
fs.writeFile(statOutputFile, JSON.stringify(result), (err) => {
if (err) throw err;
});
fs.writeFileSync(statOutputFile, JSON.stringify(result));
process.exit(0);
};

Expand Down
3 changes: 3 additions & 0 deletions test/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"extends": "mocha/test"
}
183 changes: 183 additions & 0 deletions test/licode_default.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
var config = {}

/*********************************************************
COMMON CONFIGURATION
It's used by Nuve, ErizoController, ErizoAgent and ErizoJS
**********************************************************/
config.rabbit = {};
config.rabbit.host = 'localhost'; //default value: 'localhost'
config.rabbit.port = 5672; //default value: 5672
// Sets the AQMP heartbeat timeout to detect dead TCP Connections
config.rabbit.heartbeat = 8; //default value: 8 seconds, 0 to disable
config.logger = {};
config.logger.configFile = '../log4js_configuration.json'; //default value: "../log4js_configuration.json"

/*********************************************************
CLOUD PROVIDER CONFIGURATION
It's used by Nuve and ErizoController
**********************************************************/
config.cloudProvider = {};
config.cloudProvider.name = '';

/*********************************************************
NUVE CONFIGURATION
**********************************************************/
config.nuve = {};
config.nuve.dataBaseURL = "localhost/nuvedb"; // default value: 'localhost/nuvedb'
config.nuve.superserviceID = '_auto_generated_ID_'; // default value: ''
config.nuve.superserviceKey = '_auto_generated_KEY_'; // default value: ''
config.nuve.testErizoController = 'localhost:8080'; // default value: 'localhost:8080'
// Nuve Cloud Handler policies are in nuve/nuveAPI/ch_policies/ folder
config.nuve.cloudHandlerPolicy = 'default_policy.js'; // default value: 'default_policy.js'


/*********************************************************
ERIZO CONTROLLER CONFIGURATION
**********************************************************/
config.erizoController = {};

// Use undefined to run clients without Ice Servers
//
// Stun servers format
// {
// "url": url
// }
//
// Turn servers format
// {
// "username": username,
// "credential": password,
// "url": url
// }
config.erizoController.iceServers = [{'url': 'stun:stun.l.google.com:19302'}]; // default value: [{'url': 'stun:stun.l.google.com:19302'}]

// Default and max video bandwidth parameters to be used by clients
config.erizoController.defaultVideoBW = 300; //default value: 300
config.erizoController.maxVideoBW = 300; //default value: 300

// Public erizoController IP for websockets (useful when behind NATs)
// Use '' to automatically get IP from the interface
config.erizoController.publicIP = ''; //default value: ''
config.erizoController.networkinterface = ''; //default value: ''

// This configuration is used by the clients to reach erizoController
// Use '' to use the public IP address instead of a hostname
config.erizoController.hostname = ''; //default value: ''
config.erizoController.port = 8080; //default value: 8080
// Use true if clients communicate with erizoController over SSL
config.erizoController.ssl = true; //default value: false

// This configuration is used by erizoController server to listen for connections
// Use true if erizoController listens in HTTPS.
config.erizoController.listen_ssl = true; //default value: false
config.erizoController.listen_port = 8080; //default value: 8080

// Custom location for SSL certificates. Default located in /cert
//config.erizoController.ssl_key = '/full/path/to/ssl.key';
//config.erizoController.ssl_cert = '/full/path/to/ssl.crt';
//config.erizoController.sslCaCerts = ['/full/path/to/ca_cert1.crt', '/full/path/to/ca_cert2.crt'];

// Use the name of the inferface you want to bind to for websockets
// config.erizoController.networkInterface = 'eth1' // default value: undefined

config.erizoController.warning_n_rooms = 15; // default value: 15
config.erizoController.limit_n_rooms = 20; // default value: 20
config.erizoController.interval_time_keepAlive = 1000; // default value: 1000

// Roles to be used by services
config.erizoController.roles =
{"presenter": {"publish": true, "subscribe": true, "record": true, "stats": true, "controlhandlers": true},
"viewer": {"subscribe": true},
"viewerWithData": {"subscribe": true, "publish": {"audio": false, "video": false, "screen": false, "data": true}}}; // default value: {"presenter":{"publish": true, "subscribe":true, "record":true}, "viewer":{"subscribe":true}, "viewerWithData":{"subscribe":true, "publish":{"audio":false,"video":false,"screen":false,"data":true}}}

// If true, erizoController sends report to rabbitMQ queue "report_handler"
config.erizoController.report = {
session_events: false, // Session level events -- default value: false
connection_events: false, // Connection (ICE) level events -- default value: false
rtcp_stats: false // RTCP stats -- default value: false
};

// Subscriptions to rtcp_stats via AMQP
config.erizoController.reportSubscriptions = {
maxSubscriptions: 10, // per ErizoJS -- set 0 to disable subscriptions -- default 10
minInterval: 1, // in seconds -- default 1
maxTimeout: 60 // in seconds -- default 60
};

// If undefined, the path will be /tmp/
config.erizoController.recording_path = undefined; // default value: undefined

// Erizo Controller Cloud Handler policies are in erizo_controller/erizoController/ch_policies/ folder
config.erizoController.cloudHandlerPolicy = 'default_policy.js'; // default value: 'default_policy.js'

/*********************************************************
ERIZO AGENT CONFIGURATION
**********************************************************/
config.erizoAgent = {};

// Max processes that ErizoAgent can run
config.erizoAgent.maxProcesses = 1; // default value: 1
// Number of precesses that ErizoAgent runs when it starts. Always lower than or equals to maxProcesses.
config.erizoAgent.prerunProcesses = 1; // default value: 1

// Public erizoAgent IP for ICE candidates (useful when behind NATs)
// Use '' to automatically get IP from the interface
config.erizoAgent.publicIP = ''; //default value: ''
config.erizoAgent.networkinterface = ''; //default value: ''

// Use the name of the inferface you want to bind for ICE candidates
// config.erizoAgent.networkInterface = 'eth1' // default value: undefined

//Use individual log files for each of the started erizoJS processes
//This files will be named erizo-ERIZO_ID_HASH.log
config.erizoAgent.useIndividualLogFiles = false;

// Custom log directory for agent instance log files.
// If useIndividualLogFiles is enabled, files will go here
// Default is [licode_path]/erizo_controller/erizoAgent
// config.erizoAgent.instanceLogDir = '/path/to/dir';


/*********************************************************
ERIZO JS CONFIGURATION
**********************************************************/
config.erizo = {};

//Erizo Logs are piped through erizoAgent by default
//you can control log levels in [licode_path]/erizo_controller/erizoAgent/log4cxx.properties

// Number of workers that will be used to handle WebRtcConnections
config.erizo.numWorkers = 24;

// Number of workers what will be used for IO (including ICE logic)
config.erizo.numIOWorkers = 1;

//STUN server IP address and port to be used by the server.
//if '' is used, the address is discovered locally
//Please note this is only needed if your server does not have a public IP
config.erizo.stunserver = ''; // default value: ''
config.erizo.stunport = 0; // default value: 0

//TURN server IP address and port to be used by the server.
//Please note this is not needed in most cases, setting TURN in erizoController for the clients
//is the recommended configuration
//if '' is used, no relay for the server is used
config.erizo.turnserver = ''; // default value: ''
config.erizo.turnport = 0; // default value: 0
config.erizo.turnusername = '';
config.erizo.turnpass = '';
config.erizo.networkinterface = ''; //default value: ''

//note, this won't work with all versions of libnice. With 0 all the available ports are used
config.erizo.minport = 0; // default value: 0
config.erizo.maxport = 0; // default value: 0

//Use of internal nICEr library instead of libNice.
config.erizo.useNicer = false; // default value: false

config.erizo.disabledHandlers = []; // there are no handlers disabled by default

/***** END *****/
// Following lines are always needed.
var module = module || {};
module.exports = config;
8 changes: 5 additions & 3 deletions test/package.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
{
"name" : "erizo-tests",
"name": "erizo-tests",
"version": "0.0.1",
"private": true,
"dependencies": {
"node-getopt":"0.2.3",
"chai":"3.5.0"
"aws-sdk": "^2.102.0",
"chai": "3.5.0",
"node-getopt": "0.2.3",
"node-ssh": "^4.2.3"
}
}
76 changes: 76 additions & 0 deletions test/perf-tests.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
const InstanceFactory = require('./utils/remote-spine').Factory;

const BASIC_TEST = {
'basicExampleUrl': 'https://localhost/',
'publishConfig' : {
'video': { 'synthetic': {
'audioBitrate': 30000,
'minVideoBitrate': 10000,
'maxVideoBitrate': 300000}},
'audio':true,
'data':true
},
'subscribeConfig' : {
'video': true,
'audio': true,
'data': true
},
'numPublishers': 1,
'numSubscribers': 1,
'publishersAreSubscribers': false,
'connectionCreationInterval': 500,
'stats': [
'packetsLost',
'bitrateCalculated'
]
};

describe('Licode Performance', function() {
this.timeout(60 * 60 * 1000);
let factory;

getLicodeInstance = () => factory.instances[0];
getSpineInstance = () => factory.instances[1];

before(() => {
let settings = {
numberOfInstances: 2,
imageId: 'ami-2ff3e756',
username: 'ec2-user',
instanceType: process.env.PERF_INSTANCE_TYPE || 't1.micro',
keyName: process.env.PERF_KEY_NAME || 'staging',
privateKey: process.env.PERF_PRIVATE_KEY || '~/.ssh/id_rsa',
dockerTag: process.env.PERF_DOCKER_TAG || 'develop',
region: process.env.PERF_REGION || 'us-west-2',
securityGroup: process.env.PERF_SECURITY_GROUP || 'Licode'
};
factory = new InstanceFactory(settings);
return factory.run();
});

beforeEach(() => {
return getLicodeInstance().runLicode();
});

it('Test setup', (done) => {
console.log('Starting test');
console.log('Licode: ssh -i', process.env.PERF_PRIVATE_KEY, 'ec2-user@' + getLicodeInstance().host);
console.log('Spine: ssh -i', process.env.PERF_PRIVATE_KEY, 'ec2-user@' + getSpineInstance().host);
const config = Object.assign({}, BASIC_TEST);
config.basicExampleUrl = 'https://' + getLicodeInstance().host + ':3004';
getSpineInstance().runTest(config).then(() => {
console.log(this.result);
done();
}).catch((reason) => {
done(new Error(reason));
});
});

afterEach(() => {
return getLicodeInstance().stopLicode();
});

after(() => {
return factory.terminate();
});
});
Loading

0 comments on commit d940617

Please sign in to comment.