Skip to content
This repository has been archived by the owner on Nov 3, 2021. It is now read-only.

Commit

Permalink
Merge pull request #15172 from hfiguiere/bug917717
Browse files Browse the repository at this point in the history
Bug 917717 - Collect the memory usage for the process after running the start test. r=vivien
  • Loading branch information
hfiguiere committed Jan 13, 2014
2 parents c53bace + d0ed4dc commit 1fc1be2
Show file tree
Hide file tree
Showing 8 changed files with 210 additions and 4 deletions.
1 change: 1 addition & 0 deletions package.json
Expand Up @@ -7,6 +7,7 @@
"devDependencies": {
"debug": "*",
"empty-port": "~0.0.1",
"exec-sync": "*",
"jshint": "2.4.1",
"mail-fakeservers": "~0.0.11",
"marionette-apps": "~0.3.3",
Expand Down
10 changes: 9 additions & 1 deletion tests/performance/app.js
Expand Up @@ -31,6 +31,9 @@ PerfTestApp.prototype = {

selectors: {},

/** the Webapp instance. */
instance: null,

PERFORMANCE_ATOM: 'window.wrappedJSObject.PerformanceHelperAtom',

defaultCallback: function() {
Expand All @@ -40,7 +43,12 @@ PerfTestApp.prototype = {
* Launches app, switches to frame, and waits for it to be loaded.
*/
launch: function() {
this.client.apps.launch(this.origin, this.entryPoint);
var self = this;
this.client.apps.launch(this.origin, this.entryPoint, function(err, app) {
if (app) {
self.instance = app;
}
});
this.client.apps.switchToApp(this.origin);
this.client.helper.waitForElement('body');
},
Expand Down
14 changes: 14 additions & 0 deletions tests/performance/getappname.js
@@ -0,0 +1,14 @@
var fs = require('fs');

function GetAppName(app)
{
var client = app.client.scope({ context: 'chrome' });
var appName = client.executeScript(
'var manifestUrl = \'' +
app.instance.manifestURL + '\';\n' +
fs.readFileSync('./tests/performance/getappname_atom.js')
);
return appName;
}

module.exports = GetAppName;
6 changes: 6 additions & 0 deletions tests/performance/getappname_atom.js
@@ -0,0 +1,6 @@

return (function () {
Cu.import('resource://gre/modules/Webapps.jsm');
let app = DOMApplicationRegistry.getAppByManifestURL(manifestUrl);
return app ? app.name : null;
})();
117 changes: 117 additions & 0 deletions tests/performance/meminfo.js
@@ -0,0 +1,117 @@
'use strict';

/*
* Run b2g-info in the device *synchronously*.
*
* This is because all the tests are synchronous.
*/

var fs = require('fs'),
execSync = require('exec-sync')

function b2ginfo() {
var adb = execSync('adb shell b2g-info', true);
return adb;
}

function isNotEmpty(str) {
return str != '';
}

var MemInfo = {

_meminfo: [],

/* keys for fields */
_keys: [],

_currentLineNumber: 0,
/* state in parser */
_state: 'none', // 'ps', 'done'

_parsePsLine: function MemInfo_parsePsLine(line, keys) {
var fields = line.split(' ').filter(isNotEmpty);
if (fields.length < keys.length) {
console.error('Not enough fields given the number of keys.');
return null;
}

var numKeys = keys.length;
var last = fields.length - 1;
var idx = last;
var ps = {};
while(Object.keys(ps).length < numKeys) {
ps[keys[numKeys - 1 - (last - idx)]] = fields[idx];
idx--;
}

// now fix the process name as we have some with spaces in it
// oh the joy of parsing text output.
if(idx >= 0) {
fields.splice(idx + 1, fields.length);
var s = '';
fields.forEach(function (e) {
s += (s.length ? ' ' : '') + e;
});
ps[keys[0]] = s + ' ' + ps[keys[0]];
}
return ps;
},

_processLine: function(line) {
this._currentLineNumber++;
if (this._state == 'done')
return;

if (this._currentLineNumber == 1)
return; // skip first line. XXX maybe parse it to know the units.

if (this._currentLineNumber == 2) {
this._keys = line.split(' ').filter(isNotEmpty);
this._state = 'ps';
return;
}

if (this._state == 'ps') {
if (line == '') {
// an empty line means we are done with ps.
// if we need more info change the state to something else.
this._state = 'done';
return;
}

var ps = this._parsePsLine(line, this._keys);
if(ps != null) {
this._meminfo.push(ps);
}
}
},

meminfo: function MemInfo_meminfo() {

var output = b2ginfo().stdout;

var i = 0;
while (i < output.length) {
// EOL is CRLF.
var j = output.indexOf('\r\n', i);
if (j == -1) {
j = output.length;
}
this._processLine(output.substr(i, j - i));
// skip 2 (CRLF)
i = j + 2;
}

return this._meminfo;
}

};

module.exports = MemInfo;

if(require.main === module) {
console.log('Tested MemInfo');
console.log(MemInfo.meminfo());
}

54 changes: 52 additions & 2 deletions tests/performance/performance_helper.js
@@ -1,6 +1,8 @@
'use strict';

var MarionetteHelper = requireGaia('/tests/js-marionette/helper.js');
var GetAppName = requireGaia('/tests/performance/getappname.js');
var MemInfo = requireGaia('/tests/performance/meminfo.js');

// Function to send results to the reporter that is OOP
// Basically writing to the mocha-json-proxy
Expand Down Expand Up @@ -86,10 +88,17 @@ function PerformanceHelper(opts) {
var mozPerfDurations = {};
mozPerfDurations[title] = values;
sendResults('mozPerfDuration', mozPerfDurations);
},

reportMemory: function(values, title) {
title = title || '';
var mozPerfMemory = {};
mozPerfMemory[title] = values;
sendResults('mozPerfMemory', mozPerfMemory);
}
});

PerformanceHelper.prototype = {
PerformanceHelper.prototype = {
reportRunDurations: function(runResults) {

var start = runResults.start || 0;
Expand Down Expand Up @@ -174,8 +183,49 @@ function PerformanceHelper(opts) {

waitForPerfEvent: function(callback) {
this.app.waitForPerfEvents(this.opts.lastEvent, callback);
},

/*
* Get the memory stats for the specified app
* as well as the main b2g.
* See bug 917717.
*/
getMemoryUsage: function(app) {
var appName = GetAppName(app);
var meminfo = MemInfo.meminfo();
var info = null;
var system = null;
meminfo.some(function(element) {
if(element.NAME == appName) {
info = element;
} else if(element.NAME == 'b2g') {
system = element;
}
return info && system;
});

if (!info) {
return null;
}
};

return {
app: {
name: info.NAME,
uss: parseFloat(info.USS),
pss: parseFloat(info.PSS),
rss: parseFloat(info.RSS),
vsize: parseFloat(info.VSIZE)
},
system: {
name: system.NAME,
uss: parseFloat(system.USS),
pss: parseFloat(system.PSS),
rss: parseFloat(system.RSS),
vsize: parseFloat(system.VSIZE)
}
};
}
};

module.exports = PerformanceHelper;

Expand Down
4 changes: 4 additions & 0 deletions tests/performance/startup_test.js
Expand Up @@ -41,8 +41,11 @@ marionette('startup test > ' + mozTestInfo.appPath + ' >', function() {

PerformanceHelper.registerLoadTimeListener(client);

var memStats = [];
performanceHelper.repeatWithDelay(function(app, next) {
app.launch();
var memUsage = performanceHelper.getMemoryUsage(app);
memStats.push(memUsage);
app.close();
});

Expand All @@ -61,6 +64,7 @@ marionette('startup test > ' + mozTestInfo.appPath + ' >', function() {
});

PerformanceHelper.reportDuration(results);
PerformanceHelper.reportMemory(memStats);

PerformanceHelper.unregisterLoadTimeListener(client);
});
Expand Down
8 changes: 7 additions & 1 deletion tests/reporters/jsonmozperf.js
Expand Up @@ -18,6 +18,7 @@ function JSONMozPerfReporter(runner) {
var failures = [];
var passes = [];
var mozPerfDurations;
var mozPerfMemory;

runner.on('test', function(test) {
mozPerfDurations = [];
Expand All @@ -27,6 +28,10 @@ function JSONMozPerfReporter(runner) {
mozPerfDurations = content;
});

runner.on('mozPerfMemory', function(content) {
mozPerfMemory = content;
});

runner.on('pass', function(test) {

if (mozPerfDurations === null) {
Expand All @@ -43,7 +48,8 @@ function JSONMozPerfReporter(runner) {
fullTitle: test.fullTitle() + ' ' + title,
duration: test.duration,
mozPerfDurations: mozPerfDurations[title],
mozPerfDurationsAverage: average(mozPerfDurations[title])
mozPerfDurationsAverage: average(mozPerfDurations[title]),
mozPerfMemory: mozPerfMemory[title],
});
}
});
Expand Down

0 comments on commit 1fc1be2

Please sign in to comment.