Skip to content
This repository was archived by the owner on Feb 22, 2018. It is now read-only.

Commit b0a2781

Browse files
committed
chore(reporter): record lexer benchmark results
This initial version sends benchmark metrics to the backend server. Visit https://ng-dash.appspot.com/commit/fb2aa60a584dd4b2bbb3d30e8fcd4c588f8669ed or https://ng-dash.appspot.com/all to see an example. (github: https://github.com/chirayuk/ng-dash) In this version, only Dart code run from the command line is able to record such reports. The code in benchmark/_reporter.dart handles sending the data to the server. A future version will mode this code into a locally running proxy server enabling browser based Dart code to send such reports while still including the information from the build environment. Reading data from the report server does not require any auth. See a simple example at chirayuk/ng-dash@ex_01 Writing data requires authentication. Specifically, the REST server requires two cookies set: user_email and user_secret. (user_email does not have to be a valid e-mail just like AppEngine user e-mails.) Of these, user_secret is meant to be secret and should be safeguarded. For Travis, user_email is "travis-ci.org" and user_secret is encrypted in the .travis.yml. Refer http://docs.travis-ci.com/user/build-configuration/#Secure-environment-variables for details on how this is done. Closes #1159
1 parent d18e359 commit b0a2781

File tree

3 files changed

+208
-6
lines changed

3 files changed

+208
-6
lines changed

.travis.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ env:
4141
- BROWSER_PROVIDER_READY_FILE=/tmp/sauce-connect-ready
4242
- SAUCE_USERNAME=angular-ci
4343
- SAUCE_ACCESS_KEY=9b988f434ff8-fbca-8aa4-4ae3-35442987
44+
# Reporting benchmarks to ng-dash.appspot.com
45+
- NGDASH_BASE_URL=https://ng-dash.appspot.com
46+
- NGDASH_USER_EMAIL=travis-ci.org
47+
- secure: "n3KJsLLXEh1wlLRTF2wWvnDBAL+sOg+Mf/gc/Ub9/zCpXLDd1LP76hWBH/d7TCaC0oH5dnyD3ugV6PtJ7VEPRBZp72IbuNZzj8Ui8SisXVd0aos4u7s7X5NVwcxobhxd8Csoi5QPT31w8iT6qaC9VSXnYM3EEGqeppRqRBu6Hkg="
4448

4549
branches:
4650
except:

benchmark/_reporter.dart

Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
library _reporter;
2+
3+
import 'dart:io';
4+
import 'dart:convert' show UTF8, JSON;
5+
6+
7+
String getBaseUrl() {
8+
String ngDashBaseUrl = Platform.environment["NGDASH_BASE_URL"];
9+
if (ngDashBaseUrl == null || ngDashBaseUrl.isEmpty) {
10+
ngDashBaseUrl = "http://ng-dash.gae.localhost";
11+
}
12+
return ngDashBaseUrl;
13+
}
14+
15+
16+
class ResultData {
17+
final String name;
18+
final String description;
19+
final Map<String, dynamic> dimensions = {};
20+
final Map<String, dynamic> metrics = {};
21+
final List<ResultData> children = [];
22+
23+
ResultData(this.name, this.description);
24+
25+
ResultData newChild(String name, String description) {
26+
ResultData child = new ResultData(name, description);
27+
children.add(child);
28+
return child;
29+
}
30+
31+
toJson() => {
32+
"name": name,
33+
"description": description,
34+
"dimensions_json": JSON.encode(dimensions),
35+
"metrics_json": JSON.encode(metrics),
36+
"children": children.map((i) => i.toJson()).toList(),
37+
};
38+
}
39+
40+
41+
Map<String, String> getTravisDimension() {
42+
if (Platform.environment["TRAVIS"] != "true") {
43+
throw "getTravisDimension(): Not called on TRAVIS";
44+
}
45+
Map<String, String> result = {};
46+
// Ref: http://docs.travis-ci.com/user/ci-environment/
47+
for (String envVar in const [
48+
"TRAVIS_BRANCH", // The name of the branch currently being built.
49+
"TRAVIS_BUILD_ID", // The id of the current build that Travis CI uses internally.
50+
"TRAVIS_BUILD_NUMBER", // The number of the current build (for example, "4").
51+
"TRAVIS_COMMIT", // The commit that the current build is testing.
52+
"TRAVIS_COMMIT_RANGE", // The range of commits that were included in the push or pull request.
53+
"TRAVIS_JOB_ID", // The id of the current job that Travis CI uses internally.
54+
"TRAVIS_JOB_NUMBER", // The number of the current job (for example, "4.1").
55+
"TRAVIS_PULL_REQUEST", // The pull request number if the current job is a pull request, "false" if it's not a pull request.
56+
"TRAVIS_REPO_SLUG", // "owner_name/repo_name" (e.g. "travis-ci/travis-build").
57+
"TRAVIS_OS_NAME", // Name of the operating system built on. (e.g. linux or osx)
58+
"TRAVIS_TAG", // (optional) tag name for current build if relevant.
59+
]) {
60+
String value = Platform.environment[envVar];
61+
if (value != null && value.isNotEmpty) {
62+
result[envVar.substring("TRAVIS_".length).toLowerCase()] = value;
63+
}
64+
}
65+
return result;
66+
}
67+
68+
69+
String getOsType() {
70+
if (Platform.isMacOS) {
71+
return "OSX";
72+
} else if (Platform.isLinux) {
73+
return "Linux";
74+
} else if (Platform.isWindows) {
75+
return "Windows";
76+
} else if (Platform.Android) {
77+
return "Android";
78+
}
79+
}
80+
81+
82+
class Reporter {
83+
ResultData data = new ResultData("", "");
84+
final String baseUrl = getBaseUrl();
85+
String commitSha = "";
86+
String treeSha = "";
87+
String reportId = null;
88+
List<Cookie> cookies;
89+
90+
Reporter() {
91+
var dimensions = data.dimensions;
92+
dimensions["project"] = "AngularDart";
93+
dimensions["dart"] = {
94+
"full_version": Platform.version,
95+
"version": Platform.version.split(" ")[0],
96+
};
97+
dimensions["os"] = {
98+
"type": getOsType(),
99+
};
100+
if (Platform.environment["TRAVIS"] == "true") {
101+
dimensions["travis"] = getTravisDimension();
102+
commitSha = dimensions["travis"]["commit"];
103+
}
104+
105+
// Auth cookies
106+
var user_email = Platform.environment["NGDASH_USER_EMAIL"];
107+
var user_secret = Platform.environment["NGDASH_USER_SECRET"];
108+
if (user_email == null || user_email.isEmpty ||
109+
user_secret == null || user_secret.isEmpty) {
110+
throw "Please set NGDASH_USER_EMAIL and NGDASH_USER_SECRET credentials.";
111+
}
112+
cookies = [new Cookie("user_email", user_email),
113+
new Cookie("user_secret", user_secret)];
114+
115+
if (commitSha.isEmpty) {
116+
throw "Could not detect the commit SHA. (non-travis detection not implemented yet.)";
117+
}
118+
}
119+
120+
121+
// The following machinery is there just to serialize saving to the server.
122+
// If we're already in the process of saving the results, then just mark that
123+
// we need to save again. This is also particularly important because the
124+
// first time, we create a new report, and in all subsequent calls, we update
125+
// that same report using the report ID that was received when we created it.
126+
var _messageQueue = [];
127+
var _isQueueProcessing = true;
128+
129+
_sendNextMessage() {
130+
if (_messageQueue.isEmpty) {
131+
_isQueueProcessing = true;
132+
return;
133+
}
134+
135+
String requestData = JSON.encode(_messageQueue.removeAt(0));
136+
_isQueueProcessing = false;
137+
Function onRequest = (HttpClientRequest request) {
138+
request
139+
..headers.contentType = ContentType.JSON
140+
..cookies.addAll(cookies)
141+
..write(requestData);
142+
return request.close();
143+
};
144+
145+
if (reportId == null) {
146+
new HttpClient().postUrl(Uri.parse("${baseUrl}/api/run"))
147+
.then(onRequest)
148+
.then((HttpClientResponse response) {
149+
List<String> parts = [];
150+
response.transform(UTF8.decoder).listen(parts.add, onDone: () {
151+
// Extract reportId to use in future requests.
152+
reportId = JSON.decode(parts.join(""))["id"];
153+
_sendNextMessage();
154+
});
155+
});
156+
} else {
157+
new HttpClient().putUrl(Uri.parse("${baseUrl}/api/run/id=$reportId"))
158+
.then(onRequest)
159+
.then((HttpClientResponse response) {
160+
response.transform(UTF8.decoder).listen(null, onDone: _sendNextMessage);
161+
});
162+
}
163+
}
164+
165+
166+
void saveReport() {
167+
_messageQueue.add(this);
168+
if (_isQueueProcessing) {
169+
_sendNextMessage();
170+
}
171+
}
172+
173+
174+
toJson() => {
175+
"commit_sha": commitSha,
176+
"tree_sha": treeSha,
177+
"data": data.toJson(),
178+
};
179+
}

benchmark/lexer_perf.dart

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,39 @@
11
library lexer_perf;
22

33
import '_perf.dart';
4+
import '_reporter.dart';
45
import 'package:angular/core/parser/lexer.dart';
56

7+
8+
Reporter reporter = new Reporter();
9+
var lexerStats = reporter.data.newChild("lexer", "lexer benchmarks");
10+
11+
12+
report(name, fn) {
13+
var stats = lexerStats.newChild(name, "");
14+
var metrics = statMeasure(fn);
15+
stats.metrics["ops_per_sec"] = metrics.mean_ops_sec;
16+
stats.metrics["variance"] = metrics.variance;
17+
print('$name: => $metrics');
18+
reporter.saveReport();
19+
}
20+
21+
622
main() {
723
Lexer lexer = new Lexer();
8-
time('ident', () =>
24+
25+
report('ident', () =>
926
lexer.call('ctrl foo baz ctrl.foo ctrl.bar ctrl.baz'));
10-
time('ident-path', () =>
27+
report('ident-path', () =>
1128
lexer.call('a.b a.b.c a.b.c.d a.b.c.d.e.f'));
12-
time('num', () =>
29+
report('num', () =>
1330
lexer.call('1 23 34 456 12341234 12351235'));
14-
time('num-double', () =>
31+
report('num-double', () =>
1532
lexer.call('.0 .1 .12 0.123 0.1234'));
16-
time('string', () =>
33+
report('string', () =>
1734
lexer.call("'quick brown dog and fox say what'"));
18-
time('string-escapes', () =>
35+
report('string-escapes', () =>
1936
lexer.call("quick '\\' brown \u1234 dog and fox\n\rsay what'"));
37+
38+
reporter.saveReport();
2039
}

0 commit comments

Comments
 (0)