Skip to content

Commit f9dcfa3

Browse files
committed
feat(benchpress): add a file reporter
1 parent 146d731 commit f9dcfa3

File tree

10 files changed

+217
-2
lines changed

10 files changed

+217
-2
lines changed

modules/angular2/src/facade/lang.dart

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,13 @@ class DateWrapper {
210210
static DateTime fromMillis(int ms) {
211211
return new DateTime.fromMillisecondsSinceEpoch(ms);
212212
}
213+
static int toMillis(DateTime date) {
214+
return date.millisecondsSinceEpoch;
215+
}
213216
static DateTime now() {
214217
return new DateTime.now();
215218
}
219+
static toJson(DateTime date) {
220+
return date.toUtc().toIso8601String();
221+
}
216222
}

modules/angular2/src/facade/lang.es6

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,13 @@ export class DateWrapper {
275275
static fromMillis(ms) {
276276
return new Date(ms);
277277
}
278+
static toMillis(date:Date) {
279+
return date.getTime();
280+
}
278281
static now() {
279282
return new Date();
280283
}
284+
static toJson(date) {
285+
return date.toJSON();
286+
}
281287
}

modules/benchpress/benchpress.es6

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,24 @@
1+
import { bind } from 'angular2/di';
2+
import { JsonFileReporter } from './common';
3+
14
export * from './common';
25
export { SeleniumWebDriverAdapter } from './src/webdriver/selenium_webdriver_adapter';
6+
7+
var fs = require('fs');
8+
9+
// Note: Can't do the `require` call in a facade as it can't be loaded into the browser!
10+
JsonFileReporter.BINDINGS.push(
11+
bind(JsonFileReporter.WRITE_FILE).toValue(writeFile)
12+
);
13+
14+
function writeFile(filename, content) {
15+
return new Promise(function(resolve, reject) {
16+
fs.writeFile(filename, content, (error) => {
17+
if (error) {
18+
reject(error);
19+
} else {
20+
resolve();
21+
}
22+
});
23+
})
24+
}

modules/benchpress/common.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ export { WebDriverAdapter } from './src/web_driver_adapter';
77
export { SizeValidator } from './src/validator/size_validator';
88
export { RegressionSlopeValidator } from './src/validator/regression_slope_validator';
99
export { ConsoleReporter } from './src/reporter/console_reporter';
10+
export { JsonFileReporter } from './src/reporter/json_file_reporter';
1011
export { SampleDescription } from './src/sample_description';
1112
export { PerflogMetric } from './src/metric/perflog_metric';
1213
export { ChromeDriverExtension } from './src/webdriver/chrome_driver_extension';

modules/benchpress/src/measure_values.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Date } from 'angular2/src/facade/lang';
1+
import { Date, DateWrapper } from 'angular2/src/facade/lang';
22
import { StringMap } from 'angular2/src/facade/collection';
33

44
export class MeasureValues {
@@ -11,4 +11,12 @@ export class MeasureValues {
1111
this.runIndex = runIndex;
1212
this.values = values;
1313
}
14+
15+
toJson() {
16+
return {
17+
'timeStamp': DateWrapper.toJson(this.timeStamp),
18+
'runIndex': this.runIndex,
19+
'values': this.values
20+
};
21+
}
1422
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import { DateWrapper, isPresent, isBlank, Json } from 'angular2/src/facade/lang';
2+
import { List } from 'angular2/src/facade/collection';
3+
import { Promise, PromiseWrapper } from 'angular2/src/facade/async';
4+
5+
import { bind, OpaqueToken } from 'angular2/di';
6+
7+
import { Reporter } from '../reporter';
8+
import { SampleDescription } from '../sample_description';
9+
import { MeasureValues } from '../measure_values';
10+
11+
/**
12+
* A reporter that writes results into a json file.
13+
* TODO(tbosch): right now we bind the `writeFile` method
14+
* in benchpres/benchpress.es6. This does not work for Dart,
15+
* find another way...
16+
*/
17+
export class JsonFileReporter extends Reporter {
18+
// TODO(tbosch): use static values when our transpiler supports them
19+
static get WRITE_FILE() { return _WRITE_FILE; }
20+
// TODO(tbosch): use static values when our transpiler supports them
21+
static get PATH() { return _PATH; }
22+
static get BINDINGS() { return _BINDINGS; }
23+
24+
_writeFile:Function;
25+
_path:string;
26+
_description:SampleDescription;
27+
28+
constructor(sampleDescription, path, writeFile) {
29+
super();
30+
this._description = sampleDescription;
31+
this._path = path;
32+
this._writeFile = writeFile;
33+
}
34+
35+
reportMeasureValues(measureValues:MeasureValues):Promise {
36+
return PromiseWrapper.resolve(null);
37+
}
38+
39+
reportSample(completeSample:List<MeasureValues>, validSample:List<MeasureValues>):Promise {
40+
var content = Json.stringify({
41+
'description': this._description,
42+
'completeSample': completeSample,
43+
'validSample': validSample
44+
});
45+
var filePath = `${this._path}/${this._description.id}_${DateWrapper.toMillis(DateWrapper.now())}.json`;
46+
return this._writeFile(filePath, content);
47+
}
48+
}
49+
50+
var _WRITE_FILE = new OpaqueToken('JsonFileReporter.writeFile');
51+
var _PATH = new OpaqueToken('JsonFileReporter.path');
52+
var _BINDINGS = [
53+
bind(JsonFileReporter).toFactory(
54+
(sampleDescription, path, writeFile) => new JsonFileReporter(sampleDescription, path, writeFile),
55+
[SampleDescription, _PATH, _WRITE_FILE]
56+
),
57+
bind(_PATH).toValue('.')
58+
];

modules/benchpress/src/sample_description.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,14 @@ export class SampleDescription {
2323
StringMapWrapper.forEach(description, (value, prop) => this.description[prop] = value );
2424
});
2525
}
26+
27+
toJson() {
28+
return {
29+
'id': this.id,
30+
'description': this.description,
31+
'metrics': this.metrics
32+
};
33+
}
2634
}
2735

2836
var _BINDINGS = [
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
import {describe, ddescribe, it, iit, xit, expect, beforeEach, afterEach} from 'angular2/test_lib';
2+
3+
import { DateWrapper, Json, RegExpWrapper, isPresent } from 'angular2/src/facade/lang';
4+
import { PromiseWrapper } from 'angular2/src/facade/async';
5+
6+
import {
7+
bind, Injector,
8+
SampleDescription,
9+
MeasureValues
10+
} from 'benchpress/common';
11+
12+
13+
import { JsonFileReporter } from 'benchpress/src/reporter/json_file_reporter';
14+
15+
export function main() {
16+
describe('file reporter', () => {
17+
var loggedFile;
18+
19+
function createReporter({sampleId, descriptions, metrics, path}) {
20+
var bindings = [
21+
JsonFileReporter.BINDINGS,
22+
bind(SampleDescription).toValue(new SampleDescription(sampleId, descriptions, metrics)),
23+
bind(JsonFileReporter.PATH).toValue(path),
24+
bind(JsonFileReporter.WRITE_FILE).toValue((filename, content) => {
25+
loggedFile = {
26+
'filename': filename,
27+
'content': content
28+
};
29+
return PromiseWrapper.resolve(null);
30+
})
31+
];
32+
return new Injector(bindings).get(JsonFileReporter);
33+
}
34+
35+
it('should write all data into a file', (done) => {
36+
createReporter({
37+
sampleId: 'someId',
38+
descriptions: [{ 'a': 2 }],
39+
path: 'somePath',
40+
metrics: {
41+
'script': 'script time'
42+
}
43+
}).reportSample([
44+
mv(0, 0, { 'a': 3, 'b': 6})
45+
], [mv(0, 0, {
46+
'a': 3, 'b': 6
47+
}), mv(1, 1, {
48+
'a': 5, 'b': 9
49+
})]);
50+
var regExp = RegExpWrapper.create('somePath/someId_\\d+\\.json');
51+
expect(isPresent(RegExpWrapper.firstMatch(regExp, loggedFile['filename']))).toBe(true);
52+
var parsedContent = Json.parse(loggedFile['content']);
53+
expect(parsedContent).toEqual({
54+
"description": {
55+
"id": "someId",
56+
"description": {
57+
"a": 2
58+
},
59+
"metrics": {"script": "script time"}
60+
},
61+
"completeSample": [{
62+
"timeStamp": "1970-01-01T00:00:00.000Z",
63+
"runIndex": 0,
64+
"values": {
65+
"a": 3,
66+
"b": 6
67+
}
68+
}],
69+
"validSample": [
70+
{
71+
"timeStamp": "1970-01-01T00:00:00.000Z",
72+
"runIndex": 0,
73+
"values": {
74+
"a": 3,
75+
"b": 6
76+
}
77+
},
78+
{
79+
"timeStamp": "1970-01-01T00:00:00.001Z",
80+
"runIndex": 1,
81+
"values": {
82+
"a": 5,
83+
"b": 9
84+
}
85+
}
86+
]
87+
});
88+
done();
89+
});
90+
91+
});
92+
}
93+
94+
function mv(runIndex, time, values) {
95+
return new MeasureValues(runIndex, DateWrapper.fromMillis(time), values);
96+
}

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
"dgeni": "^0.4.1",
4141
"dgeni-packages": "^0.10.10",
4242
"event-stream": "^3.1.5",
43+
"fs-extra": "^0.16.4",
4344
"glob": "^4.0.6",
4445
"gulp": "^3.8.8",
4546
"gulp-changed": "^1.0.0",

protractor-shared.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// load traceur runtime as our tests are written in es6
22
require('traceur/bin/traceur-runtime.js');
3+
var fs = require('fs-extra');
34

45
var argv = require('yargs')
56
.usage('Angular e2e/perf test options.')
@@ -208,13 +209,21 @@ exports.createBenchpressRunner = function(options) {
208209
if (process.env.GIT_SHA) {
209210
runId = process.env.GIT_SHA + ' ' + runId;
210211
}
212+
var resultsFolder = './dist/benchmark_results';
213+
fs.ensureDirSync(resultsFolder);
211214
var bindings = [
212215
benchpress.SeleniumWebDriverAdapter.PROTRACTOR_BINDINGS,
213216
benchpress.bind(benchpress.Options.FORCE_GC).toValue(argv['force-gc']),
214217
benchpress.bind(benchpress.Options.DEFAULT_DESCRIPTION).toValue({
215218
'lang': options.lang,
216219
'runId': runId
217-
})
220+
}),
221+
benchpress.MultiReporter.createBindings([
222+
benchpress.ConsoleReporter,
223+
benchpress.JsonFileReporter
224+
]),
225+
benchpress.JsonFileReporter.BINDINGS,
226+
benchpress.bind(benchpress.JsonFileReporter.PATH).toValue(resultsFolder)
218227
];
219228
if (argv['benchmark']) {
220229
bindings.push(benchpress.Validator.bindTo(benchpress.RegressionSlopeValidator));

0 commit comments

Comments
 (0)