feat(benchpress): add a file reporter
This commit is contained in:
parent
146d731e73
commit
f9dcfa3ba5
|
@ -210,7 +210,13 @@ class DateWrapper {
|
||||||
static DateTime fromMillis(int ms) {
|
static DateTime fromMillis(int ms) {
|
||||||
return new DateTime.fromMillisecondsSinceEpoch(ms);
|
return new DateTime.fromMillisecondsSinceEpoch(ms);
|
||||||
}
|
}
|
||||||
|
static int toMillis(DateTime date) {
|
||||||
|
return date.millisecondsSinceEpoch;
|
||||||
|
}
|
||||||
static DateTime now() {
|
static DateTime now() {
|
||||||
return new DateTime.now();
|
return new DateTime.now();
|
||||||
}
|
}
|
||||||
|
static toJson(DateTime date) {
|
||||||
|
return date.toUtc().toIso8601String();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -275,7 +275,13 @@ export class DateWrapper {
|
||||||
static fromMillis(ms) {
|
static fromMillis(ms) {
|
||||||
return new Date(ms);
|
return new Date(ms);
|
||||||
}
|
}
|
||||||
|
static toMillis(date:Date) {
|
||||||
|
return date.getTime();
|
||||||
|
}
|
||||||
static now() {
|
static now() {
|
||||||
return new Date();
|
return new Date();
|
||||||
}
|
}
|
||||||
|
static toJson(date) {
|
||||||
|
return date.toJSON();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,2 +1,24 @@
|
||||||
|
import { bind } from 'angular2/di';
|
||||||
|
import { JsonFileReporter } from './common';
|
||||||
|
|
||||||
export * from './common';
|
export * from './common';
|
||||||
export { SeleniumWebDriverAdapter } from './src/webdriver/selenium_webdriver_adapter';
|
export { SeleniumWebDriverAdapter } from './src/webdriver/selenium_webdriver_adapter';
|
||||||
|
|
||||||
|
var fs = require('fs');
|
||||||
|
|
||||||
|
// Note: Can't do the `require` call in a facade as it can't be loaded into the browser!
|
||||||
|
JsonFileReporter.BINDINGS.push(
|
||||||
|
bind(JsonFileReporter.WRITE_FILE).toValue(writeFile)
|
||||||
|
);
|
||||||
|
|
||||||
|
function writeFile(filename, content) {
|
||||||
|
return new Promise(function(resolve, reject) {
|
||||||
|
fs.writeFile(filename, content, (error) => {
|
||||||
|
if (error) {
|
||||||
|
reject(error);
|
||||||
|
} else {
|
||||||
|
resolve();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ export { WebDriverAdapter } from './src/web_driver_adapter';
|
||||||
export { SizeValidator } from './src/validator/size_validator';
|
export { SizeValidator } from './src/validator/size_validator';
|
||||||
export { RegressionSlopeValidator } from './src/validator/regression_slope_validator';
|
export { RegressionSlopeValidator } from './src/validator/regression_slope_validator';
|
||||||
export { ConsoleReporter } from './src/reporter/console_reporter';
|
export { ConsoleReporter } from './src/reporter/console_reporter';
|
||||||
|
export { JsonFileReporter } from './src/reporter/json_file_reporter';
|
||||||
export { SampleDescription } from './src/sample_description';
|
export { SampleDescription } from './src/sample_description';
|
||||||
export { PerflogMetric } from './src/metric/perflog_metric';
|
export { PerflogMetric } from './src/metric/perflog_metric';
|
||||||
export { ChromeDriverExtension } from './src/webdriver/chrome_driver_extension';
|
export { ChromeDriverExtension } from './src/webdriver/chrome_driver_extension';
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { Date } from 'angular2/src/facade/lang';
|
import { Date, DateWrapper } from 'angular2/src/facade/lang';
|
||||||
import { StringMap } from 'angular2/src/facade/collection';
|
import { StringMap } from 'angular2/src/facade/collection';
|
||||||
|
|
||||||
export class MeasureValues {
|
export class MeasureValues {
|
||||||
|
@ -11,4 +11,12 @@ export class MeasureValues {
|
||||||
this.runIndex = runIndex;
|
this.runIndex = runIndex;
|
||||||
this.values = values;
|
this.values = values;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
toJson() {
|
||||||
|
return {
|
||||||
|
'timeStamp': DateWrapper.toJson(this.timeStamp),
|
||||||
|
'runIndex': this.runIndex,
|
||||||
|
'values': this.values
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
import { DateWrapper, isPresent, isBlank, Json } from 'angular2/src/facade/lang';
|
||||||
|
import { List } from 'angular2/src/facade/collection';
|
||||||
|
import { Promise, PromiseWrapper } from 'angular2/src/facade/async';
|
||||||
|
|
||||||
|
import { bind, OpaqueToken } from 'angular2/di';
|
||||||
|
|
||||||
|
import { Reporter } from '../reporter';
|
||||||
|
import { SampleDescription } from '../sample_description';
|
||||||
|
import { MeasureValues } from '../measure_values';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A reporter that writes results into a json file.
|
||||||
|
* TODO(tbosch): right now we bind the `writeFile` method
|
||||||
|
* in benchpres/benchpress.es6. This does not work for Dart,
|
||||||
|
* find another way...
|
||||||
|
*/
|
||||||
|
export class JsonFileReporter extends Reporter {
|
||||||
|
// TODO(tbosch): use static values when our transpiler supports them
|
||||||
|
static get WRITE_FILE() { return _WRITE_FILE; }
|
||||||
|
// TODO(tbosch): use static values when our transpiler supports them
|
||||||
|
static get PATH() { return _PATH; }
|
||||||
|
static get BINDINGS() { return _BINDINGS; }
|
||||||
|
|
||||||
|
_writeFile:Function;
|
||||||
|
_path:string;
|
||||||
|
_description:SampleDescription;
|
||||||
|
|
||||||
|
constructor(sampleDescription, path, writeFile) {
|
||||||
|
super();
|
||||||
|
this._description = sampleDescription;
|
||||||
|
this._path = path;
|
||||||
|
this._writeFile = writeFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
reportMeasureValues(measureValues:MeasureValues):Promise {
|
||||||
|
return PromiseWrapper.resolve(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
reportSample(completeSample:List<MeasureValues>, validSample:List<MeasureValues>):Promise {
|
||||||
|
var content = Json.stringify({
|
||||||
|
'description': this._description,
|
||||||
|
'completeSample': completeSample,
|
||||||
|
'validSample': validSample
|
||||||
|
});
|
||||||
|
var filePath = `${this._path}/${this._description.id}_${DateWrapper.toMillis(DateWrapper.now())}.json`;
|
||||||
|
return this._writeFile(filePath, content);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var _WRITE_FILE = new OpaqueToken('JsonFileReporter.writeFile');
|
||||||
|
var _PATH = new OpaqueToken('JsonFileReporter.path');
|
||||||
|
var _BINDINGS = [
|
||||||
|
bind(JsonFileReporter).toFactory(
|
||||||
|
(sampleDescription, path, writeFile) => new JsonFileReporter(sampleDescription, path, writeFile),
|
||||||
|
[SampleDescription, _PATH, _WRITE_FILE]
|
||||||
|
),
|
||||||
|
bind(_PATH).toValue('.')
|
||||||
|
];
|
|
@ -23,6 +23,14 @@ export class SampleDescription {
|
||||||
StringMapWrapper.forEach(description, (value, prop) => this.description[prop] = value );
|
StringMapWrapper.forEach(description, (value, prop) => this.description[prop] = value );
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
toJson() {
|
||||||
|
return {
|
||||||
|
'id': this.id,
|
||||||
|
'description': this.description,
|
||||||
|
'metrics': this.metrics
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var _BINDINGS = [
|
var _BINDINGS = [
|
||||||
|
|
|
@ -0,0 +1,96 @@
|
||||||
|
import {describe, ddescribe, it, iit, xit, expect, beforeEach, afterEach} from 'angular2/test_lib';
|
||||||
|
|
||||||
|
import { DateWrapper, Json, RegExpWrapper, isPresent } from 'angular2/src/facade/lang';
|
||||||
|
import { PromiseWrapper } from 'angular2/src/facade/async';
|
||||||
|
|
||||||
|
import {
|
||||||
|
bind, Injector,
|
||||||
|
SampleDescription,
|
||||||
|
MeasureValues
|
||||||
|
} from 'benchpress/common';
|
||||||
|
|
||||||
|
|
||||||
|
import { JsonFileReporter } from 'benchpress/src/reporter/json_file_reporter';
|
||||||
|
|
||||||
|
export function main() {
|
||||||
|
describe('file reporter', () => {
|
||||||
|
var loggedFile;
|
||||||
|
|
||||||
|
function createReporter({sampleId, descriptions, metrics, path}) {
|
||||||
|
var bindings = [
|
||||||
|
JsonFileReporter.BINDINGS,
|
||||||
|
bind(SampleDescription).toValue(new SampleDescription(sampleId, descriptions, metrics)),
|
||||||
|
bind(JsonFileReporter.PATH).toValue(path),
|
||||||
|
bind(JsonFileReporter.WRITE_FILE).toValue((filename, content) => {
|
||||||
|
loggedFile = {
|
||||||
|
'filename': filename,
|
||||||
|
'content': content
|
||||||
|
};
|
||||||
|
return PromiseWrapper.resolve(null);
|
||||||
|
})
|
||||||
|
];
|
||||||
|
return new Injector(bindings).get(JsonFileReporter);
|
||||||
|
}
|
||||||
|
|
||||||
|
it('should write all data into a file', (done) => {
|
||||||
|
createReporter({
|
||||||
|
sampleId: 'someId',
|
||||||
|
descriptions: [{ 'a': 2 }],
|
||||||
|
path: 'somePath',
|
||||||
|
metrics: {
|
||||||
|
'script': 'script time'
|
||||||
|
}
|
||||||
|
}).reportSample([
|
||||||
|
mv(0, 0, { 'a': 3, 'b': 6})
|
||||||
|
], [mv(0, 0, {
|
||||||
|
'a': 3, 'b': 6
|
||||||
|
}), mv(1, 1, {
|
||||||
|
'a': 5, 'b': 9
|
||||||
|
})]);
|
||||||
|
var regExp = RegExpWrapper.create('somePath/someId_\\d+\\.json');
|
||||||
|
expect(isPresent(RegExpWrapper.firstMatch(regExp, loggedFile['filename']))).toBe(true);
|
||||||
|
var parsedContent = Json.parse(loggedFile['content']);
|
||||||
|
expect(parsedContent).toEqual({
|
||||||
|
"description": {
|
||||||
|
"id": "someId",
|
||||||
|
"description": {
|
||||||
|
"a": 2
|
||||||
|
},
|
||||||
|
"metrics": {"script": "script time"}
|
||||||
|
},
|
||||||
|
"completeSample": [{
|
||||||
|
"timeStamp": "1970-01-01T00:00:00.000Z",
|
||||||
|
"runIndex": 0,
|
||||||
|
"values": {
|
||||||
|
"a": 3,
|
||||||
|
"b": 6
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
"validSample": [
|
||||||
|
{
|
||||||
|
"timeStamp": "1970-01-01T00:00:00.000Z",
|
||||||
|
"runIndex": 0,
|
||||||
|
"values": {
|
||||||
|
"a": 3,
|
||||||
|
"b": 6
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timeStamp": "1970-01-01T00:00:00.001Z",
|
||||||
|
"runIndex": 1,
|
||||||
|
"values": {
|
||||||
|
"a": 5,
|
||||||
|
"b": 9
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function mv(runIndex, time, values) {
|
||||||
|
return new MeasureValues(runIndex, DateWrapper.fromMillis(time), values);
|
||||||
|
}
|
|
@ -40,6 +40,7 @@
|
||||||
"dgeni": "^0.4.1",
|
"dgeni": "^0.4.1",
|
||||||
"dgeni-packages": "^0.10.10",
|
"dgeni-packages": "^0.10.10",
|
||||||
"event-stream": "^3.1.5",
|
"event-stream": "^3.1.5",
|
||||||
|
"fs-extra": "^0.16.4",
|
||||||
"glob": "^4.0.6",
|
"glob": "^4.0.6",
|
||||||
"gulp": "^3.8.8",
|
"gulp": "^3.8.8",
|
||||||
"gulp-changed": "^1.0.0",
|
"gulp-changed": "^1.0.0",
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
// load traceur runtime as our tests are written in es6
|
// load traceur runtime as our tests are written in es6
|
||||||
require('traceur/bin/traceur-runtime.js');
|
require('traceur/bin/traceur-runtime.js');
|
||||||
|
var fs = require('fs-extra');
|
||||||
|
|
||||||
var argv = require('yargs')
|
var argv = require('yargs')
|
||||||
.usage('Angular e2e/perf test options.')
|
.usage('Angular e2e/perf test options.')
|
||||||
|
@ -208,13 +209,21 @@ exports.createBenchpressRunner = function(options) {
|
||||||
if (process.env.GIT_SHA) {
|
if (process.env.GIT_SHA) {
|
||||||
runId = process.env.GIT_SHA + ' ' + runId;
|
runId = process.env.GIT_SHA + ' ' + runId;
|
||||||
}
|
}
|
||||||
|
var resultsFolder = './dist/benchmark_results';
|
||||||
|
fs.ensureDirSync(resultsFolder);
|
||||||
var bindings = [
|
var bindings = [
|
||||||
benchpress.SeleniumWebDriverAdapter.PROTRACTOR_BINDINGS,
|
benchpress.SeleniumWebDriverAdapter.PROTRACTOR_BINDINGS,
|
||||||
benchpress.bind(benchpress.Options.FORCE_GC).toValue(argv['force-gc']),
|
benchpress.bind(benchpress.Options.FORCE_GC).toValue(argv['force-gc']),
|
||||||
benchpress.bind(benchpress.Options.DEFAULT_DESCRIPTION).toValue({
|
benchpress.bind(benchpress.Options.DEFAULT_DESCRIPTION).toValue({
|
||||||
'lang': options.lang,
|
'lang': options.lang,
|
||||||
'runId': runId
|
'runId': runId
|
||||||
})
|
}),
|
||||||
|
benchpress.MultiReporter.createBindings([
|
||||||
|
benchpress.ConsoleReporter,
|
||||||
|
benchpress.JsonFileReporter
|
||||||
|
]),
|
||||||
|
benchpress.JsonFileReporter.BINDINGS,
|
||||||
|
benchpress.bind(benchpress.JsonFileReporter.PATH).toValue(resultsFolder)
|
||||||
];
|
];
|
||||||
if (argv['benchmark']) {
|
if (argv['benchmark']) {
|
||||||
bindings.push(benchpress.Validator.bindTo(benchpress.RegressionSlopeValidator));
|
bindings.push(benchpress.Validator.bindTo(benchpress.RegressionSlopeValidator));
|
||||||
|
|
Loading…
Reference in New Issue