UploadedFile should support a callback for upload progress
[WebKit-https.git] / Websites / perf.webkit.org / ChangeLog
1 2017-03-22  Ryosuke Niwa  <rniwa@webkit.org>
2
3         UploadedFile should support a callback for upload progress
4         https://bugs.webkit.org/show_bug.cgi?id=169977
5
6         Reviewed by Andreas Kling.
7
8         Added a new option dictionary to CommonRemoteAPI.sendHttpRequest with uploadProgressCallback
9
10         Moved request headers and responseHandler callback in NodeRemoteAPI to this dictionary,
11         and updated the tests which relied on this code.
12
13         * public/shared/common-remote.js:
14         (CommonRemoteAPI.prototype.postJSON):
15         (CommonRemoteAPI.prototype.postJSONWithStatus):
16         (CommonRemoteAPI.prototype.postFormData):
17         (CommonRemoteAPI.prototype.postFormDataWithStatus):
18         * public/v3/privileged-api.js:
19         (PrivilegedAPI.prototype.sendRequest):
20         * public/v3/remote.js:
21         (BrowserRemoteAPI.prototype.sendHttpRequest):
22         (BrowserRemoteAPI.prototype.sendHttpRequestWithFormData):
23         (BrowserRemoteAPI):
24         * server-tests/api-uploaded-file.js:
25         * tools/js/remote.js:
26         (NodeRemoteAPI.prototype.sendHttpRequest):
27         (NodeRemoteAPI.prototype.sendHttpRequestWithFormData):
28         (NodeRemoteAPI):
29
30 2017-03-22  Ryosuke Niwa  <rniwa@webkit.org>
31
32         ComponentBase should enqueue itself to render when it becomes connected
33         https://bugs.webkit.org/show_bug.cgi?id=169905
34
35         Reviewed by Antti Koivisto.
36
37         When a component becomes connected to a document, enqueue itself to render automatically.
38         Also added the support for boolean attribute to ComponentBase.createElement.
39
40         * ReadMe.md: Added an instruction to raise the upload limit per r214065.
41         * browser-tests/component-base-tests.js: Added tests for the new behavior and createElement. Also moved
42         the tests related to enqueueToRenderOnResize out of defineElement tests.
43
44         * browser-tests/index.html:
45         (BrowsingContext.prototype.constructor): Override requestAnimationFrame so that the callback would be
46         involved immediately durign testing.
47
48         * public/v3/components/base.js:
49         (ComponentBase): Enqueue itself to render during construction if custom elements is not available.
50         (ComponentBase.defineElement):
51         (ComponentBase.defineElement.elementClass.prototype.connectedCallback): Enqueue itself to render when
52         the component's element became connected.
53         (ComponentBase.createElement): Use Array.isArray instead of instanceof to make it work with arrays made
54         in other realms (global objects) during testing. Added the support for boolean attributes. Setting an
55         attribute value to true would set the attribute, and setting it to false would not set the attribute.
56         (ComponentBase.useNativeCustomElements): Added. True iff window.customElements is defined.
57
58         * public/v3/components/chart-pane-base.js:
59         (ChartPaneBase.prototype.render): No longer need to call enqueueToRender on the commit log viewer.
60
61         * public/v3/components/commit-log-viewer.js:
62         (CommitLogViewer.prototype.render): No longer need to call enqueueToRender on the spinner icon.
63
64         * public/v3/models/time-series.js:
65         (TimeSeries): Made this a proper class declaration now that we don't include data.js after r213300.
66
67         * public/v3/pages/chart-pane.js:
68         (ChartPane.prototype._renderActionToolbar): No longer need to call enqueueToRender on the close icon.
69
70         * public/v3/pages/summary-page.js:
71         (SummaryPage.prototype._renderCell): No longer need to call enqueueToRender on the spinner icon.
72
73 2017-03-20  Ryosuke Niwa  <rniwa@webkit.org>
74
75         Delete another function that was supposed to be removed in the previous commit.
76
77         * public/v3/models/build-request.js:
78         (BuildRequest.cachedRequestsForTriggerableID): Deleted.
79
80 2017-03-20  Ryosuke Niwa  <rniwa@webkit.org>
81
82         Modernize BuildRequestQueuePage
83         https://bugs.webkit.org/show_bug.cgi?id=169903
84
85         Reviewed by Antti Koivisto.
86
87         Modernized the code for /v3/#/analysis/queue.
88
89         * public/v3/models/build-request.js:
90         (BuildRequest.fetchTriggerables): Deleted since the manifest JSON now contains all the triggerables.
91
92         * public/v3/pages/build-request-queue-page.js:
93         (BuildRequestQueuePage): Deleted this._triggerables. Added this._buildRequestsByTriggerable.
94         (BuildRequestQueuePage.prototype.open): Modernized the code.
95         (BuildRequestQueuePage.prototype.render): Ditto.
96         (BuildRequestQueuePage.prototype._constructBuildRequestTable): Ditto.
97
98 2017-03-19  Ryosuke Niwa  <rniwa@webkit.org>
99
100         Charts page show an inconsistent list of revisions for Git and Subversion
101         https://bugs.webkit.org/show_bug.cgi?id=169888
102
103         Reviewed by Andreas Kling.
104
105         With Git, CommitLogViewer was showing the list of revisions including the starting hash,
106         which was the last data point's revision instead of all revisions after the last data point.
107
108         Fixed the bug by always specifying the revision at the last data point in both Subversion
109         and Git and then making /api/commits/<repository>/?from=X&to=Y exclude the first revision.
110         For clarity, "from" and "to" query parameters have been renamed to "precedingRevision" and
111         "lastRevision" respectively.
112
113         We also no longer adds 1 to the starting revision of Subversion-like starting revisions. e.g.
114         when the last data point was at r1234, new data point is at r1250, the label is now "r1234-r1250"
115         instead of "r1235-r1250".
116
117         * browser-tests/chart-revision-range-tests.js: Fixed the tests since revisionList no longer
118         specifies from/to revisions.
119         * browser-tests/commit-log-viewer-tests.js: Added. Added tests for CommitLogViewer.
120         * browser-tests/index.html: Include the new test. Also use a local copy of mocha.js/css.
121
122         * public/api/commits.php:
123         (main): Renamed "from" and "to" query parameters.
124
125         * public/include/commit-log-fetcher.php:
126         (CommitLogFetcher::fetch_between): Added a check that commit time should either be specified
127         in both rows or not specified in either. Also reject when before_first_revision is identical
128         or after last_revision instead of re-ordering them since it no longer makes sense to do so with
129         new query parameter names.
130
131         * public/v3/components/base.js:
132         (ComponentBase._addContentToElement): Use Array.isArray instead of instanceof. It's resilient
133         againt realm (global object) differences.
134
135         * public/v3/components/chart-pane-base.js:
136         (ChartPaneBase.prototype._updateCommitLogViewer): No longer calls enqueueToRender on this since
137         CommitLogViewer does that on its own now.
138         (ChartPaneBase.prototype.render): Juse use this._openRepository instead of relying on CommitLogViewer
139         to remember which repository is current. This was the only use of currentRepository.
140
141         * public/v3/components/commit-log-viewer.js:
142         (CommitLogViewer):
143         (CommitLogViewer.prototype.currentRepository): Deleted.
144         (CommitLogViewer.prototype.view):
145         (CommitLogViewer.prototype._fetchCommitLogs): Modernized and extracted from view to make it lazy.
146         Call fetchForSingleRevision when precedingRevision is not specified or it's identical to lastRevision
147         since the generic JSON API no longer supports being called with the identical revisions.
148         (CommitLogViewer.prototype.render): Modernized & simplified the code.
149         (CommitLogViewer.prototype._renderCommitList): Extracted from render to make it lazy.
150         (CommitLogViewer.htmlTemplate): Add ID on caption & tbody so that they're more easily addressable.
151         (CommitLogViewer.cssTemplate):
152
153         * public/v3/models/commit-log.js:
154         (CommitLog.prototype.diff): No longer includes from/to revisions in the result. Also avoid adding
155         1 to a Subversion-like starting revision for creating the label. See above. But we still do this
156         for forming URLs due to the way tools like Trac work with Subversion revisions.
157         (CommitLog.fetchBetweenRevisions): Rewritten using DataModel.prototype.cachedFetch with FIXME for
158         what this function is supposed to be doing.
159         (CommitLog._cachedCommitLogs): Deleted.
160         (CommitLog.fetchForSingleRevision): Added.
161         (CommitLog._constructFromRawData): Added.
162
163         * public/v3/models/data-model.js:
164         (DataModelObject.cachedFetch): Don't parse query values as an integer. Just URL-escape them.
165
166         * public/v3/remote.js:
167         (BrowserRemoteAPI.prototype.sendHttpRequest): Fixed a typo.
168
169         * server-tests/api-commits-tests.js: Renamed from api-commits.js. Updated the existing tests to
170         use new query parameters and added more test cases.
171
172         * unit-tests/commit-log-tests.js: Updated the test cases now that CommitLog.prototype.diff no longer
173         includes from/to values. They're computed in ChartRevisionRange instead.
174
175 2017-03-20  Ryosuke Niwa  <rniwa@webkit.org>
176
177         Fix os-build-fetcher.js and subprocess.js to make them work
178         https://bugs.webkit.org/show_bug.cgi?id=169844
179
180         Reviewed by Antti Koivisto.
181
182         The script added in r213976 has a bug that it can execute commands to fetch subcommits in parallel.
183         Some commands to poll the lsit of system components is not desirable to be ran in parallel.
184
185         * server-tests/resources/mock-subprocess.js:
186         (MockSubprocess): Use const declaration.
187         (MockSubprocess.resetAndWaitForInvocation): Added.
188         (MockSubprocess.waitForInvocation): Renamed from waitingForInvocation. A function name must be a verb.
189         See https://webkit.org/code-style-guidelines/#names-verb
190         (MockSubprocess.reset): Set invocations.length to 0 so that tests can store a reference to the array
191         regardless of whether reset is called or when it's called.
192
193         * server-tests/tools-os-build-fetcher-tests.js: Updated tests per the code change. Most of codes now
194         expect each command to be ran seprately. e.g. if there were two commands to run, instead of expecting
195         them to be both ran, and resolving invocation promises, we'd wait for one command to run, resolve,
196         its subcommand to run, and then move onto the second top-level command. Also use a local reference
197         to MockSubprocess.invocations instead of using the fully qualified name.
198
199         * tools/js/os-build-fetcher.js:
200         (mapInSerialPromiseChain): Added. Calling a closure that returns a promise on each item in an array
201         in serial (not asynchronous) is a very common pattern in this class.
202         (OSBuildFetcher.fetchAndReportAllInOrder): Added.
203         (OSBuildFetcher.prototype.fetchAndReportNewBuilds): Log what the number of builds being submitted.
204         (OSBuildFetcher.prototype._fetchAvailableBuilds): Fixed the main bug. Using Promise.all would result
205         in each top-level command to be execued in parallel. Since each subcommand is executed as soon as
206         its parent command is executed, this results in commands to be executed in parallel.
207         Added a whole bunch of logging so that we can at least detect a bug like this in the future.
208         (OSBuildFetcher.prototype._commitsForAvailableBuilds): Cleanup the coding style.
209         (OSBuildFetcher.prototype._addSubCommitsForBuild): Use mapInSerialPromiseChain. Tightened the assertion
210         about the content returned by a subcommand.
211
212         * tools/js/subprocess.js: Fixed the bug that we were importing require('child_process').ChildProcess.
213         execFile is defined on require('child_process') itself.
214         (Subprocess.prototype.execute): Fixed a typo. this._childProcess doesn't exist.
215         (Subprocess):
216
217         * tools/sync-os-versions.js: Renamed from tools/pull-os-versions.js.
218         (syncLoop): Cleaned up the coding style a little. Also added logging about how long we're about to sleep.
219
220 2017-03-16  Ryosuke Niwa  <rniwa@webkit.org>
221
222         Add the file uploading capability to the perf dashboard.
223         https://bugs.webkit.org/show_bug.cgi?id=169737
224
225         Reviewed by Chris Dumez.
226
227         Added /privileged-api/upload-file to upload a file, and /api/uploaded-file/ to download the file
228         and retrieve its meta data based on its SHA256. We treat two files with the identical SHA256 as
229         identical since anyone who can upload a file using this mechanism can execute arbitrary code in
230         our bots anyway. This is important for avoiding uploading a large darwinup roots multiple times
231         to the server, saving both user's time/bandwidth and server's disk space.
232
233         * config.json: Added uploadDirectory, uploadFileLimitInMB, and uploadUserQuotaInMB as options.
234         * init-database.sql: Added uploaded_files table.
235
236         * public/api/uploaded-file.php: Added.
237         (main): /api/uploaded-file/N would download uploaded_file with id=N. /api/uploaded-file/?sha256=X
238         would return the meta data for uploaded_file with sha256=X.
239         (stream_file_content): Streams the file content in 64KB chunks. We support Range & If-Range HTTP
240         request headers so that browsers can pause and resume downloading of a large root file.
241         (parse_range_header): Parses Range HTTP request header.
242
243         * public/include/json-header.php:
244         (remote_user_name): Use the default argument of NULL.
245
246         * public/include/manifest-generator.php:
247         (ManifestGenerator::generate): Include the maximum upload size in the manifest file to let the
248         frontend code preemptively check the file size before attempting to submit a file.
249
250         * public/include/uploaded-file-helpers.php: Added.
251         (format_uploaded_file):
252         (uploaded_file_path_for_row):
253
254         * public/privileged-api/upload-file-form.html: Added. For debugging purposes.
255         (fetchCSRFfToken):
256         (upload):
257
258         * public/privileged-api/upload-file.php: Added.
259         (main):
260         (query_total_file_size):
261         (create_uploaded_file_from_form_data):
262
263         * public/shared/common-remote.js:
264         (CommonRemoteAPI.prototype.postFormData): Added.
265         (CommonRemoteAPI.prototype.postFormDataWithStatus): Added.
266         (CommonRemoteAPI.prototype.sendHttpRequestWithFormData): Added.
267         (CommonRemoteAPI.prototype._asJSON): Throw an exception instead of calling a non-existent reject.
268
269         * public/v3/models/uploaded-file.js: Added.
270         (UploadedFile): Added.
271         (UploadedFile.uploadFile): Added.
272         (UploadedFile.fetchUnloadedFileWithIdenticalHash): Added. Finds the file with the same SHA256 in
273         the server to avoid uploading a large custom root multiple times.
274         (UploadedFile._computeSHA256Hash): Added.
275
276         * public/v3/privileged-api.js:
277         (PrivilegedAPI.prototype.sendRequest): Added the options dictionary as a third argument. For now,
278         only support useFormData boolean.
279
280         * public/v3/remote.js:
281         (BrowserRemoteAPI.prototype.sendHttpRequestWithFormData): Added.
282
283         * server-tests/api-manifest.js: Updated per the inclusion of fileUploadSizeLimit in the manifest.
284         * server-tests/api-uploaded-file.js: Added.
285         * server-tests/privileged-api-upload-file-tests.js: Added.
286
287         * server-tests/resources/temporary-file.js: Added.
288         (TemporaryFile): Added. A helper class for creating a temporary file to upload.
289         (TemporaryFile.makeTemporaryFileOfSizeInMB):
290         (TemporaryFile.makeTemporaryFile):
291         (TemporaryFile.inject):
292
293         * server-tests/resources/test-server.conf: Set upload_max_filesize and post_max_size for testing.
294         * server-tests/resources/test-server.js:
295         (TestServer.prototype.testConfig): Use uploadFileLimitInMB and uploadUserQuotaInMB of 2MB and 5MB.
296         (TestServer.prototype._ensureDataDirectory): Create a directory to store uploaded files inside
297         the data directory. In a production server, we can place it outside ServerRoot / DocumentRoot.
298         (TestServer.prototype.cleanDataDirectory): Delete the aforementioned directory as needed.
299
300         * tools/js/database.js:
301         (tableToPrefixMap): Added uploaded_files.
302
303         * tools/js/remote.js:
304         (NodeRemoteAPI.prototype.sendHttpRequest): Added a dictionary to specify request headers and
305         a callback to process the response as arguments. Fixed the bug that any 2xx code other than 200
306         was resulting in a rejected promise. Also include the response headers in the result for tests.
307         Finally, when content is a function, call that instead of writing the content since FormData
308         requires a custom logic.
309         (NodeRemoteAPI.prototype.sendHttpRequestWithFormData): Added.
310
311         * tools/js/v3-models.js: Include uploaded-file.js.
312
313         * tools/run-tests.py:
314         (main): Add form-data as a new dependency.
315
316 2017-03-15  Dewei Zhu  <dewei_zhu@apple.com>
317
318         Fix unit test and bug fix for 'pull-os-versions.js' script.
319         https://bugs.webkit.org/show_bug.cgi?id=169701
320
321         Reviewed by Ryosuke Niwa.
322
323         Fix unit tests warnings on node-6.10.0.
324         Fix 'pull-os-versions.js' does not fetch new builds and report.
325
326         * server-tests/tools-os-build-fetcher-tests.js:
327         (then):
328         (beforeEach):
329         (afterEach):
330         * tools/pull-os-versions.js:
331         (syncLoop):
332
333 2017-03-15  Ryosuke Niwa  <rniwa@webkit.org>
334
335         In-browser and node.js implementations of RemoteAPI should share some code
336         https://bugs.webkit.org/show_bug.cgi?id=169695
337
338         Rubber-stamped by Antti Koivisto.
339
340         Extracted CommonRemoteAPI out of RemoteAPI implementations for node.js and browser. 
341
342         * public/shared/common-remote.js: Added.
343         (CommonRemoteAPI): Added.
344         (CommonRemoteAPI.prototype.postJSON): Extracted from RemoteAPI.
345         (CommonRemoteAPI.prototype.postJSONWithStatus): Ditto.
346         (CommonRemoteAPI.prototype.getJSON): Ditto.
347         (CommonRemoteAPI.prototype.getJSONWithStatus): Ditto.
348         (CommonRemoteAPI.prototype.sendHttpRequest): Added. Needs to implemented by a subclass.
349         (CommonRemoteAPI.prototype._asJSON): Added.
350         (CommonRemoteAPI.prototype._checkStatus): Added.
351
352         * public/v3/index.html: Include common-remote.js.
353
354         * public/v3/privileged-api.js:
355         (PrivilegedAPI): Use class now that we don't include data.js.
356         (PrivilegedAPI.sendRequest): Modernized the code.
357         (PrivilegedAPI.requestCSRFToken): Ditto.
358
359         * public/v3/remote.js:
360         (BrowserRemoteAPI): Renamed from RemoteAPI. window.RemoteAPI is now an instance of this class.
361         (BrowserRemoteAPI.prototype.sendHttpRequest): Moved from RemoteAPI.sendHttpRequest.
362         (BrowserRemoteAPI.prototype.sendHttpRequest):
363
364         * server-tests/privileged-api-create-analysis-task-tests.js: Updated tests since NodeJSRemoteAPI
365         now throws the JSON status as an error to be consistent with BrowserRemoteAPI.
366         * server-tests/privileged-api-create-test-group-tests.js: Ditto.
367         * server-tests/privileged-api-upate-run-status.js: Ditto.
368
369         * tools/js/buildbot-triggerable.js:
370         (BuildbotTriggerable.prototype.syncOnce): Just use postJSONWithStatus instead of manually
371         checking the status.
372
373         * tools/js/remote.js:
374         (NodeRemoteAPI): Renamed from RemoteAPI. Still exported as RemoteAPI.
375         (NodeRemoteAPI.prototype.constructor):
376         (NodeRemoteAPI.prototype.sendHttpRequest): Modernized the code.
377
378 2017-03-15  Ryosuke Niwa  <rniwa@webkit.org>
379
380         Fix server tests after r213998 and r213969
381         https://bugs.webkit.org/show_bug.cgi?id=169690
382
383         Reviewed by Antti Koivisto.
384
385         Fixed the existing server tests.
386
387         * public/v3/models/analysis-task.js:
388         (AnalysisTask.prototype._updateRemoteState): Use the relative path from the root so that it works inside tests.
389         (AnalysisTask.prototype.associateBug): Ditto.
390         (AnalysisTask.prototype.dissociateBug): Ditto.
391         (AnalysisTask.prototype.associateCommit): Ditto.
392         (AnalysisTask.prototype.dissociateCommit): Ditto.
393         (AnalysisTask._fetchSubset): Ditto.
394         (AnalysisTask.fetchAll): Ditto.
395         * public/v3/models/test-group.js:
396         (TestGroup.prototype.updateName): Ditto.
397         (TestGroup.prototype.updateHiddenFlag): Ditto.
398         (TestGroup.createAndRefetchTestGroups): Ditto.
399         (TestGroup.cachedFetch): Ditto.
400         * server-tests/api-manifest.js: Reverted an inadvertant change in r213969.
401         * tools/js/database.js:
402         (tableToPrefixMap): Added analysis_strategies.
403         * unit-tests/analysis-task-tests.js: Updated expectations per changes to AnalysisTask.
404
405 2017-03-15  Ryosuke Niwa  <rniwa@webkit.org>
406
407         Add tests for privileged-api/create-analysis-task and privileged-api/create-test-group
408         https://bugs.webkit.org/show_bug.cgi?id=169688
409
410         Rubber-stamped by Antti Koivisto.
411
412         Added tests for privileged-api/create-analysis-task and privileged-api/create-test-group, and fixed newly found bugs.
413
414         * public/privileged-api/create-analysis-task.php:
415         (main): Fixed the bug that we were not explicitly checking whether start_run and end_run were integers or not.
416         Also return InvalidTimeRange when start and end times are identical as that makes no sense for an analysis task.
417
418         * public/privileged-api/create-test-group.php:
419         (main): Fixed a bug that we were not explicitly checking task and repetitionCount to be an integer.
420         (ensure_commit_sets): Fixed the bug that the number of commit sets weren't checked. 
421
422         * server-tests/privileged-api-create-analysis-task-tests.js: Added.
423         * server-tests/privileged-api-create-test-group-tests.js: Added.
424
425         * server-tests/resources/common-operations.js:
426         (prepareServerTest): Increase the timeout from 1s to 5s.
427
428         * server-tests/resources/mock-data.js:
429         (MockData.addMockData): Use a higher database ID of 20 for a mock build_slave to avoid a conflict with auto-generated IDs.
430
431 2017-03-15  Ryosuke Niwa  <rniwa@webkit.org>
432
433         Make unit tests return a promise instead of manually calling done
434         https://bugs.webkit.org/show_bug.cgi?id=169663
435
436         Reviewed by Antti Koivisto.
437
438         Make the existing unit tests always reutrn a promise instead of manually calling "done" callback as done
439         in r213969. The promise tests are a lot more stable and less error prone.
440
441         Also use MockRemoteAPI.waitForRequest() instead of chaining two resolved promises where appropriate.
442
443         * unit-tests/analysis-task-tests.js:
444         * unit-tests/buildbot-syncer-tests.js:
445         * unit-tests/checkconfig.js:
446         * unit-tests/privileged-api-tests.js:
447
448 2017-03-15  Dewei Zhu  <dewei_zhu@apple.com>
449
450         Rewrite 'pull-os-versions' script in Javascript to add support for reporting os revisions with sub commits.
451         https://bugs.webkit.org/show_bug.cgi?id=169542
452
453         Reviewed by Ryosuke Niwa.
454
455         Extend '/api/commits/<repository>/last-reported' to accept a range and return last reported commits in given range.
456         Rewrite 'pull-os-versions' in JavaScript and add unit tests for it.
457         Instead of writing query manually while searching criteria contains null columns, use the methods provided in 'db.php'.
458         Add '.gitignore' file to ommit files generated by while running tests/instances locally.
459
460         * .gitignore: Added.
461         * public/api/commits.php:
462         * public/api/report-commits.php:
463         * public/include/commit-log-fetcher.php:
464         * public/include/db.php: 'null_columns' of prepare_params should be a reference.
465         * public/include/report-processor.php:
466         * server-tests/api-commits.js:
467         (then):
468         * server-tests/api-report-commits-tests.js:
469         * server-tests/resources/mock-logger.js: Added.
470         (MockLogger):
471         (MockLogger.prototype.log):
472         (MockLogger.prototype.error):
473         * server-tests/resources/mock-subprocess.js: Added.
474         (MockSubprocess.call):
475         (MockSubprocess.waitingForInvocation):
476         (MockSubprocess.inject):
477         (MockSubprocess.reset):
478         * server-tests/tools-buildbot-triggerable-tests.js:
479         (MockLogger): Deleted.
480         (MockLogger.prototype.log): Deleted.
481         (MockLogger.prototype.error): Deleted.
482         * server-tests/tools-os-build-fetcher-tests.js: Added.
483         (beforeEach):
484         (return.waitingForInvocationPromise.then):
485         (then):
486         (string_appeared_here.return.waitingForInvocationPromise.then):
487         (return.addSlaveForReport.emptyReport.then):
488         * tools/js/os-build-fetcher.js: Added.
489         (OSBuildFetcher):
490         (OSBuildFetcher.prototype._fetchAvailableBuilds):
491         (OSBuildFetcher.prototype._computeOrder):
492         (OSBuildFetcher.prototype._commitsForAvailableBuilds.return.this._subprocess.call.then.):
493         (OSBuildFetcher.prototype._commitsForAvailableBuilds):
494         (OSBuildFetcher.prototype._addSubCommitsForBuild):
495         (OSBuildFetcher.prototype._submitCommits):
496         (OSBuildFetcher.prototype.fetchAndReportNewBuilds):
497         * tools/js/subprocess.js: Added.
498         (const.childProcess.require.string_appeared_here.Subprocess.prototype.call):
499         (const.childProcess.require.string_appeared_here.Subprocess):
500         * tools/pull-os-versions.js: Added.
501         (main):
502         (syncLoop):
503         * tools/sync-commits.py:
504         (Repository.fetch_commits_and_submit):
505
506 2017-03-14  Ryosuke Niwa  <rniwa@webkit.org>
507
508         Make server tests return a promise instead of manually calling done
509         https://bugs.webkit.org/show_bug.cgi?id=169648
510
511         Rubber-stamped by Chris Dumez.
512
513         Make the existing server tests always reutrn a promise instead of manually calling "done" callback.
514         The promise tests are a lot more stable and less error prone.
515
516         Also use arrow functions everywhere and use prepareServerTest, renamed from connectToDatabaseInEveryTest,
517         in more tests instead of manually connecting to database in every test, and reset v3 models.
518
519         * server-tests/admin-platforms-tests.js:
520         * server-tests/admin-reprocess-report-tests.js:
521         * server-tests/api-build-requests-tests.js:
522         * server-tests/api-manifest.js:
523         * server-tests/api-measurement-set-tests.js:
524         (.postReports): Deleted. Not used in any test.
525         * server-tests/api-report-commits-tests.js:
526         * server-tests/api-report-tests.js:
527         * server-tests/api-update-triggerable.js:
528         * server-tests/privileged-api-upate-run-status.js:
529         * server-tests/resources/common-operations.js:
530         (prepareServerTest): Renamed from connectToDatabaseInEveryTest. Increase the timeout and reset v3 models.
531         * server-tests/tools-buildbot-triggerable-tests.js:
532
533 2017-03-12  Ryosuke Niwa  <rniwa@webkit.org>
534
535         Rename RootSet to CommitSet
536         https://bugs.webkit.org/show_bug.cgi?id=169580
537
538         Rubber-stamped by Chris Dumez.
539
540         Renamed root_sets to commit_sets and roots to commit_set_relationships in the database schema, and renamed
541         related classes in public/v3/ and tools accordingly.
542
543         RootSet, MeasurementRootSet, and CustomRootSet are respectively renamed to CommitSet, MeasurementCommitSet,
544         and CustomCommitSet.
545
546         In order to migrate the database, run:
547         ```
548         BEGIN;
549         ALTER TABLE root_sets RENAME TO commit_sets;
550         ALTER TABLE commit_sets RENAME COLUMN rootset_id TO commitset_id;
551         ALTER TABLE roots RENAME TO commit_set_relationships;
552         ALTER TABLE commit_set_relationships RENAME COLUMN root_set TO commitset_set;
553         ALTER TABLE commit_set_relationships RENAME COLUMN root_commit TO commitset_commit;
554         ALTER TABLE build_requests RENAME COLUMN request_root_set TO request_commit_set;
555         END;
556         ```
557
558         * browser-tests/index.html:
559         * init-database.sql:
560         * public/api/build-requests.php:
561         (main):
562         * public/api/test-groups.php:
563         (main):
564         (format_test_group):
565         * public/include/build-requests-fetcher.php:
566         (BuildRequestsFetcher::__construct):
567         (BuildRequestsFetcher::results_internal):
568         (BuildRequestsFetcher::commit_sets): Renamed from root_sets.
569         (BuildRequestsFetcher::commits): Renamed from roots.
570         (BuildRequestsFetcher::fetch_commits_for_set_if_needed): Renamed from fetch_roots_for_set_if_needed.
571         * public/privileged-api/create-test-group.php:
572         (main):
573         (ensure_commit_sets): Renamed from commit_sets_from_root_sets.
574         * public/v3/components/analysis-results-viewer.js:
575         (AnalysisResultsViewer.prototype.buildRowGroups):
576         (AnalysisResultsViewer.prototype._collectCommitSetsInTestGroups): Renamed from _collectRootSetsInTestGroups.
577         (AnalysisResultsViewer.prototype._buildRowsForPointsAndTestGroups):
578         (AnalysisResultsViewer.prototype._buildRowsForPointsAndTestGroups):
579         (AnalysisResultsViewer.CommitSetInTestGroup): Renamed from RootSetInTestGroup.
580         (AnalysisResultsViewer.CommitSetInTestGroup.prototype.constructor):
581         (AnalysisResultsViewer.CommitSetInTestGroup.prototype.commitSet): Renamed from rootSet.
582         (AnalysisResultsViewer.CommitSetInTestGroup.prototype.succeedingCommitSet): Renamed from succeedingRootSet.
583         (AnalysisResultsViewer.TestGroupStackingBlock.prototype.constructor):
584         (AnalysisResultsViewer.TestGroupStackingBlock.prototype.addRowIndex):
585         (AnalysisResultsViewer.TestGroupStackingBlock.prototype.isComplete):
586         (AnalysisResultsViewer.TestGroupStackingBlock.prototype.startRowIndex):
587         (AnalysisResultsViewer.TestGroupStackingBlock.prototype.endRowIndex):
588         (AnalysisResultsViewer.TestGroupStackingBlock.prototype._computeTestGroupStatus):
589         * public/v3/components/chart-revision-range.js:
590         (ChartRevisionRange.prototype._revisionForPoint):
591         (ChartRevisionRange.prototype._computeRevisionList):
592         * public/v3/components/customizable-test-group-form.js:
593         (CustomizableTestGroupForm.prototype.constructor):
594         (CustomizableTestGroupForm.prototype.setCommitSetMap): Renamed from setRootSetMap.
595         (CustomizableTestGroupForm.prototype._submitted):
596         (CustomizableTestGroupForm.prototype._computeCommitSetMap): Renamed from _computeRootSetMap.
597         (CustomizableTestGroupForm.prototype.render): Renamed from render.
598         (CustomizableTestGroupForm.prototype._constructRevisionRadioButtons):
599         * public/v3/components/results-table.js:
600         (ResultsTable.prototype.render):
601         (ResultsTable.prototype._createRevisionListCells):
602         (ResultsTable.prototype._computeRepositoryList):
603         (ResultsTableRow.prototype.constructor):
604         (ResultsTableRow.prototype.commitSet): Renamed from rootSet.
605         * public/v3/components/test-group-results-table.js:
606         (TestGroupResultsTable.prototype.buildRowGroups):
607         * public/v3/index.html:
608         * public/v3/models/build-request.js:
609         (BuildRequest.prototype.constructor):
610         (BuildRequest.prototype.updateSingleton):
611         (BuildRequest.prototype.commitSet): Renamed from rootSet.
612         (BuildRequest.constructBuildRequestsFromData):
613         * public/v3/models/commit-set.js: Renamed from public/v3/models/root-set.js.
614         (CommitSet): Renamed from RootSet.
615         (CommitSet.containsMultipleCommitsForRepository):
616         (MeasurementCommitSet): Renamed from MeasurementRootSet.
617         (MeasurementCommitSet.prototype.namedStaticMap):
618         (MeasurementCommitSet.prototype.ensureNamedStaticMap):
619         (MeasurementCommitSet.namedStaticMap):
620         (MeasurementCommitSet.ensureNamedStaticMap):
621         (MeasurementCommitSet.ensureSingleton):
622         (CustomCommitSet): Renamed from CustomRootSet.
623         * public/v3/models/measurement-adaptor.js:
624         (MeasurementAdaptor.prototype.applyTo):
625         * public/v3/models/test-group.js:
626         (TestGroup.prototype.constructor):
627         (TestGroup.prototype.addBuildRequest):
628         (TestGroup.prototype.repetitionCount):
629         (TestGroup.prototype.requestedCommitSets): Renamed from requestedRootSets.
630         (TestGroup.prototype.requestsForCommitSet): Renamed from requestsForRootSet.
631         (TestGroup.prototype.labelForCommitSet): Renamed from labelForRootSet.
632         (TestGroup.prototype.didSetResult):
633         (TestGroup.prototype.compareTestResults):
634         (TestGroup.prototype._valuesForCommitSet): Renamed from _valuesForRootSet.
635         (TestGroup.prototype.createAndRefetchTestGroups):
636         * public/v3/pages/analysis-task-page.js:
637         (AnalysisTaskPage.prototype.render):
638         (AnalysisTaskPage.prototype._retryCurrentTestGroup):
639         (AnalysisTaskPage.prototype._createNewTestGroupFromChart):
640         (AnalysisTaskPage.prototype._createNewTestGroupFromViewer):
641         (AnalysisTaskPage.prototype._createTestGroupAfterVerifyingCommitSetList):
642         * server-tests/api-build-requests-tests.js:
643         * server-tests/resources/mock-data.js:
644         (MockData.resetV3Models):
645         (MockData.addMockData):
646         (MockData.addAnotherMockTestGroup):
647         * tools/detect-changes.js:
648         (createAnalysisTaskAndNotify):
649         * tools/js/buildbot-syncer.js:
650         (BuildbotSyncer.prototype._propertiesForBuildRequest):
651         (BuildbotSyncer.prototype._revisionSetFromCommitSetWithExclusionList):
652         * tools/js/database.js:
653         (tableToPrefixMap):
654         * tools/js/v3-models.js:
655         * tools/sync-buildbot.js:
656         (syncLoop):
657         * tools/sync-with-buildbot.py: Deleted. No longer used.
658         * unit-tests/analysis-task-tests.js:
659         * unit-tests/build-request-tests.js:
660         (sampleBuildRequestData):
661         * unit-tests/buildbot-syncer-tests.js:
662         (sampleCommitSetData):
663         * unit-tests/measurement-adaptor-tests.js:
664         * unit-tests/measurement-set-tests.js:
665         * unit-tests/resources/mock-v3-models.js:
666         (MockModels.inject):
667         * unit-tests/test-groups-tests.js:
668         (sampleTestGroup):
669
670 2017-03-13  Ryosuke Niwa  <rniwa@webkit.org>
671
672         Database's query functions should support querying for a row with NULL value
673         https://bugs.webkit.org/show_bug.cgi?id=169504
674
675         Reviewed by Antti Koivisto.
676
677         Add the support for calling select_* with one of column values set to NULL.
678         This feature is useful in webkit.org/b/146374 and webkit.org/b/168962.
679
680         * public/include/db.php:
681         (Database::prepare_params): Added $null_columns as an optional argument.
682         (Database::select_conditions_with_null_columns): Added. Builds up a query string by appending AND x is NULL
683         to match columns whose value must be NULL.
684         (Database::_select_update_or_insert_row):
685         (Database::select_rows):
686
687 2017-03-13  Dewei Zhu  <dewei_zhu@apple.com>
688
689         Add the ability to report a commit with sub-commits.
690         https://bugs.webkit.org/show_bug.cgi?id=168962
691
692         Reviewed by Ryosuke Niwa.
693
694         Introduce 'commit_ownerships' which records ownership between commits.
695         On existing production server, run ```
696             CREATE TABLE commit_ownerships (
697                 commit_owner integer NOT NULL REFERENCES commits ON DELETE CASCADE,
698                 commit_ownee integer NOT NULL REFERENCES commits ON DELETE CASCADE,
699                 PRIMARY KEY (commit_owner, commit_ownee)
700             );
701             ALTER TABLE repositories RENAME repository_parent TO repository_owner;
702             ALTER TABLE repositories DROP repository_name_must_be_unique;
703             CREATE UNIQUE INDEX repository_name_owner_unique_index ON repositories (repository_owner, repository_name) WHERE repository_owner IS NOT NULL;
704             CREATE UNIQUE INDEX repository_name_unique_index ON repositories (repository_name) WHERE repository_owner IS NULL;
705         ``` to update database.
706         Add unit-tests to cover this change.
707
708         * init-database.sql:
709         * public/api/report-commits.php:
710         * public/include/commit-log-fetcher.php:
711         * public/include/db.php:
712         * public/include/manifest-generator.php:
713         * public/include/report-processor.php:
714         * public/v3/models/repository.js:
715         (Repository):
716         (Repository.prototype.owner):
717         * server-tests/admin-reprocess-report-tests.js:
718         (addBuilderForReport.simpleReportWithRevisions.0.then):
719         (then):
720         * server-tests/api-manifest.js:
721         (then):
722         * server-tests/api-report-commits-tests.js:
723         (addSlaveForReport.sameRepositoryNameInSubCommitAndMajorCommit.then):
724         (then):
725         (addSlaveForReport.systemVersionCommitWithSubcommits.then):
726         (addSlaveForReport.multipleSystemVersionCommitsWithSubcommits.then):
727         (addSlaveForReport.systemVersionCommitWithEmptySubcommits.then):
728         (addSlaveForReport.systemVersionCommitAndSubcommitWithTimestamp.then):
729         * tools/js/database.js:
730
731 2017-03-07  Ryosuke Niwa  <rniwa@webkit.org>
732
733         Update ReadMe.md to use directory format for backing up & restoring the database
734         https://bugs.webkit.org/show_bug.cgi?id=169263
735
736         Reviewed by Joseph Pecoraro.
737
738         Update ReadMe.md's instruction to backup and restore the database to use directory format instead of
739         piping it to gzip. The new command will backup and restore the database with multiple concurrent processes
740         with a custom compression level.
741
742         * ReadMe.md:
743
744 2017-03-02  Ryosuke Niwa  <rniwa@webkit.org>
745
746         Make baseline data points selectable
747         https://bugs.webkit.org/show_bug.cgi?id=169069
748         <rdar://problem/29209427>
749
750         Reviewed by Antti Koivisto.
751
752         Add the capability to select data points other than "current" configuration type.
753
754         This patch refactors the way the "chart status" is computed. Before this patch, ChartStatusView was
755         responsible for determining two data points for which to compute the status, and computing the status
756         between two data points. ChartPaneStatusView which inherits from ChartStatusView and used in the charts
757         page relied upon ChartStatusView to compute these values, and computed the list of revision ranges for
758         each relevant repository between the data points. ChartPane then had callbacks on ChartPaneStatusView
759         to know whenever these values changed. Because of this entangled mess, ChartStatusView had to be aware
760         of InteractiveTimeSeriesChart even though only ChartPaneStatusView could be used with it.
761
762         This patch dramatically simplifies the situation by adding referencePoints() on TimeSeriesChart and
763         InteractiveTimeSeriesChart which returns the current point, the previous point if there is any, and
764         their time series view. It also extracts ChartStatusEvaluator which computes the current status values
765         and ChartRevisionRange which computes a list of revision differences both based on the referencePoints.
766         As a result, ChartPaneStatusView no longer inherits from ChartStatusView, and ChartStatusView has been
767         renamed to DashboardChartStatusView to reflect its purpose. Furthermore, ChartPane which used to rely on
768         ChartPaneStatusView's revisionCallback to update the commit log viewer simply uses another instance of
769         ChartRevisionRange, eliminating the need for the callback.
770
771         To implement these classes easily, this patch also introduces a new class, LazilyEvaluatedFunction to
772         memoize the return value of a function when called with the same arguments. Delaying the computation of
773         a value and avoiding the work when the values are the same is a very common pattern in the perf dashboard
774         so I expect this class would be used in a lot more places in the future.
775
776         * browser-tests/chart-revision-range-tests.js: Added. Tests for ChartRevisionRange.
777         * browser-tests/chart-status-evaluator-tests.js: Added. Tests for ChartStatusEvaluator.
778
779         * browser-tests/index.html:
780         (BrowsingContext):
781         (BrowsingContext.importScripts): Fixed the bug that calling importScripts twice results in MockRemoteAPI
782         being loaded twice.
783         (ChartTest.importChartScripts): Import more model objects.
784         (ChartTest.sampleCluster): Made this a getter.
785         (ChartTest.makeModelObjectsForSampleCluster):
786         (ChartTest.makeSampleCluster): Added. Cutomizes the valus of baseline / target based on options.
787         (ChartTest.respondWithSampleCluster): Now takes an options argument for makeSampleCluster.
788
789         * public/v3/components/chart-pane-base.js:
790         (ChartPaneBase): Added _openRepository to keep track of the currently open repository instead of relying
791         on _mainChartStatus or _commitLogViewer to keep track of it.
792         (ChartPaneBase.prototype.configure):  The callback for when the user clicked on a repository name in
793         ChartPaneStatusView has been replaced by "openRepository" action.
794         (ChartPaneBase.prototype.setOpenRepository): Moved from ChartPane.
795         (ChartPaneBase.prototype._mainSelectionDidChange):
796         (ChartPaneBase.prototype._indicatorDidChange):
797         (ChartPaneBase.prototype._didFetchData):
798         (ChartPaneBase.prototype._updateCommitLogViewer): Renamed from _updateStatus.
799         (ChartPaneBase.prototype.openNewRepository): Renamed from _requestOpeningCommitViewer. Fixed a bug that
800         clicking on the repository name inside ChartPaneStatusView would not focus the pane, which resulted in
801         arrow keys to be ignored instead of moving the main chart's indicator or the currently open repository.
802         (ChartPaneBase.prototype._keyup):
803         (ChartPaneBase.prototype._moveOpenRepository): Moved from ChartPaneStatusView's
804         moveRepositoryWithNotification. Used when changing the open repository by up/down arrow keys.
805
806         * public/v3/components/chart-revision-range.js: Added. Extracted from ChartPaneStatusView.
807         (ChartRevisionRange): Added.
808         (ChartRevisionRange.prototype.revisionList): Added.
809         (ChartRevisionRange.prototype.rangeForRepository): Added.
810         (ChartRevisionRange._revisionForPoint): Added. Extracted from ChartPaneStatusView's
811         _updateRevisionListForNewCurrentRepository.
812         (ChartRevisionRange._computeRevisionList): Ditto from computeChartStatusLabels.
813
814         * public/v3/components/chart-status-evaluator.js: Added.
815         (ChartStatusEvaluator): Added.
816         (ChartStatusEvaluator.prototype.status): Added.
817         (ChartStatusEvaluator.computeChartStatus): Added. Extracted from ChartStatusView's updateStatusIfNeeded.
818
819         * public/v3/components/chart-status-view.js: Removed.
820         (ChartStatusView): Deleted. Split into ChartStatusEvaluator and DashboardChartStatusView.
821
822         * public/v3/components/chart-styles.js:
823         (ChartStyles.baselineStyle): Make baseline data points interactive. This single line change is what
824         enables the user to interact with the data points. The rest of changes in this patch mostly deals with
825         the status text such as "5% worse than baseline" and the list of revisions shown in the commit log viewer
826         which would have shown the wrong range without these changes.
827
828         * public/v3/components/dashboard-chart-status-view.js: Added. Extracted from ChartStatusView.
829         (DashboardChartStatusView): Added.
830         (DashboardChartStatusView.prototype.render): Added.
831         (DashboardChartStatusView.htmlTemplate): Added.
832         (DashboardChartStatusView.cssTemplate): Added.
833
834         * public/v3/components/interactive-time-series-chart.js:
835         (InteractiveTimeSeriesChart.prototype.referencePoints): Added. Return the first point and the last point
836         as the reference points when there is a selection. Only report the previous point if they are distinct as
837         showing a range of revisions from a data point to itself makes no sense. When there is a indicator simply
838         return it and its previous point as reference points. Otherwise return null unlike TimeSeriesChart's
839         referencePoints which always returns the latest point as the reference point.
840
841         * public/v3/components/time-series-chart.js:
842         (TimeSeriesChart.prototype.referencePoints): Added. Return the latest point as the reference point. It
843         never returns the previous point even if there were more data points as there is no way for the user to
844         specify which data points to compare.
845
846         * public/v3/index.html: Include newly added files.
847
848         * public/v3/lazily-evaluated-function.js: Added.
849         (LazilyEvaluatedFunction): Added.
850         (LazilyEvaluatedFunction.prototype.evaluate): Added.
851
852         * public/v3/models/commit-log.js:
853         (CommitLog.prototype.diff): Fixed a bug that computing the diff of two Subversion-like revisions results
854         in "from" field to be unexpectedly an integer instead of a string.
855
856         * public/v3/models/metric.js:
857         (Metric): Moved the code to compute the unit from the metric name from v2's RunsData class. This makes
858         writing tests easier since it eliminates the need to load v2's data.js.
859         (Metric.prototype.unit):
860         (Metric.prototype.isSmallerBetter): Ditto for determining whether the unit is smaller-is-better.
861
862         * public/v3/pages/analysis-task-page.js:
863         (AnalysisTaskChartPane.prototype._updateStatus): Deleted the unused code.
864
865         * public/v3/pages/chart-pane-status-view.js:
866         (ChartPaneStatusView): No longer inherits from ChartStatusView. Uses ChartStatusEvaluator and
867         ChartRevisionRange to to compute the chart status and the list of revision changes.
868         (ChartPaneStatusView.prototype.pointsRangeForAnalysis): Deleted.
869         (ChartPaneStatusView.prototype.render): Split it into _renderStatus and _renderBuildRevisionTable using
870         LazilyEvaluatedFunction.
871         (ChartPaneStatusView.prototype._renderStatus): Added.
872         (ChartPaneStatusView.prototype._renderBuildRevisionTable): Added.
873         (ChartPaneStatusView.prototype.setCurrentRepository): _updateRevisionListForNewCurrentRepository has been
874         moved into ChartRevisionRange. Just enqueue itself to re-render.
875         (ChartPaneStatusView.prototype._setRevisionRange): Deleted.
876         (ChartPaneStatusView.prototype.moveRepositoryWithNotification): Deleted.
877         (ChartPaneStatusView.prototype.updateRevisionList): Deleted.
878         (ChartPaneStatusView.prototype._updateRevisionListForNewCurrentRepository): Deleted.
879         (ChartPaneStatusView.prototype.computeChartStatusLabels): Deleted.
880         (ChartPaneStatusView.htmlTemplate):
881         (ChartPaneStatusView.cssTemplate):
882
883         * public/v3/pages/chart-pane.js:
884         (ChartPane.prototype.openNewRepository): Overrides the one in ChartPaneBase, which has been renamed from
885         _requestOpeningCommitViewer.
886         (ChartPane.prototype._analyzeRange):
887         (ChartPane.prototype._renderActionToolbar): Use the main chart's selection directly to determine whether
888         an analysis task can be created for the currenty selected range.
889
890         * public/v3/pages/dashboard-page.js:
891         (DashboardPage.prototype._createChartForCell):
892
893         * unit-tests/lazily-evaluated-function-tests.js: Added. Tests for LazilyEvaluatedFunction.
894
895 2017-03-01  Ryosuke Niwa  <rniwa@webkit.org>
896
897         Build fix after r212853. Make creating an analysis task work again.
898
899         * public/v3/pages/analysis-task-page.js:
900         (AnalysisTaskPage.prototype.render):
901
902 2017-02-27  Ryosuke Niwa  <rniwa@webkit.org>
903
904         Fix tests after r213119 and r213120.
905
906         * browser-tests/time-series-chart-tests.js:
907         (return.ChartTest.importChartScripts.context.then):
908         (string_appeared_here.then): Deleted.
909
910 2017-02-27  Ryosuke Niwa  <rniwa@webkit.org>
911
912         Removed the unused code that was supposed to be removed in the previous commit.
913
914         * browser-tests/time-series-chart-tests.js:
915
916 2017-02-27  Ryosuke Niwa  <rniwa@webkit.org>
917
918         Split tests for InteractiveTimeSeriesChart into a separate test file.
919         https://bugs.webkit.org/show_bug.cgi?id=168960
920
921         Reviewed by Joseph Pecoraro.
922
923         Extracted the test cases for InteractiveTimeSeriesChart charts from time-series-chart-tests.js
924         into interactive-time-series-chart-tests.js now that the former file has gotten really big over time.
925
926         Also extracted a bunch of helper functions time-series-chart-tests.js as ChartTest in index.html.
927         Any test which instantiates a time series chart can use this helper class.
928
929         * browser-tests/index.html:
930         (ChartTest.importChartScripts): Ditto.
931         (ChartTest.posixTime): Moved from time-series-chart-tests.js.
932         (ChartTest.sampleCluster): Ditto.
933         (ChartTest.createChartWithSampleCluster): Ditto.
934         (ChartTest.createInteractiveChartWithSampleCluster): Ditto.
935         (ChartTest.respondWithSampleCluster):
936         * browser-tests/interactive-time-series-chart-tests.js: Extracted from time-series-chart-tests.js.
937         * browser-tests/time-series-chart-tests.js:
938         (posixTime): Moved.
939         (dayInMilliseconds): Moved.
940         (sampleCluster): Moved.
941         (createChartWithSampleCluster): Moved.
942         (createInteractiveChartWithSampleCluster): Moved.
943         (respondWithSampleCluster): Moved.
944         * unit-tests/analysis-task-tests.js: Fixed a typo. s/adopter/adapter/.
945
946 2017-02-27  Ryosuke Niwa  <rniwa@webkit.org>
947
948         Calling build() on a baseline point results in an exception
949         https://bugs.webkit.org/show_bug.cgi?id=168959
950
951         Reviewed by Joseph Pecoraro.
952
953         Some baseline points may lack the build information. e.g. A custom data point made by an user.
954         Only instantiate Build object in a point object returned by MeasurementAdaptor when the builder id
955         is available so that we don't hit an assertion inside Build's constructor.
956
957         * public/v3/models/measurement-adaptor.js:
958         (MeasurementAdaptor.prototype.applyTo..build): Only instantiate Build when builderId is set.
959         * unit-tests/measurement-adaptor-tests.js: Added a test case.
960
961 2017-02-27  Ryosuke Niwa  <rniwa@webkit.org>
962
963         Arrow key shouldn't move the indicator beyond the visible points
964         https://bugs.webkit.org/show_bug.cgi?id=168956
965
966         Reviewed by Joseph Pecoraro.
967
968         The bug was caused by moveLockedIndicatorWithNotification using the full sampled time series view
969         instead of the one constrained by the domain. Since the time series chart expands the visible domain
970         to include at least one point before the start time and one point after the end tiem to draw lines
971         extending beyond the visible region (otherwise it looks as though the graph ends there), we need to
972         use a view constrained by the start time and the end time before looking for a next/previous point.
973
974         * browser-tests/time-series-chart-tests.js: Added test cases for moveLockedIndicatorWithNotification.
975         * public/v3/components/interactive-time-series-chart.js:
976         (InteractiveTimeSeriesChart.prototype.moveLockedIndicatorWithNotification): Fixed the bug. Also
977         enqueue itself to render instead of relying on a parent component to do it.
978
979 2017-02-27  Ryosuke Niwa  <rniwa@webkit.org>
980
981         A Locked indicator should be visually distinct from an unlocked indicator
982         https://bugs.webkit.org/show_bug.cgi?id=168868
983         <rdar://problem/29666054>
984
985         Reviewed by Antti Koivisto.
986
987         Added the support for specifying options.lockedIndicator in addition to options.indicator to style
988         an locked indicator differently from an unlocked one.
989
990         * browser-tests/time-series-chart-tests.js: Added new test cases for indicators.
991         (createChartWithSampleCluster): Renamed and swapped the order of arguments to better match
992         TimeSeriesChart's constructor. Now the second argument is an array of source as is in the constructor.
993         (createInteractiveChartWithSampleCluster): Added.
994
995         * public/v3/components/chart-styles.js:
996         (ChartStyles.overviewChartOptions): Changed the color of a selection to blue.
997         (ChartStyles.mainChartOptions): Ditto. Also use a different style for a locked indicator.
998
999         * public/v3/components/interactive-time-series-chart.js:
1000         (InteractiveTimeSeriesChart.prototype._layout): Removed the unused variable.
1001         (InteractiveTimeSeriesChart.prototype._renderChartContent): Use options.lockedIndicator when rendering
1002         a locked indicator. Also stroke the circle in addition to filling it so that we can use a blue circle
1003         with a white hole for a locked indicator to make it even more visually distinctive from an unlocked one.
1004
1005 2017-02-25  Dewei Zhu  <dewei_zhu@apple.com>
1006
1007         Commit should order by 'commit_order' as secondary key.
1008         https://bugs.webkit.org/show_bug.cgi?id=168866
1009
1010         Reviewed by Ryosuke Niwa.
1011
1012         Currently, commits are sorted by 'commit_time' only.
1013         We should use 'commit_order' as secondary key when 'commit_time' is equal or null.
1014
1015         * public/include/commit-log-fetcher.php:
1016         * public/include/db.php:
1017         * server-tests/api-commits.js:
1018         (return.addSlaveForReport.subversionCommits.then):
1019         (then):
1020
1021 2017-02-24  Ryosuke Niwa  <rniwa@webkit.org>
1022
1023         REGRESSION(r212853): Comparisons to baseline no longer shows up
1024         https://bugs.webkit.org/show_bug.cgi?id=168863
1025
1026         Reviewed by Joseph Pecoraro.
1027
1028         The bug was caused by ChartStatusView's code not being updated to use TimeSeriesView's.
1029         Updated the code to use TimeSeriesView's methods to fix the bug.
1030
1031         Also made InteractiveTimeSeriesChart's currentPoint to return a (TimeSeriesView, point, isLocked) tuple
1032         to consolidate it with lockedIndicator() to work towards making the baseline data points selectable.
1033
1034         * browser-tests/time-series-chart-tests.js: Updated the test cases to use currentIndicator, and added
1035         test cases for newly added lastPointInTimeRange.
1036
1037         * public/v3/components/chart-pane.js:
1038         (ChartPane.prototype.serializeState): Updated to use currentIndicator.
1039         (ChartPane.prototype._renderFilteringPopover): Ditto.
1040
1041         * public/v3/components/chart-status-view.js:
1042         (ChartStatusView.prototype.updateStatusIfNeeded): Use currentIndicator for an interative time series.
1043         Fixed the non-interactive chart's code path for TimeSeriesView.
1044         (ChartStatusView.prototype._computeChartStatus): Modernized the code.
1045         (ChartStatusView.prototype._findLastPointPriorToTime): Deleted. Replaced by TimeSeriesView's
1046         lastPointInTimeRange.
1047
1048         * public/v3/components/interactive-time-series-chart.js:
1049         (InteractiveTimeSeriesChart.prototype.currentIndicator):
1050         (InteractiveTimeSeriesChart.prototype.moveLockedIndicatorWithNotification):
1051         (InteractiveTimeSeriesChart.prototype._renderChartContent):
1052         (InteractiveTimeSeriesChart):
1053
1054         * public/v3/models/time-series.js:
1055         (TimeSeriesView.prototype.lastPointInTimeRange): Added.
1056         (TimeSeriesView.prototype._reverse): Added. Traverses the view in the reverse order.
1057         * unit-tests/time-series-tests.js:
1058
1059 2017-02-23  Dewei Zhu  <dewei_zhu@apple.com>
1060
1061         Rename 'commit_parent' in 'commits' table to 'commit_previous_commit'.
1062         https://bugs.webkit.org/show_bug.cgi?id=168816
1063
1064         Reviewed by Ryosuke Niwa.
1065
1066         Rename 'commit_parent' to avoid ambiguity in the coming feature.
1067         For exisiting database, run
1068             "ALTER TABLE commits RENAME commit_parent TO commit_previous_commit;"
1069         to update the database.
1070
1071         * init-database.sql:
1072         * public/api/report-commits.php:
1073         * public/include/commit-log-fetcher.php:
1074         * server-tests/api-commits.js:
1075         (then):
1076         * server-tests/api-report-commits-tests.js:
1077         (then):
1078         * tools/sync-commits.py:
1079         (main):
1080         (Repository.fetch_commits_and_submit):
1081         (GitRepository._revision_from_tokens):
1082         * unit-tests/analysis-task-tests.js:
1083         (sampleAnalysisTask):
1084
1085 2017-02-23  Ryosuke Niwa  <rniwa@webkit.org>
1086
1087         New sampling algorithm shows very few points when zoomed out
1088         https://bugs.webkit.org/show_bug.cgi?id=168813
1089
1090         Reviewed by Saam Barati.
1091
1092         When a chart is zoomed out to a large time interval, the new sampling algorithm introduced in r212853 can
1093         hide most of the data points because the difference between the preceding point's time and the succeeding
1094         point's time of most points will be below the threshold we computed.
1095
1096         Instead, rank each data point based on the aforementioned time interval difference, and pick the first M data
1097         points when M data points are to be shown.
1098
1099         This makes the new algorithm behave like our old algorithm while keeping it stable still. Note that this
1100         algorithm still biases data points without a close neighboring point but this seems to work out in practice
1101         because such a point tends to be an important sample anyway, and we don't have a lot of space between
1102         data points since we aim to show about one point per pixel.
1103
1104         * browser-tests/index.html:
1105         (CanvasTest.canvasContainsColor): Extracted from one of the test cases and generalized. Returns true when
1106         the specified region of the canvas contains a specified color (alpha is optional).
1107         * browser-tests/time-series-chart-tests.js: Added a test case for sampling. It checks that sampling happens
1108         and that we always show some data point even when zoomed out to a large time interval.
1109         (createChartWithSampleCluster):
1110
1111         * public/v3/components/interactive-time-series-chart.js:
1112         (InteractiveTimeSeriesChart.prototype._sampleTimeSeries):
1113         * public/v3/components/time-series-chart.js:
1114         (TimeSeriesChart.prototype._ensureSampledTimeSeries): M, the number of data points we pick must be computed
1115         based on the width of data points we're about to draw constrained by the canvas size. e.g. when the canvas
1116         is only half filled, we shouldn't be showing two points per pixel in the filled region.
1117         (TimeSeriesChart.prototype._sampleTimeSeries): Refined the algorithm. First, compute the time difference or
1118         the rank for each N data points. Sort those ranks in descending order (in the order we prefer), and include
1119         all data points above the M-th rank in the sample.
1120         (TimeSeriesChart.prototype.computeTimeGrid): Revert the inadvertent change in r212935.
1121
1122         * public/v3/models/time-series.js:
1123         (TimeSeriesView.prototype.filter): Fixed a bug that the indices passed onto the callback were shifted by the
1124         starting index.
1125         * unit-tests/time-series-tests.js: Added a test case to ensure callbacks are called with correct data points
1126         and indices.
1127
1128 2017-02-23  Ryosuke Niwa  <rniwa@webkit.org>
1129
1130         REGRESSION(r212542): Make TimeSeriesChart.computeTimeGrid stops x-axis grid prematurely
1131         https://bugs.webkit.org/show_bug.cgi?id=168812
1132
1133         Reviewed by Joseph Pecoraro.
1134
1135         Add time iterator of two months, three months, and four months with some tests.
1136
1137         Also for one-month time iterator, round the day of month to 1 or 15 whichever is closer.
1138
1139         * browser-tests/time-series-chart-tests.js: Added more tests.
1140         * public/v3/components/time-series-chart.js:
1141         (TimeSeriesChart._timeIterators.next):
1142         (TimeSeriesChart._timeIterators):
1143
1144 2017-02-22  Ryosuke Niwa  <rniwa@webkit.org>
1145
1146         Add tests for InteractiveTimeSeriesChart and adopt actions
1147         https://bugs.webkit.org/show_bug.cgi?id=168750
1148
1149         Reviewed by Chris Dumez.
1150
1151         Added tests for InteractiveTimeSeriesChart.
1152
1153         Also replaced selection.onchange, selection.onzoom, indicator.onchange, annotations.onclick callbacks
1154         by "selectionChange", "zoom", "indicatorChange", and "annotationClick" actions respectively.
1155
1156         Also fixed various bugs and bad code I encountered while writing these tests.
1157
1158         * browser-tests/index.html:
1159         (waitForComponentsToRender): Delay the call to enqueueToRender until the next run loop because there
1160         might be outstanding promises that just got resolved. e.g. for fetching measurement sets JSONs. Let
1161         all those promises get resolved first. Otherwise, some tests become racy.
1162         (canvasImageData): Extracted from time-series-chart-tests.js.
1163         (canvasRefTest): Ditto.
1164         (CanvasTest): Ditto.
1165         (CanvasTest.fillCanvasBeforeRedrawCheck): Ditto.
1166         (CanvasTest.hasCanvasBeenRedrawn): Ditto.
1167         (CanvasTest.canvasImageData): Ditto.
1168         (CanvasTest.expectCanvasesMatch): Ditto.
1169         (CanvasTest.expectCanvasesMismatch): Ditto.
1170
1171         * browser-tests/time-series-chart-tests.js: Fixed some test cases where dpr multipler was not doing
1172         the right thing anymore in Safari under a high DPI screen. Also added a lot of test cases for interactive
1173         time series chart and one for rendering annotations.
1174         (scripts): Moved.
1175         (posixTime): Added. A helper function for sampleCluster.
1176         (dayInMilliseconds): Ditto.
1177         (sampleCluster): Moved here. Made the same cluster more artifical for an easier testing.
1178         (createChartWithSampleCluster): Moved out of one of the tests.
1179         (respondWithSampleCluster): Ditto.
1180
1181         * public/v3/components/chart-pane-base.js:
1182         (ChartPaneBase.prototype.configure): Adopted new actions in InteractiveTimeSeriesChart.
1183
1184         * public/v3/components/chart-status-view.js:
1185         (ChartStatusView.prototype.updateStatusIfNeeded): Removed a superflous console.log.
1186
1187         * public/v3/components/chart-styles.js:
1188         (ChartStyles.mainChartOptions): Set zoomButton to true. InteractiveTimeSeriesChart used to determine
1189         whether to show the zoom button or not based on the precense of the zoom callback. We made it explicit.
1190
1191         * public/v3/components/interactive-time-series-chart.js:
1192         (InteractiveTimeSeriesChart.prototype.setIndicator): Explicitly call _notifySelectionChanged with false
1193         instead of relying on undefined to be treated as falsey.
1194         (InteractiveTimeSeriesChart.prototype._createCanvas): Use id instead of selector to find elements.
1195         (InteractiveTimeSeriesChart.htmlTemplate):
1196         (InteractiveTimeSeriesChart.cssTemplate):
1197         (InteractiveTimeSeriesChart.prototype._mouseMove): Explicitly call _startOrContinueDragging with false
1198         instead of relying on undefined treated as falsey. Also added the missing call to enqueueToRender found
1199         by new tests. This was working fine on the dashboard due to other components invoking enqueueToRender
1200         but won't work in a standalone instance of InteractiveTimeSeriesChart.
1201         (InteractiveTimeSeriesChart.prototype._mouseLeave): Ditto, adding the missing call to enqueueToRender.
1202         (InteractiveTimeSeriesChart.prototype._click): Removed the assignment to _forceRender when calling
1203         _mouseMove in an early exist, which does set this flag and invokes enqueueToRender, and added the missing
1204         call to enqueueToRender in the other code path.
1205         (InteractiveTimeSeriesChart.prototype._startOrContinueDragging): Replaced annotations.onclick callback
1206         by the newly added "annotationClick" action, and added the missing call to enqueueToRender.
1207         (InteractiveTimeSeriesChart.prototype._endDragging): Use arrow function.
1208         (InteractiveTimeSeriesChart.prototype._notifyIndicatorChanged): Replaced indicator.onchange callback by
1209         the newly added "indicatorChange" action.
1210         (InteractiveTimeSeriesChart.prototype._notifySelectionChanged): Replaced selection.onchange callback by
1211         the newly added "selectionChange" action.
1212         (InteractiveTimeSeriesChart.prototype._renderChartContent): Show the zoom button when options.zoomButton
1213         is set instead of relying on the presence of selection.onzoom especially now that the callback has been
1214         replaced by the "zoom" action.
1215
1216         * public/v3/components/time-series-chart.js:
1217         (TimeSeriesChart.prototype.setAnnotations): Added the missing call to enqueueToRender.
1218
1219         * public/v3/main.js:
1220
1221 2017-02-21  Ryosuke Niwa  <rniwa@webkit.org>
1222
1223         Make sampling algorithm more stable and introduce an abstraction for sampled data
1224         https://bugs.webkit.org/show_bug.cgi?id=168693
1225
1226         Reviewed by Chris Dumez.
1227
1228         Before this patch, TimeSeriesChart's resampling resulted in some points poping up and disappearing as
1229         the width of a chart is changed. e.g. when resizing the browser window. The bug was by caused by
1230         the sample for a given width not always including all points for a smaller width so as the width is
1231         expanded, some point may be dropped.
1232
1233         Fixed this by using a much simpler algorithm of always picking a point when the time interval between
1234         the preceding point and the succeeding point is larger than the minimum space we allow for a given width.
1235
1236         Also introduced a new abstraction around the sample data: TimeSeriesView. A TimeSeriesView provides
1237         a similar API to TimeSeries for a subset of the time series filtered by a time range a custom function.
1238         This paves a way to adding the ability to select baseline, etc... on the chart status view.
1239
1240         TimeSeriesView can be in two modes:
1241         Mode 1. The view represents a contiguous subrange of TimeSeries - In this mode, this._data references
1242                 the underlying TimeSeries's _data directly, and we use _startingIndex to adjust index given to
1243                 find the relative index. Finding the next point or the previous point of a given point is done
1244                 via looking up the point's seriesIndex and doing a simple arithmetic. In general, an index is
1245                 converted to the absolute index in the underlying TimeSeries's _data array.
1246
1247         Mode 2. The view represents a filtered non-contiguous subset of TimeSeries -  In this mode, this._data is
1248                 its own array. Finding the next point or the previous point of a given point requires finding
1249                 a sibling point in the underlying TimeSeries which is in this view. Since this may result in O(n)
1250                 traversal and a hash lookup, we lazily build a map of each point to its position in _data instead.
1251
1252         * public/v3/components/chart-status-view.js:
1253         (ChartStatusView.prototype.updateStatusIfNeeded): Call selectedPoints instead of sampledDataBetween for
1254         clarity. This function now returns a TimeSeriesView instead of a raw array.
1255
1256         * public/v3/components/interactive-time-series-chart.js:
1257         (InteractiveTimeSeriesChart.prototype.currentPoint): Updated now that _sampledTimeSeriesData contains
1258         an array of TimeSeriesView's. Note that diff is either 0, -1, or 1.
1259         (InteractiveTimeSeriesChart.prototype.selectedPoints): Ditto. sampledDataBetween no longer exists since
1260         we can simply call viewTimeRange on TimeSeriesView returned by sampledDataBetween.
1261         (InteractiveTimeSeriesChart.prototype.firstSelectedPoint): Ditto.
1262         (InteractiveTimeSeriesChart.prototype._sampleTimeSeries): Use add since excludedPoints is now a Set.
1263
1264         * public/v3/components/time-series-chart.js:
1265         (TimeSeriesChart.prototype.sampledDataBetween): Deleted.
1266         (TimeSeriesChart.prototype.firstSampledPointBetweenTime): Deleted.
1267         (TimeSeriesChart.prototype._ensureSampledTimeSeries): Modernized the code. Use the the time interval of
1268         the chart divided by the number of allowed points as the time interval used in the new sampling algorithm.
1269         (TimeSeriesChart.prototype._sampleTimeSeries): Rewritten. We also create TimeSeriesView here.
1270         (TimeSeriesChart.prototype._sampleTimeSeries.findMedian): Deleted.
1271         (TimeSeriesChart.prototype._updateCanvasSizeIfClientSizeChanged): Fixed a bug that the canvas size wasn't
1272         set to the correct value on Chrome when a high DPI screen is used.
1273
1274         * public/v3/models/time-series.js:
1275         (TimeSeries.prototype.viewBetweenPoints): Renamed from dataBetweenPoints. Now returns a TimeSeriesView.
1276         (TimeSeriesView): Added. This constructor is to be called by viewBetweenPoints, viewTimeRange, and filter.
1277         (TimeSeriesView.prototype._buildPointIndexMap): Added. Used in mode (2).
1278         (TimeSeriesView.prototype.length): Added.
1279         (TimeSeriesView.prototype.firstPoint): Added.
1280         (TimeSeriesView.prototype.lastPoint): Added.
1281         (TimeSeriesView.prototype.nextPoint): Added. Note index is always a position in this._data. In mode (1),
1282         this is the position of the point in the underlying TimeSeries' _data. In mode (2), this is the position
1283         of the point in this._data which is dictinct from the underlying TimeSeries' _data.
1284         (TimeSeriesView.prototype.previousPoint): Ditto.
1285         (TimeSeriesView.prototype.findPointByIndex): Added. Finds the point using the positional index from the
1286         beginning of this view. findPointByIndex(0) on one view may not be same as findPointByIndex(0) of another.
1287         (TimeSeriesView.prototype.findById): Added. This is O(n).
1288         (TimeSeriesView.prototype.values): Added. Returns the value of each point in this view.
1289         (TimeSeriesView.prototype.filter): Added. Creates a new view with a subset of data points the predicate
1290         function returned true.
1291         (TimeSeriesView.prototype.viewTimeRange): Added. Creates a new view with a subset of data points for the
1292         given time ragne. When the resultant view would include all points of this view, it simply returns itself
1293         as an optimization.
1294         (TimeSeriesView.prototype.firstPointInTimeRange): Added. Returns the first point in the view which lies
1295         within the specified time range.
1296         (TimeSeriesView.prototype.Symbol.iterator): Added. Iterates over each point in the view.
1297
1298         * public/v3/pages/analysis-task-page.js:
1299         (AnalysisTaskChartPane.prototype.selectedPoints): Use selectedPoints in lieu of getting selection and then
1300         calling sampledDataBetween with that range.
1301
1302         * public/v3/pages/summary-page.js:
1303         (SummaryPageConfigurationGroup.set _medianForTimeRange): Modernized.
1304
1305         * unit-tests/time-series-tests.js: Added tests for TimeSeries and TimeSeriesView. Already caught bugs!
1306         (addPointsToSeries):
1307
1308 2017-02-17  Ryosuke Niwa  <rniwa@webkit.org>
1309
1310         Add tests for the time series chart and fix bugs I found along the way
1311         https://bugs.webkit.org/show_bug.cgi?id=168499
1312
1313         Reviewed by Antti Koivisto.
1314
1315         Add basic tests for the time series chart.
1316
1317         Replaced the "ondata" callback set in the options by "dataChange" action now that ComponentBase provides
1318         a facility for defining event-like actions.
1319
1320         Also fixed bugs I encountered while writing these tests see below for descriptions.
1321
1322         * browser-tests/editable-text-tests.js:
1323         (waitToRender): Moved to index.html
1324         * browser-tests/index.html:
1325         (waitToRender): Moved from editable-text-tests.js.
1326         (wait): Added.
1327         * browser-tests/time-series-chart-tests.js: Added.
1328         * public/v3/components/chart-pane-base.js:
1329         (ChartPaneBase.prototype.configure):
1330         * public/v3/components/time-series-chart.js:
1331         (TimeSeriesChart): Removed the code to set display and position inline properties. This is now done inside
1332         cssTemplate with :host pseudo class.
1333         (TimeSeriesChart.prototype._ensureCanvas): Don't strech the canvas to 100% of width and height. This was
1334         causing a flush of contents where the canvas is momentarily streched by the browser and the script later
1335         updates with the content with the correct aspect ratio.
1336         (TimeSeriesChart.cssTemplate): Added :host rule to set display: block and position: relative.
1337         (TimeSeriesChart._updateAllCharts): Deleted.
1338         (TimeSeriesChart.prototype.render): Only run the code for axis when options.axis is defined. Also, avoid
1339         setting the fill style because we never fill for axis drawing.
1340         (TimeSeriesChart.prototype._computeHorizontalRenderingMetrics): Ditto. Fallback to sensible values when
1341         options.axis is not defined.
1342         (TimeSeriesChart.prototype._renderYAxis): Now computeValueGrid generates a sequence of {time, label}.
1343         (TimeSeriesChart.prototype._renderTimeSeries): Don't draw the shades for confidence intervals unless its
1344         fill style is defined. Otherwise, we'd end up drawing black shade and mask the actual data points.
1345         (TimeSeriesChart.prototype._ensureSampledTimeSeries): Dispatch newly added "dataChange" action instead of
1346         calling "ondata" callback in options dictionary.
1347         (TimeSeriesChart.computeTimeGrid): Modernized to use const/let. Also fixed the bug that we were emitting
1348         the date even when the entire time range fit within a 24-hour interval.
1349         (TimeSeriesChart.computeValueGrid): Rewritten to make MB/GB use a nice round number instead of 0.98GB.
1350         We were using a power of 10 to round up the stepping value but the value formatter used a power of 1024
1351         to divide byte measurements (e.g. for memory). Use formatter.divisor to find the right scaling factor for
1352         each kind.
1353         * public/v3/models/metric.js:
1354         (Metric.prototype.makeFormatter):
1355         (Metric.makeFormatter): Extracted from the one on the prototype so that tests don't need a metric object
1356         just to test TimeSeriesChart. Added the second argument which specifies the maximum absolute value of the
1357         range we're formatting. This is needed to use the same number of decimal points when the most significant
1358         digit of some value is smaller than that of the biggest one. For example, we were emitting 0.50GB instead
1359         of 0.5G along with 2.0GB. The "adjustment" reduces the number of significant figures in these cases.
1360         * public/v3/pages/dashboard-page.js:
1361         (DashboardPage.prototype._createChartForCell):
1362
1363 2017-02-16  Ryosuke Niwa  <rniwa@webkit.org>
1364
1365         Use expect.js instead of expect in browser tests
1366         https://bugs.webkit.org/show_bug.cgi?id=168492
1367
1368         Reviewed by Joseph Pecoraro.
1369
1370         Use expect.js (https://github.com/Automattic/expect.js) instead of expect (https://github.com/mjackson/expect).
1371
1372         * browser-tests/close-button-tests.js:
1373         * browser-tests/component-base-tests.js:
1374         * browser-tests/editable-text-tests.js:
1375         * browser-tests/index.html:
1376
1377 2017-02-16  Ryosuke Niwa  <rniwa@webkit.org>
1378
1379         Modernize and fix measurement-set tests
1380         https://bugs.webkit.org/show_bug.cgi?id=168484
1381
1382         Reviewed by Joseph Pecoraro.
1383
1384         Modernized and fixed the tests in measurement-set-tests.js.
1385
1386         1. Return a promise instead of manually calling done in then/catch hanlders.
1387         2. Use arrow function everywhere.
1388         3. Explicitly assert the number of calls to callbacks instead of asserting never reached.
1389
1390         The test case labled "should return false when the range ends after the fetched cluster"
1391         was incorrectly asserting that hasFetchedRange returns false when the end time is after
1392         the primary cluster's end time. Test an interval before the primary cluster instead.
1393
1394         Added a test case for hasFetchedRange returning true when the end time appears after
1395         the end of the primary cluster and fixed hasFetchedRange to that end. Since there are
1396         no data points after the primary cluster which is chronologically the last cluster,
1397         there is nothing to fetch beyond its end time.
1398
1399         * public/v3/models/measurement-set.js:
1400         (MeasurementSet.prototype.hasFetchedRange): Fixed the bug that this function returned
1401         false when the end time was after the primary cluster's end by truncating the range by
1402         the end of the primary cluster.
1403         * unit-tests/measurement-set-tests.js:
1404         * unit-tests/resources/mock-remote-api.js:
1405         (assert.notReached.assert.notReached): Deleted. It's no longer used by any tests.
1406
1407 2017-02-15  Ryosuke Niwa  <rniwa@webkit.org>
1408
1409         Update ReadMe.md and merge it with Install.md
1410         https://bugs.webkit.org/show_bug.cgi?id=168405
1411
1412         Reviewed by Michael Catanzaro.
1413
1414         Merged Install.md and ReadMe.md into one file.
1415
1416         * Install.md: Removed.
1417         * ReadMe.md: Merged Install.md at the top and updated the rest of the content.
1418
1419 2017-01-24  Ryosuke Niwa  <rniwa@webkit.org>
1420
1421         Modernize editable-text component and add tests
1422         https://bugs.webkit.org/show_bug.cgi?id=167398
1423
1424         Reviewed by Yusuke Suzuki.
1425
1426         Modernized EditableText component to use the action feature added in r210938.
1427
1428         * browser-tests/editable-text-tests.js: Added. Added tests for EditableText component.
1429         (.waitToRender):
1430         * browser-tests/index.html:
1431         * public/v3/components/base.js:
1432         (ComponentBase.prototype.dispatchAction): Return the result from the callback.
1433         * public/v3/components/editable-text.js:
1434         (EditableText): Removed a bunch of instance variables that are no longer needed.
1435         (EditableText.prototype.didConstructShadowTree): Added. Add event listeners on the Edit/Save button and the host.
1436         (EditableText.prototype.editedText): Return the text field's value directly.
1437         (EditableText.prototype.text): Added.
1438         (EditableText.prototype.setText): Call enqueueToRender automatically instead of relying on the parent component
1439         to do so in _startedEditingCallback, which has been removed.
1440         (EditableText.prototype.render): Modernized the code.
1441         (EditableText.prototype._didClick): No longer prevents the default action manually since that's automatically done
1442         in createEventHandler. Handle the case where the update action is not handled.
1443         (EditableText.prototype._endEditingMode): Renamed from _didUpdate.
1444         (EditableText.htmlTemplate): Added ids on various elements in the shadow tree.
1445         (EditableText.cssTemplate): Updated the CSS selectors per above change.
1446         * public/v3/main.js:
1447         (main): Fixed a typo.
1448         * public/v3/pages/analysis-task-page.js:
1449         (AnalysisTaskPage): Use the action listener instead of manually setting callbacks.
1450         (AnalysisTaskPage.prototype._createTestGroupListItem): Ditto.
1451         (AnalysisTaskPage.prototype._didStartEditingTaskName): Deleted.
1452
1453 2017-01-20  Ryosuke Niwa  <rniwa@webkit.org>
1454
1455         Build fix after r210783. Didn't mean to require custom elements API.
1456
1457         * public/v3/main.js:
1458         (main):
1459
1460 2017-01-20  Ryosuke Niwa  <rniwa@webkit.org>
1461
1462         Make sync-commits.py robust against missing Subversion authors and missing parent Git commits
1463         https://bugs.webkit.org/show_bug.cgi?id=167231
1464
1465         Reviewed by Antti Koivisto.
1466
1467         Fixed a bug that a subversion commit that's missing author name (anonymous commit) results in an out of bound
1468         exception, and a bug that syncing a git repository starts failing once there was a merge commit which pulled
1469         in a commit data earlier than that of the last reported commit.
1470
1471         For the latter fix, added --max-ancestor-fetch-count to specify the number of maximum commits to look back.
1472
1473         * tools/sync-commits.py:
1474         (main): Added --max-ancestor-fetch-count.
1475         (Repository.fetch_commits_and_submit): If submit_commits fails with FailedToFindParentCommit, fetch the parent
1476         commit's information until we've resolved them all.
1477         (Repository.fetch_next_commit): Renamed from fetch_commit.
1478         (SVNRepository.fetch_next_commit): Renamed from fetch_commit. Don't try to get the author name if it's missing
1479         due to an anonymous commit. It's important to never include the "author" field in the JSON submitted to
1480         a dashboard since it rejects when "author" field is not an array (e.g. null). 
1481         (GitRepository.fetch_next_commit): Renamed from fetch_commit.
1482         (GitRepository.fetch_commit): Added. Fetches the commit information for a given git hash. Used to retrieve
1483         missing parent commits.
1484         (GitRepository._revision_from_tokens): Extracted from fetch_commit.
1485
1486         * tools/util.py:
1487         (submit_commits): Optionally takes status_to_accept to avoid throwing in the case of FailedToFindParentCommit
1488         and returns the response JSON.
1489
1490 2017-01-20  Ryosuke Niwa  <rniwa@webkit.org>
1491
1492         REGRESSION(r198234): /api/commits/%revision% always fails
1493         https://bugs.webkit.org/show_bug.cgi?id=167235
1494
1495         Reviewed by Antti Koivisto.
1496
1497         The bug was caused by a typo in CommitLogFetcher::fetch_revision, which was calling commit_for_revision on
1498         $this->db instead of $this. This had been monkey-patched in the internal dashboard so it was working there.
1499
1500         Also fixed a bug that /latest wasn't doing what it claimed to do, and a bug that /oldest /latest,
1501         and /last-reported would return a commit with all values set to null instead of an empty list.
1502
1503         Finally, added server API tests for /api/commits.
1504
1505         * public/api/commits.php:
1506         (main): Add a comment for APIs that only exist for v2 UI.
1507
1508         * public/include/commit-log-fetcher.php:
1509         (CommitLogFetcher::fetch_latest): Fixed the bug that this function was returning the oldest commit, not the
1510         the latest commit as desired.
1511         (CommitLogFetcher::fetch_revision): Fixed the bug that this function would always encounter an exception
1512         because commit_for_revision is defined on $this, not $this->db.
1513         (CommitLogFetcher::format_single_commit): Return an empty list instead of an array with a single commit with
1514         all values set to null.
1515
1516         * server-tests/api-commits.js: Added. Added tests for the JSON API at /api/commits.
1517         (.assertCommitIsSameAsOneSubmitted): Added. A helper function to compare a commit returned by /api/commits
1518         to one sent to /api/report-commits.
1519
1520 2017-01-19  Ryosuke Niwa  <rniwa@webkit.org>
1521
1522         measurement-sets API can incorrectly order points with OS version without commit time
1523         https://bugs.webkit.org/show_bug.cgi?id=167227
1524
1525         Reviewed by Chris Dumez.
1526
1527         Ignore revision_order for the purpose of ordering data points in /api/measurement-sets.
1528
1529         These orderings are used in some UI (e.g A/B testing) to order OS build numbers which do not have a timestamp
1530         associated with each "revision".
1531
1532         The baseline measurements made in our internal dashboard were using these ordering numbers before ordering
1533         results with build time. Because those data points don't have an associated Webkit revisions, all data points
1534         were ordered first by macOS's revision_order, then build time. Because v3 UI completely ignores revision_order
1535         for the purpose of plotting data points, this resulted in some data points being plotted in a wrong order
1536         with some lines going backwards in time.
1537
1538         This patch addresses this discrepancy by stop ordering data points with revision_order in the JSON API.
1539
1540         * public/api/measurement-set.php:
1541         (MeasurementSetFetcher::execute_query): Fixed the bug.
1542         * server-tests/api-measurement-set-tests.js: Added a test.
1543
1544 2017-01-19  Ryosuke Niwa  <rniwa@webkit.org>
1545
1546         Build fix after r210626. We need to clear Triggerable's static map in each iteration.
1547
1548         * tools/sync-buildbot.js:
1549         (syncLoop):
1550
1551 2017-01-18  Ryosuke Niwa  <rniwa@webkit.org>
1552
1553         Add a mechanism to dispatch and listen to an action
1554         https://bugs.webkit.org/show_bug.cgi?id=167191
1555
1556         Reviewed by Antti Koivisto.
1557
1558         Added the notion of an action to components. Like DOM events, it can be dispatched or listen to.
1559
1560         Also added ComponentBase.prototype.part which finds a sub-component inside a component's shadow tree,
1561         and made ComponentBase.prototype.content take an id to find an element that matches it.
1562
1563         * browser-tests/close-button-tests.js: Added. Tests for CloseButton.
1564         * browser-tests/component-base-tests.js: Added tests for ComponentBase's part(~), content(id), dispatchEvent.
1565         * browser-tests/index.html:
1566         * public/v3/components/base.js:
1567         (ComponentBase): Added this._actionCallbacks, which is a map of an action name to a callback to be invoked.
1568         (ComponentBase.prototype.content): Return an element of the given id if one is specified.
1569         (ComponentBase.prototype.part): Find a component whose element has the matching id.
1570         (ComponentBase.prototype.dispatchAction): Added.
1571         (ComponentBase.prototype.listenToAction): Added.
1572         (ComponentBase.prototype._ensureShadowTree): Call didConstructShadowTree.
1573         (ComponentBase.prototype.didConstructShadowTree): Added.
1574         (ComponentBase.prototype._recursivelyReplaceUnknownElementsByComponents): Copy attributes when instantiating
1575         an element for a component when the browser doesn't support custom elements API.
1576         (ComponentBase.createLink):
1577         (ComponentBase.prototype.createEventHandler): Added.
1578         (ComponentBase.createEventHandler): Renamed from createActionHandler.
1579         * public/v3/components/button-base.js:
1580         (ButtonBase.prototype.didConstructShadowTree): Added. Dispatch "activate" action when the button is clicked.
1581         (ButtonBase.prototype.setCallback): Deleted.
1582         (ButtonBase.htmlTemplate): Use id instead of class so that this.content() can find it.
1583         (ButtonBase.cssTemplate): Updated style rules.
1584         * public/v3/pages/chart-pane.js:
1585         (ChartPane):
1586         (ChartPane.prototype.didConstructShadowTree): Added. Listen to "activate" action on the close button.
1587         (ChartPane.prototype.render): Fixed a bug that we were never calling enqueueToRender on the close button.
1588         (ChartPane.htmlTemplate): Add the id on the close button.
1589
1590 2017-01-18  Dewei Zhu  <dewei_zhu@apple.com>
1591
1592         'buildbot-syncer.js' should be able to determine force build argument from a list of possible repositories.
1593         https://bugs.webkit.org/show_bug.cgi?id=167152
1594
1595         Reviewed by Ryosuke Niwa.
1596
1597         Add 'rootOptions' key which maps to a list of possible repositories.
1598         For a build request, only one of the repositories in the list is valid.
1599
1600         * tools/js/buildbot-syncer.js:
1601         (BuildbotSyncer.prototype._propertiesForBuildRequest):
1602         (BuildbotSyncer._validateAndMergeProperties):
1603         (BuildbotSyncer):
1604         * unit-tests/buildbot-syncer-tests.js:
1605         (sampleiOSConfig):
1606         (sampleiOSConfigWithExpansions):
1607         (createSampleBuildRequest):
1608         (Promise.resolve.then):
1609         * unit-tests/resources/mock-v3-models.js:
1610         (MockModels.inject):
1611
1612 2017-01-17  Ryosuke Niwa  <rniwa@webkit.org>
1613
1614         Make calls to render() functions async
1615         https://bugs.webkit.org/show_bug.cgi?id=167151
1616
1617         Reviewed by Andreas Kling.
1618
1619         Make calls to render() async by coalescing calls inside enqueueToRender(), which has been renamed from
1620         updateRendering(). We now queue up all the components and wait until the next animation frame to invoke
1621         render() on all those components.
1622
1623         This reduces render() calls in the summary page of our internal dashboard by 15x from ~9400 to ~600 by
1624         eliminating pathological O(n^2) behavior between render() calls.
1625
1626         Consolidated TimeSeriesChart's enqueueRender into this newly added feature of ComponentBase along with
1627         the support to call render() on a resize event. New implementation makes use of connectedCallback and
1628         disconnectedCallback to avoid the work when the component is not in a document tree.
1629
1630         The rest of the patch concerns with renaming updateRendering to enqueueToRender and fixing a few minor bugs
1631         that I encountered while working on this patch.
1632
1633         * browser-tests/component-base-tests.js: Added tests for ComponentBase.enqueueToRender().
1634         * browser-tests/index.html:
1635         (BrowserContext.prototype.importScripts): Renamed from importScript; Now supports loading multiple scripts.
1636         (BrowserContext.prototype.importScript): Added.
1637         (BrowserContext): Removed the unused createWithScripts.
1638
1639         * public/v3/components/analysis-results-viewer.js:
1640         (AnalysisResultsViewer.prototype._expandBetween):
1641         * public/v3/components/bar-graph-group.js:
1642         (BarGraphGroup.prototype.updateGroupRendering):
1643
1644         * public/v3/components/base.js:
1645         (ComponentBase): When the browser doesn't support custom elements and 
1646         (ComponentBase.prototype.enqueueToRender): Renamed from updateRendering. Queues up the component to call
1647         render() instead of immediately invoking it.
1648         (ComponentBase.renderingTimerDidFire): Call render(). Since render() function often calls enqueueToRender
1649         on child components, go ahead and invoke render() on any components enqueued during render() calls.
1650         (ComponentBase._connectedComponentToRenderOnResize): Added.
1651         (ComponentBase._disconnectedComponentToRenderOnResize): Added.
1652         (ComponentBase.defineElement.elementClass.prototype.connectedCallback): Added. This is an optimization to
1653         avoid the work when the component is not in the document; e.g. because the entire page component has been
1654         detached from the document. The old implementation in TimeSeriesChart was not doing this.
1655         (ComponentBase.defineElement.elementClass.prototype.disconnectedCallback): Added.
1656         (ComponentBase): Replaced unused static variables with _componentsToRender and _componentsToRenderOnResize.
1657
1658         * public/v3/components/chart-pane-base.js:
1659         (ChartPaneBase.prototype.fetchAnalysisTasks):
1660         (ChartPaneBase.prototype.didUpdateAnnotations): Added. Addresses the bug that the annotation bars in the
1661         charts shown an an analysis task doesn't update its color when the state is updated in the UI. 
1662         (ChartPaneBase.prototype._mainSelectionDidZoom):
1663         (ChartPaneBase.prototype._updateStatus):
1664         (ChartPaneBase.prototype._requestOpeningCommitViewer):
1665         (ChartPaneBase.prototype._keyup):
1666         (ChartPaneBase.prototype.render):
1667         * public/v3/components/commit-log-viewer.js:
1668         * public/v3/components/customizable-test-group-form.js:
1669         (CustomizableTestGroupForm):
1670         (CustomizableTestGroupForm.prototype._customize):
1671         * public/v3/components/editable-text.js:
1672         (EditableText.prototype._didUpdate):
1673         * public/v3/components/interactive-time-series-chart.js:
1674         * public/v3/components/pane-selector.js:
1675         (PaneSelector.prototype._selectedItem):
1676         * public/v3/components/time-series-chart.js:
1677         (TimeSeriesChart): Removed the logic to update upon resize. See _connectedComponentToRenderOnResize above.
1678         (TimeSeriesChart.prototype.get enqueueToRenderOnResize): Added. Returns true.
1679         (TimeSeriesChart.prototype.enqueueToRender): Deleted.
1680         (TimeSeriesChart._renderEnqueuedCharts): Deleted.
1681         (TimeSeriesChart): Call ComponentBase.defineElement to make this a proper component so that the logic in
1682         connectedCallback to update upon resize event would work.
1683         * public/v3/instrumentation.js:
1684         (Instrumentation.dumpStatistics): Sort results by the key names.
1685         * public/v3/models/time-series.js:
1686         (TimeSeries.prototype.values): Added. This method was never ported to v3 in r198462, and broke the feature
1687         to show moving averages, etc... on the charts page.
1688         * public/v3/pages/analysis-category-page.js:
1689         (AnalysisCategoryPage.prototype.open):
1690         (AnalysisCategoryPage.prototype.updateFromSerializedState):
1691         (AnalysisCategoryPage.prototype.filterDidChange):
1692         (AnalysisCategoryPage.prototype.render):
1693         * public/v3/pages/analysis-task-page.js:
1694         (AnalysisTaskChartPane.prototype._updateStatus):
1695         (AnalysisTaskPage.prototype.updateFromSerializedState):
1696         (AnalysisTaskPage.prototype._didFetchTask):
1697         (AnalysisTaskPage.prototype._didFetchRelatedAnalysisTasks):
1698         (AnalysisTaskPage.prototype._didFetchMeasurement):
1699         (AnalysisTaskPage.prototype._didFetchTestGroups):
1700         (AnalysisTaskPage.prototype._showAllTestGroups):
1701         (AnalysisTaskPage.prototype._didFetchAnalysisResults):
1702         (AnalysisTaskPage.prototype.render):
1703         (AnalysisTaskPage.prototype._renderTestGroupList.):
1704         (AnalysisTaskPage.prototype._renderTestGroupList):
1705         (AnalysisTaskPage.prototype._createTestGroupListItem):
1706         (AnalysisTaskPage.prototype._showTestGroup):
1707         (AnalysisTaskPage.prototype._didStartEditingTaskName):
1708         (AnalysisTaskPage.prototype._updateTaskName):
1709         (AnalysisTaskPage.prototype._updateTestGroupName):
1710         (AnalysisTaskPage.prototype._hideCurrentTestGroup):
1711         (AnalysisTaskPage.prototype._updateChangeType): Fixed the bug that we were never updating annotation bars
1712         in the main chart by calling didUpdateAnnotations.
1713         (AnalysisTaskPage.prototype._associateBug):
1714         (AnalysisTaskPage.prototype._dissociateBug):
1715         (AnalysisTaskPage.prototype._associateCommit):
1716         (AnalysisTaskPage.prototype._dissociateCommit):
1717         (AnalysisTaskPage.prototype._chartSelectionDidChange):
1718         (AnalysisTaskPage.prototype._selectedRowInAnalysisResultsViewer):
1719         * public/v3/pages/build-request-queue-page.js:
1720         (BuildRequestQueuePage.prototype.open.):
1721         (BuildRequestQueuePage.prototype.open):
1722         * public/v3/pages/chart-pane.js:
1723         (ChartPane.prototype.setOpenRepository):
1724         (ChartPane.prototype._renderTrendLinePopover): Fixed a race condition. Insert a select element as needed
1725         before trying to assign the current value on it.
1726         (ChartPane.prototype._trendLineTypeDidChange):
1727         (ChartPane.prototype._updateTrendLine):
1728         * public/v3/pages/charts-page.js:
1729         (ChartsPage.prototype.updateFromSerializedState):
1730         (ChartsPage.prototype._updateDomainsFromSerializedState):
1731         (ChartsPage.prototype.setNumberOfDaysFromToolbar):
1732         (ChartsPage.prototype._didMutatePaneList):
1733         (ChartsPage.prototype.render):
1734         * public/v3/pages/charts-toolbar.js:
1735         (ChartsToolbar.prototype.render):
1736         * public/v3/pages/create-analysis-task-page.js:
1737         (CreateAnalysisTaskPage.prototype.updateFromSerializedState):
1738         * public/v3/pages/dashboard-page.js:
1739         (DashboardPage.prototype.updateFromSerializedState):
1740         (DashboardPage.prototype._fetchedData):
1741         * public/v3/pages/heading.js:
1742         (Heading.prototype.render):
1743         * public/v3/pages/page-with-heading.js:
1744         (PageWithHeading.prototype.render):
1745         * public/v3/pages/page.js:
1746         (Page.prototype.open):
1747         * public/v3/pages/summary-page.js:
1748         (SummaryPage.prototype.open):
1749         (SummaryPage.prototype.this._renderQueue.push):
1750         (SummaryPage):
1751         (SummaryPage.prototype._renderCell):
1752
1753 2017-01-15  Ryosuke Niwa  <rniwa@webkit.org>
1754
1755         Add the build fix for browsers that don't yet support custom elements SPI.
1756         It was supposedly to be a part of the previous commit.
1757
1758         * public/v3/components/base.js:
1759         (ComponentBase.defineElement):
1760
1761 2017-01-12  Ryosuke Niwa  <rniwa@webkit.org>
1762
1763         Adopt custom elements API in perf dashboard
1764         https://bugs.webkit.org/show_bug.cgi?id=167045
1765
1766         Reviewed by Darin Adler.
1767
1768         Adopt custom elements API in ComponentBase, and create the shadow tree lazily in content() and render()
1769         instead of eagerly creating it inside the constructor.
1770
1771         For now, create a separate element class for each component in ComponentBase.defineElement instead of
1772         making ComponentBase inherit from HTMLElement to preserve the semantics we have as well as to test
1773         the boundaries of what custom elements API allows for framework authors.
1774
1775         In order to ensure one-to-one correspondence between elements and their components, we use a static map,
1776         ComponentBase._currentlyConstructedByInterface, to remember which element or component is being created
1777         and use that in custom element's constructor to update element.component() and this._element.
1778
1779         Also dropped the support for not having attachShadow as we've shipped this feature in Safari 10.
1780
1781         Finally, added tests to be ran inside a browser to test the front end code in browser-tests.
1782
1783         * browser-tests/component-base-tests.js: Added. Basic tests for ComponentBase.
1784         * browser-tests/index.html: Added.
1785
1786         * public/v3/components/base.js:
1787         (ComponentBase): Don't create the shadow tree. Use the currently constructed element as this._element if
1788         there is one (the custom element's constructor is getting called). Otherwise create a new element but
1789         store this component in the map to avoid creating a new component in the custom element's constructor.
1790         (ComponentBase.prototype.content): Lazily create the shadow tree now.
1791         (ComponentBase.prototype.render): Ditto.
1792         (ComponentBase.prototype._ensureShadowTree): Renamed from _constructShadowTree. Dropped the support for
1793         not having shadow DOM API. This is now required. Also use importNode instead of cloneNode in cloning
1794         the template content since the latter would not get upgraded.
1795         (ComponentBase.prototype._recursivelyReplaceUnknownElementsByComponents): Modernized the code. Don't
1796         re-create a component if its element had already been upgraded by its custom element constructor.
1797         (ComponentBase.defineElement): Add this component to the static maps. _componentByName is used by
1798         _recursivelyReplaceUnknownElementsByComponents to instantiate new components in the browsers that don't
1799         support custom elements API and _componentByClass is used by ComponentBase's constructor to lookup the
1800         element name. The latter should go away once all components fully adopt ComponentBase.defineElement.
1801         (ComponentBase.defineElement.elementClass): A class to define a custom element for the component.
1802         We need to reconfigure the property since class's name is not writable but configurable.
1803
1804         * public/v3/components/button-base.js:
1805         (ButtonBase.htmlTemplate): Added. Extracted the common code from CloseButton and WarningIcon.
1806         (ButtonBase.buttonContent): Added. An abstract method overridden by CloseButton and WarningIcon.
1807         (ButtonBase.sizeFactor): Added. Overridden by WarningIcon.
1808         (ButtonBase.cssTemplate): Updated to use :host.
1809         * public/v3/components/close-button.js:
1810         (CloseButton.buttonContent): Renamed from htmlTemplate.
1811         * public/v3/components/spinner-icon.js:
1812         (SpinnerIcon.cssTemplate): Removed webkit prefixed properties, and updated it to animate stroke instead
1813         of opacity to reduce the power usage.
1814         (SpinnerIcon.htmlTemplate): Factored stroke, stroke-width, and stroke-linecap into cssTemplate.
1815         * public/v3/components/warning-icon.js:
1816         (WarningIcon.cssTemplate): Deleted.
1817         (WarningIcon.sizeFactor): Added.
1818         (WarningIcon.buttonContent): Renamed from htmlTemplate.
1819         * public/v3/pages/summary-page.js:
1820         (SummaryPage._constructRatioGraph): Fixed a bug that we were not never calling spinner.updateRendering().
1821         (SummaryPage.prototype._renderCell):
1822
1823 2017-01-13  Ryosuke Niwa  <rniwa@webkit.org>
1824
1825         Instrument calls to render()
1826         https://bugs.webkit.org/show_bug.cgi?id=167037
1827
1828         Reviewed by Sam Weinig.
1829
1830         Wrap every call to render() by newly added ComponentBase.updateRendering() to instrument it.
1831         Also, use arrow functions instead of this.render.bind or regular closures for simplicity.
1832
1833         Currently, we're making 5100 calls to render() while opening the summary page, and that's way too high.
1834
1835         * public/v3/components/analysis-results-viewer.js:
1836         (AnalysisResultsViewer.prototype._expandBetween):
1837         * public/v3/components/bar-graph-group.js:
1838         (BarGraphGroup.prototype.updateGroupRendering): Renamed form render() as BarGraphGroup is not a component.
1839         * public/v3/components/base.js:
1840         (ComponentBase.prototype.updateRendering): Added. Instruments render() call.
1841         * public/v3/components/chart-pane-base.js:
1842         (ChartPaneBase.prototype.fetchAnalysisTasks):
1843         (ChartPaneBase.prototype._mainSelectionDidZoom):
1844         (ChartPaneBase.prototype._updateStatus):
1845         (ChartPaneBase.prototype._requestOpeningCommitViewer):
1846         (ChartPaneBase.prototype._keyup):
1847         (ChartPaneBase.prototype.render):
1848         * public/v3/components/commit-log-viewer.js:
1849         * public/v3/components/customizable-test-group-form.js:
1850         (CustomizableTestGroupForm):
1851         (CustomizableTestGroupForm.prototype._customize):
1852         * public/v3/components/editable-text.js:
1853         (EditableText.prototype._didUpdate):
1854         * public/v3/components/pane-selector.js:
1855         (PaneSelector.prototype._selectedItem):
1856         * public/v3/components/results-table.js:
1857         (ResultsTable.prototype.render):
1858         * public/v3/components/time-series-chart.js:
1859         (TimeSeriesChart._renderEnqueuedCharts):
1860         * public/v3/pages/analysis-category-page.js:
1861         (AnalysisCategoryPage.prototype.open):
1862         (AnalysisCategoryPage.prototype.updateFromSerializedState):
1863         (AnalysisCategoryPage.prototype.filterDidChange):
1864         (AnalysisCategoryPage.prototype.render):
1865         * public/v3/pages/analysis-task-page.js:
1866         (AnalysisTaskChartPane.prototype._updateStatus):
1867         (AnalysisTaskPage.prototype.updateFromSerializedState):
1868         (AnalysisTaskPage.prototype._didFetchTask):
1869         (AnalysisTaskPage.prototype._didFetchRelatedAnalysisTasks):
1870         (AnalysisTaskPage.prototype._didFetchMeasurement):
1871         (AnalysisTaskPage.prototype._didFetchTestGroups):
1872         (AnalysisTaskPage.prototype._showAllTestGroups):
1873         (AnalysisTaskPage.prototype._didFetchAnalysisResults):
1874         (AnalysisTaskPage.prototype.render):
1875         (AnalysisTaskPage.prototype._renderTestGroupList.):
1876         (AnalysisTaskPage.prototype._renderTestGroupList):
1877         (AnalysisTaskPage.prototype._createTestGroupListItem):
1878         (AnalysisTaskPage.prototype._showTestGroup):
1879         (AnalysisTaskPage.prototype._didStartEditingTaskName):
1880         (AnalysisTaskPage.prototype._updateTaskName):
1881         (AnalysisTaskPage.prototype._updateTestGroupName):
1882         (AnalysisTaskPage.prototype._hideCurrentTestGroup):
1883         (AnalysisTaskPage.prototype._updateChangeType):
1884         (AnalysisTaskPage.prototype._associateBug):
1885         (AnalysisTaskPage.prototype._dissociateBug):
1886         (AnalysisTaskPage.prototype._associateCommit):
1887         (AnalysisTaskPage.prototype._dissociateCommit):
1888         (AnalysisTaskPage.prototype._chartSelectionDidChange):
1889         (AnalysisTaskPage.prototype._selectedRowInAnalysisResultsViewer):
1890         * public/v3/pages/build-request-queue-page.js:
1891         (BuildRequestQueuePage.prototype.open.):
1892         (BuildRequestQueuePage.prototype.open):
1893         * public/v3/pages/chart-pane.js:
1894         (ChartPane.prototype.setOpenRepository):
1895         (ChartPane.prototype._trendLineTypeDidChange):
1896         (ChartPane.prototype._updateTrendLine):
1897         * public/v3/pages/charts-page.js:
1898         (ChartsPage.prototype.updateFromSerializedState):
1899         (ChartsPage.prototype._updateDomainsFromSerializedState):
1900         (ChartsPage.prototype.setNumberOfDaysFromToolbar):
1901         (ChartsPage.prototype._didMutatePaneList):
1902         (ChartsPage.prototype.render):
1903         * public/v3/pages/charts-toolbar.js:
1904         (ChartsToolbar.prototype.render):
1905         * public/v3/pages/create-analysis-task-page.js:
1906         (CreateAnalysisTaskPage.prototype.updateFromSerializedState):
1907         * public/v3/pages/dashboard-page.js:
1908         (DashboardPage.prototype.updateFromSerializedState):
1909         (DashboardPage.prototype._fetchedData):
1910         * public/v3/pages/heading.js:
1911         (Heading.prototype.render):
1912         * public/v3/pages/page-with-heading.js:
1913         (PageWithHeading.prototype.render):
1914         * public/v3/pages/page.js:
1915         (Page.prototype.open):
1916         * public/v3/pages/summary-page.js:
1917         (SummaryPage.prototype.open):
1918         (SummaryPage.prototype.this._renderQueue.push):
1919         (SummaryPage):
1920         (SummaryPage.prototype._renderCell):
1921
1922 2017-01-12  Ryosuke Niwa  <rniwa@webkit.org>
1923
1924         Outliers are not hidden in v3 UI
1925         https://bugs.webkit.org/show_bug.cgi?id=166966
1926
1927         Reviewed by Andreas Kling.
1928
1929         Fixed the typo in addToSeries. An outlier has markedOutlier set to true, not isOutlier.
1930
1931         Also fixed a bug unveiled by new tests in MeasurementRootSet.ensureSingleton. It was was creating
1932         a new MeasurementRootSet each time it was called instead of finding an existing instance. Fixed the bug
1933         by merging the static maps of MeasurementRootSet and RootSet.
1934
1935         * public/v3/models/measurement-cluster.js:
1936         (MeasurementCluster.prototype.addToSeries): Fixed the bug.
1937         * public/v3/models/root-set.js:
1938         (MeasurementRootSet.prototype.namedStaticMap): Added.
1939         (MeasurementRootSet.prototype.ensureNamedStaticMap): Added.
1940         (MeasurementRootSet.namedStaticMap): Added.
1941         (MeasurementRootSet.ensureNamedStaticMap): Added.
1942         * unit-tests/measurement-set-tests.js: Added tests for adopting time series data from a cluster.
1943
1944 2017-01-12  Ryosuke Niwa  <rniwa@webkit.org>
1945
1946         Hide the UI to trigger an A/B testing when there are no triggerables
1947         https://bugs.webkit.org/show_bug.cgi?id=166964
1948
1949         Reviewed by Yusuke Suzuki.
1950
1951         Hide the "Start A/B Testing" button on analysis task pages instead of showing it and failing later
1952         when the user tries to create one it with a TriggerableNotFound error.
1953
1954         Added the list of triggerables to the manifest JSON so that we can determine this condition without
1955         having to fetch /api/triggerable for each analysis task as done in v2 UI.
1956
1957         * public/admin/reprocess-report.php:
1958         * public/api/manifest.php:
1959         * public/api/report.php:
1960         * public/include/admin-header.php:
1961         * public/include/manifest-generator.php: Moved from public/include/manifest.php.
1962         (ManifestGenerator::generate):
1963         (ManifestGenerator::triggerables): Added. Include the list of repositories this triggerable accepts
1964         as well as the list of (test, platform) pairs on which this triggerable is available.
1965         Use [testId, platformId] instead of a dictionary to reduce the file size.
1966         * public/v3/components/customizable-test-group-form.js:
1967         (CustomizableTestGroupForm): Removed this._disabled. This variable was used in TestGroupFrom to
1968         disable the "Start A/B Testing" button when no range is selected but this ended up racy. Compute
1969         the visibility of the button in render() function instead.
1970         (CustomizableTestGroupForm.prototype.setRootSetMap):
1971         (CustomizableTestGroupForm.prototype._submitted):
1972         (CustomizableTestGroupForm.prototype.render): Hide the customize link and the button as needed.
1973         The "Start A/B Testing" button must be hidden when either no range is selected or no title is typed.
1974         "Customize" button must be hidden when no range is selected.
1975         * public/v3/components/test-group-form.js:
1976         (TestGroupForm): Removed _disabled since it's no longer used.
1977         (TestGroupForm.prototype.setDisabled): Ditto.
1978         (TestGroupForm.prototype.render): Ditto.
1979         * public/v3/index.html: Include triggerable.js.
1980         * public/v3/models/manifest.js:
1981         (Manifest._didFetchManifest): Modernized. Create Triggerable objects from the manifest JSON.
1982         * public/v3/models/triggerable.js: Added.
1983         (Triggerable): Add this triggerable object to the static map of (test id, platform id) pair.
1984         (Triggerable.prototype.acceptedRepositories): Added.
1985         (Triggerable.findByTestConfiguration): Added. Finds a triggerable in the aforementioned static map.
1986         * public/v3/pages/analysis-task-page.js:
1987         (AnalysisTaskChartPane.prototype._updateStatus): Added. Re-render the page since time series data
1988         points that were previously not available may have become available. The lack of this update was
1989         causing a race condition in which the "Start A/B Testing" button for the charts is disabled even
1990         after a group name had been specified because setRootSetMap was never called with a valid set.
1991         (AnalysisTaskPage): Added this._triggerable.
1992         (AnalysisTaskPage.prototype._didFetchTask): Find the triggerable now that we've fetched the task.
1993         (AnalysisTaskPage.prototype.render): Hide the group view (the table of A/B testing results) entirely
1994         when there are no groups to show. Also hide the forms to start A/B testing when there are no matching
1995         triggerable, which is the main feature of this patch.
1996         * server-tests/api-manifest.js: Added a test for including a list of triggerables in the manifest JSON.
1997         * server-tests/resources/mock-data.js:
1998         (MockData.resetV3Models): Reset Triggerable's static map.
1999         * server-tests/tools-buildbot-triggerable-tests.js: Assert that Triggerable objects are  constructed
2000         with appropriate list of repositories and (test, platform) associations.
2001         * tools/js/database.js:
2002         (tableToPrefixMap): Added triggerable_repositories's prefix.
2003         * tools/js/remote.js:
2004         (RemoteAPI.prototype.getJSON): Log the entire response to stderr when JSON.parse fails to aid debugging.
2005         * tools/js/v3-models.js: Import triggerable.js.
2006
2007 2017-01-11  Ryosuke Niwa  <rniwa@webkit.org>
2008
2009         fetch-from-remote doesn’t work with some websites
2010         https://bugs.webkit.org/show_bug.cgi?id=166963
2011
2012         Reviewed by Yusuke Suzuki.
2013
2014         Apparently file_get_contents is not compatible with some SSL/TLS connections.
2015         Use curl_* functions to access remote servers instead.
2016
2017         * public/admin/fetch-from-remote.php:
2018         (fetch_remote):
2019
2020 2017-01-10  Ryosuke Niwa  <rniwa@webkit.org>
2021
2022         Another build fix. Always use UTC when expressing commit times in UNIX-epoch timestamps.
2023
2024         * public/api/measurement-set.php:
2025
2026 2017-01-10  Ryosuke Niwa  <rniwa@webkit.org>
2027
2028         Fix a typo in the previous commit.
2029
2030         * public/api/measurement-set.php:
2031
2032 2017-01-10  Ryosuke Niwa  <rniwa@webkit.org>
2033
2034         Build fixes for older versions of Postgres.
2035
2036         Also redirect / and /# to /v3/ as intended in r200820.
2037
2038         * public/api/measurement-set.php:
2039         * public/api/runs.php:
2040         * public/index.html:
2041
2042 2016-10-18  Dewei Zhu  <dewei_zhu@apple.com>
2043
2044         Update test cases for change r206465.
2045         https://bugs.webkit.org/show_bug.cgi?id=163618
2046
2047         Reviewed by Ryosuke Niwa.
2048
2049         Update test case for change r206465 which added support for multiple summary pages.
2050         Use deepStrictEqual instead of deepEqual as deepEqual will not complain in the case like 'deepEqual([],{})'.
2051         Fix a test failure in tools-buildbot-triggerable-tests.js.
2052         Fix a bug in generating manifest.
2053
2054         * config.json:
2055         * public/include/manifest.php:
2056         * server-tests/api-manifest.js:
2057         (TestServer.remoteAPI.getJSON.string_appeared_here.then):
2058         * server-tests/tools-buildbot-triggerable-tests.js:
2059         (then):
2060
2061 2016-09-27  Dewei Zhu  <dewei_zhu@apple.com>
2062
2063         Extend perf dashboard to support multiple summary pages.
2064         https://bugs.webkit.org/show_bug.cgi?id=162594
2065
2066         Reviewed by Ryosuke Niwa.
2067
2068         Start support multiple summary pages instead of one.
2069         Specify 'summaryPages' as key that map to a list of summaries which follows
2070         current 'summary' format in 'config.json' but with 2 more properties:
2071            'name': specifying the name shows on perf dashboard,
2072            'route': specifying the path to this page.
2073
2074         * public/include/manifest.php:
2075         * public/v3/main.js:
2076         (main):
2077         (main.): Deleted.
2078         * public/v3/models/manifest.js:
2079         (Manifest._didFetchManifest):
2080         (Manifest):
2081         * public/v3/pages/summary-page.js:
2082         (SummaryPage):
2083         (SummaryPage.prototype.routeName):
2084
2085 2016-08-09  Ryosuke Niwa  <rniwa@webkit.org>
2086
2087         Don't filter out the latest data point in chart data sampling
2088         https://bugs.webkit.org/show_bug.cgi?id=160714
2089
2090         Reviewed by Chris Dumez.
2091
2092         Exclude the last data point from sampling so that it's always included in the "sampled" charts data.
2093         Without this, the last data point can change as we zoom out the time domain.
2094
2095         Luckily, we already had a mechanism to exclude the user selected point from sampling. Extend this
2096         feature by supporting an array of point IDs instead of a single ID to exclude from filering.
2097
2098         * public/v3/components/interactive-time-series-chart.js:
2099         (InteractiveTimeSeriesChart.prototype._sampleTimeSeries): Replaced exclusionPointID by excludedPoints. 
2100
2101         * public/v3/components/time-series-chart.js:
2102         (TimeSeriesChart.prototype._ensureSampledTimeSeries): Put the last data point in excludedPoints.
2103         (TimeSeriesChart.prototype._sampleTimeSeries): Check point's id against the list of IDs.
2104
2105 2016-08-09  Ryosuke Niwa  <rniwa@webkit.org>
2106
2107         Build fix after r204187. interval has to be a getter, not a method.
2108
2109         * public/v3/components/time-series-chart.js:
2110         (TimeSeriesChart.prototype._renderTimeSeries):
2111         * public/v3/models/measurement-adaptor.js:
2112         (MeasurementAdaptor.prototype.applyTo):
2113
2114 2016-08-09  Ryosuke Niwa  <rniwa@webkit.org>
2115
2116         Fix a typo that was supposed to be fixed in r204296 before landing.
2117
2118         * public/v3/pages/chart-pane.js:
2119         (ChartPane):
2120         (ChartPane.prototype.updateFromSerializedState):
2121         (ChartPane.prototype._analyzeRange):
2122         (ChartPane.prototype._renderTrendLinePopover):
2123         (ChartPane.prototype._trendLineTypeDidChange):
2124
2125 2016-08-08  Ryosuke Niwa  <rniwa@webkit.org>
2126
2127         Always show segmentation on v3 charts page
2128         https://bugs.webkit.org/show_bug.cgi?id=160576
2129
2130         Rubber-stamped by Chris Dumez.
2131
2132         Added "Trend Lines" popover to select and customize a moving average or a segmentation to show on charts page
2133         and made Schwarz criterion segmentation the default trend line for all charts.
2134
2135         Because computing the segmentation is expensive, we use WebWorker to parallelize the computation via AsyncTask.
2136         We also compute and cache the segmentation for each cluster separately to avoid processing the entire measurement
2137         set as that could take 10-20s total, which was a huge problem in v2 UI. v3 UI's approach is more incremental and
2138         even opens up an opportunity to cache the results in the server side.
2139
2140         Also brought back "shading" for the confidence interval drawing as done in v1 and v2 UI.
2141
2142         * public/shared/statistics.js:
2143         (Statistics.segmentTimeSeriesByMaximizingSchwarzCriterion): Added segmentCountWeight and gridSize as arguments
2144         to customize the algorithm.
2145         (Statistics.splitIntoSegmentsUntilGoodEnough): Takes segmentCountWeight as BirgeAndMassartC.
2146
2147         * public/v3/async-task.js: Added.
2148         (AsyncTask): Added. This class represents a task such as computing segmentation to be executed in a worker.
2149         (AsyncTask.prototype.execute): Added. Returns a promise that gets resolved when the specified task completes.
2150         (AsyncTaskWorker.waitForAvailableWorker): Added. Calls the given callback with the first available worker. When
2151         all workers are processing some tasks, it waits until one becomes available by putting the callback into a queue.
2152         _didRecieveMessage pops an item out of this queue when a worker completes a task. We don't use a promise here
2153         because calling this function multiple times synchronously could result in all the returned promises getting
2154         resolved with the same worker as none of the callers get to lock away the first available worker until the end
2155         of the current micro-task.
2156         (AsyncTaskWorker._makeWorkerEventuallyAvailable): Added. A helper function for waitForAvailableWorker. Start
2157         a new worker if the number of workers we've started is less than the number of extra cores (e.g. 7 if there are
2158         8 cores on the machine). Avoid starting a new worker if we've started a new worker within the last 50 ms since
2159         starting a new worker takes some time.
2160         (AsyncTaskWorker._findAvailableWorker): Added. Finds a worker that's available right now if there is any.
2161         (AsyncTaskWorker): Added. An instance of AsyncTaskWorker represents a Web worker.
2162         (AsyncTaskWorker.prototype.id): Added.
2163         (AsyncTaskWorker.prototype.sendTask): Added. Sends a task represented by AsyncTask to the worker.
2164         (AsyncTaskWorker.prototype._didRecieveMessage): Added. This function gets called when the current task completes
2165         in the worker. Pop the next callback if some caller of waitForAvailableWorker is still waiting. Otherwise stop
2166         the worker after one second of waiting to avoid worker churning.
2167         (AsyncTaskWorker.workerDidRecieveMessage): Added. Called by onmessage on the worker. Executes the specified task
2168         and sends back a message upon completion with the appropriate timing data.
2169
2170         * public/v3/components/chart-pane-base.js:
2171         (ChartPaneBase.prototype.configure): Uses _createSourceList.
2172         (ChartPaneBase.prototype._createSourceList): Added. Extracted from configure to customize the source list for
2173         the main chart and the overview chart.
2174         (ChartPaneBase.prototype._updateSourceList): Uses _createSourceList.
2175
2176         * public/v3/components/chart-styles.js:
2177         (ChartStyles.createSourceList): Added a boolean showPoint as an extra argument. This specifies whether circles
2178         are drawn for each data point.
2179         (ChartStyles.baselineStyle): Added styles for foreground lines and background lines. They're used for trend lines
2180         and underlying raw data respectively when trend lines are shown.
2181         (ChartStyles.targetStyle): Ditto.
2182         (ChartStyles.currentStyle): Ditto.
2183
2184         * public/v3/components/time-series-chart.js:
2185         (TimeSeriesChart): Added _trendLines, _renderedTrendLines, and _fetchedTimeSeries as instance variables.
2186         (TimeSeriesChart.prototype.setSourceList): Clear _fetchedTimeSeries before calling setSourceList for consistency.
2187         (TimeSeriesChart.prototype.sourceList): Added.
2188         (TimeSeriesChart.prototype.clearTrendLines): Added.
2189         (TimeSeriesChart.prototype.setTrendLine): Added. Preserves the existing trend lines for other sources. This is
2190         necessary because segmentation for "current" and "baseline" lines may become available at different times, and we
2191         don't want to clear one or the other when setting one.
2192         (TimeSeriesChart.prototype._layout): Added a call to _ensureTrendLines.
2193         (TimeSeriesChart.prototype._renderChartContent): Call _renderTimeSeries for trend lines. Trend lines are always
2194         foreground lines and "regular" raw data points are drawn as background if there are trend lines.
2195         (TimeSeriesChart.prototype._renderTimeSeries): Added layerName as an argument. It could be an empty string,
2196         "foreground", or "background". Draw a "shade" just like v1 and v2 UI instead of vertical lines for the confidence
2197         intervals. Pick "foreground", "background", or "regular" chart style based on layerName. Also avoid drawing data
2198         points when *PointRadius is set to zero to reduce the runtime of this function.
2199         (TimeSeriesChart.prototype._sourceOptionWithFallback): Added.
2200         (TimeSeriesChart.prototype._ensureSampledTimeSeries): When *PointRadius is 0, show as many points as there are x
2201         coordinates as a fallback instead of showing every point.
2202         (TimeSeriesChart.prototype._ensureTrendLines): Added. Returns true if the chart contents haven't been re-rendered
2203         since the last update to trend lines. This flag is unset by setTrendLine.
2204
2205         * public/v3/index.html:
2206
2207         * public/v3/models/measurement-cluster.js:
2208         (MeasurementCluster.prototype.addToSeries): Store the data points' index to idMap to help aid MeasurementSet's
2209         _cachedClusterSegmentation efficiently re-create the segmentation from the cache.
2210
2211         * public/v3/models/measurement-set.js:
2212         (MeasurementSet): Added _segmentationCache as an instance variable.
2213         (MeasurementSet.prototype.fetchSegmentation): Added. Calls _cachedClusterSegmentation on each cluster, and
2214         constructs the time series representation of the segmentation from the results.
2215         (MeasurementSet.prototype._cachedClusterSegmentation): Computes and caches the segmentation for each cluster.
2216         The cache of segmentation stores ID of each measurement set at which segment changes instead of its index since
2217         the latter could change in any moment when a new test result is reported, or an existing test result is removed
2218         from the time series; e.g. when it's marked as an outlier.
2219         (MeasurementSet.prototype._validateSegmentationCache): Added. Checks whether the cached segmentation's name and
2220         its parameters match that of the requested one.
2221         (MeasurementSet.prototype._invokeSegmentationAlgorithm): Added. Invokes the segmentation algorithm either in the
2222         main thread or in a Web worker via AsyncTask API based on the size of the time series. While parallelizing the
2223         work is beneficial when the data set is large, the overhead can add up if we keep processing a very small data
2224         set in a worker.
2225
2226         * public/v3/models/time-series.js: Made the file compatible with Node.
2227         (TimeSeries.prototype.length): Added.
2228         (TimeSeries.prototype.valuesBetweenRange): Added.
2229
2230         * public/v3/pages/chart-pane.js:
2231         (createTrendLineExecutableFromAveragingFunction): Added.
2232         (ChartTrendLineTypes): Added. Similar to StatisticsStrategies (statistics-strategies.js) in v2 UI.
2233         (ChartPane): Added _trendLineType, _trendLineParameters, _trendLineVersion, and _renderedTrendLineOptions as
2234         instance variables.
2235         (ChartPane.prototype.serializeState): Serialize the trend line option. This format is compatible with v2 UI.
2236         (ChartPane.prototype.updateFromSerializedState): Ditto. Parsing is compatible with v2 UI except that we now have
2237         the default trend line set when the specified ID doesn't match an existing type ID.
2238         (ChartPane.prototype._renderActionToolbar): Added a call to _renderTrendLinePopover. This is the popover that
2239         specifies the type of a trend line to show as well as its parameters.
2240         (ChartPane.prototype._renderTrendLinePopover): Added. A popover for specifying and customizing a trend line.
2241         (ChartPane.prototype._trendLineTypeDidChange): Added. Called when a new trend line is selected.
2242         (ChartPane.prototype._defaultParametersForTrendLine): Added.
2243         (ChartPane.prototype._trendLineParameterDidChange): Added. Called when the trend lines' parameters are changed.
2244         (ChartPane.prototype._didFetchData): Added. Overrides the one in ChartPaneBase to trigger a trend line update.
2245         (ChartPane.prototype._updateTrendLine): Added. Update the trend line. Since segmentation can take an arbitrary
2246         long time, avoid updating trend lines if this function had been called again (possibly for a different trend line
2247         type or with different parameters) before the results become available; hence the versioning.
2248         (ChartPane.paneHeaderTemplate): Added the trend line popover.
2249         (ChartPane.cssTemplate): Added styles for the trend line popover. Also use a more opaque background color behind
2250         popovers when the -webkit-backdrop-filter property is not supported.
2251
2252         * public/v3/pages/dashboard-page.js:
2253         (DashboardPage.prototype._createChartForCell): Call createSourceList with showPoints set to true to preserve the
2254         existing behavior.
2255
2256         * tools/js/v3-models.js: Include TimeSeries object.
2257
2258         * unit-tests/measurement-set-tests.js: Added two test cases for MeasurementSet's fetchSegmentation.
2259
2260         * unit-tests/resources/almost-equal.js: Added.
2261         (almostEqual): Extracted out of statistics-tests.js.
2262
2263         * unit-tests/statistics-tests.js:
2264
2265 2016-08-05  Ryosuke Niwa  <rniwa@webkit.org>
2266
2267         segmentTimeSeriesByMaximizingSchwarzCriterion returns a bogus result on empty charts
2268         https://bugs.webkit.org/show_bug.cgi?id=160575
2269
2270         Rubber-stamped by Chris Dumez.
2271
2272         The bug was caused by an early return in segmentTimeSeriesByMaximizingSchwarzCriterion.
2273         Removed this early return as the one in splitIntoSegmentsUntilGoodEnough was sufficient.
2274
2275         Also factored out a few functions in findOptimalSegmentation so that they can be better
2276         optimized in JSC's DFG and FTL tiers, and removed unused debuggingTestingRangeNomination.
2277
2278         * public/shared/statistics.js:
2279         (Statistics.segmentTimeSeriesByMaximizingSchwarzCriterion): Removed an early return.
2280         (Statistics.splitIntoSegmentsUntilGoodEnough):
2281         (.allocateCostUpperTriangularForSegmentation): Extracted from findOptimalSegmentation.
2282         (.allocatePreviousNodeForSegmentation): Ditto.
2283         (.findOptimalSegmentationInternal): Ditto.
2284         (.findOptimalSegmentation):
2285
2286         * unit-tests/statistics-tests.js: Added a test case.
2287
2288 2016-08-05  Ryosuke Niwa  <rniwa@webkit.org>
2289
2290         Perf dashboard sometimes tries to fetch a non-existent measurement-set JSON
2291         https://bugs.webkit.org/show_bug.cgi?id=160577
2292
2293         Rubber-stamped by Chris Dumez.
2294
2295         The bug was caused by findClusters computing the first cluster's endTime incorrectly. Namely, we were
2296         multiplying the number of clusters by clusterStart instead of clusterSize with an off-by-one error.
2297
2298         * public/v3/models/measurement-set.js:
2299         (MeasurementSet.prototype.findClusters): Folded computeClusterStart into where clusterEnd is computed
2300         for clarity. Also fixed a bug that we were not computing the first cluster to fetch correctly when
2301         the fetched time range started before clusterStart (i.e. when startTime - clusterStart is negative).
2302         Finally, fixed the main bug by multiplying the number of clusters by clusterSize instead of
2303         clusterStart to compute the end time of the very first cluster in this measurement set. Because what
2304         we're computing here is the end time of the first cluster, not the start time, we also need to subtract
2305         one from the number of clusters. e.g. if there was exactly one cluster, then firstClusterEndTime is
2306         identically equal to lastClusterEndTime.
2307         (MeasurementSet.prototype.fetchedTimeSeries): Removed the unused argument to TimeSeries's constructor.
2308
2309         * unit-tests/analysis-task-tests.js: Fixed the tests for the latest version of Mocha which complains if
2310         we returned a promise in unit tests when "done" function is used.
2311         * unit-tests/checkconfig.js: Ditto.
2312         * unit-tests/measurement-set-tests.js: Added a test case for findClusters and a test to make sure
2313         fetchBetween doesn't try to fetch a cluster before the first cluster in the set. Also fixed other test
2314         cases which were relying on the bug this patch fixed.
2315
2316 2016-08-04  Ryosuke Niwa  <rniwa@webkit.org>
2317
2318         MeasurementCluster's addToSeries is slow
2319         https://bugs.webkit.org/show_bug.cgi?id=160581
2320
2321         Rubber-stamped by Chris Dumez.
2322
2323         The bulk of time was spent in MeasurementAdaptor.prototype.applyTo where we computed the interval.
2324
2325         Since some of data points are filtered out by TimeSeriesChart component before intervals are used,
2326         we can significantly reduce the CPU time by lazily compute them. This patch reduces the runtime of
2327         applyTo from ~60ms to ~30ms on my machine.
2328
2329         * public/v3/models/measurement-adaptor.js:
2330         (MeasurementAdaptor.prototype.applyTo): Lazily compute and cache the interval. Also cache the build
2331         object instead of always creating a new object.
2332         * public/v3/models/measurement-cluster.js:
2333         (MeasurementCluster.prototype.addToSeries): Call applyTo first before checking whether the point is
2334         an outlier or its id to avoid extracting those values twice since they show up in the profiler. Also
2335         use "of" instead "forEach" since "of" seems to be faster here.
2336
2337 2016-08-04  Ryosuke Niwa  <rniwa@webkit.org>
2338
2339         Syncing script's configuration duplicates a lot of boilerplate
2340         https://bugs.webkit.org/show_bug.cgi?id=160574
2341
2342         Rubber-stamped by Chris Dumez.
2343
2344         This patch makes each configuration accept an array of platforms and types so that we can write:
2345
2346         {"type": "speedometer", "builder": "mba", "platform": "Trunk El Capitan MacBookAir"},
2347         {"type": "speedometer", "builder": "mbp", "platform": "Trunk El Capitan MacBookPro"},
2348         {"type": "speedometer", "builder": "mba", "platform": "Trunk Sierra MacBookAir"},
2349         {"type": "speedometer", "builder": "mbp", "platform": "Trunk Sierra MacBookPro"},
2350         {"type": "jetstream", "builder": "mba", "platform": "Trunk El Capitan MacBookAir"},
2351         {"type": "jetstream", "builder": "mbp", "platform": "Trunk El Capitan MacBookPro"},
2352         {"type": "jetstream", "builder": "mba", "platform": "Trunk Sierra MacBookAir"},
2353         {"type": "jetstream", "builder": "mbp", "platform": "Trunk Sierra MacBookPro"},
2354
2355         more concisely as:
2356
2357         {"builder": "mba", "types": ["speedometer", "jetstream"],
2358             "platforms": ["Trunk El Capitan MacBookAir", "Trunk Sierra MacBookAir"]},
2359         {"builder": "mbp", "types": ["speedometer", "jetstream"],
2360             "platforms": ["Trunk El Capitan MacBookPro", "Trunk Sierra MacBookPro"]},
2361
2362         * tools/js/buildbot-syncer.js:
2363         (BuildbotSyncer._loadConfig):
2364         (BuildbotSyncer._expandTypesAndPlatforms): Added. Clones a new configuration entry for each type
2365         and platform.
2366         (BuildbotSyncer._createTestConfiguration): Extracted from _loadConfig.
2367         (BuildbotSyncer._validateAndMergeConfig): Added a new argument that specifies a property that
2368         shouldn't be merged into the configuration. Also added the support for 'types' and 'platforms',
2369         and merged the code for verify an array of strings. Finally, allow the appearance of 'properties'
2370         since this function can now be called on a cloned configuration in which 'arguments' had already
2371         been renamed to 'properties'.
2372
2373         * unit-tests/buildbot-syncer-tests.js: Added a test case to parse a consolidated configuration.
2374         (sampleiOSConfigWithExpansions): Added.
2375
2376         * unit-tests/resources/mock-v3-models.js:
2377         (MockModels.inject): Added a few more mock models for the newly added test.
2378
2379 2016-07-26  Ryosuke Niwa  <rniwa@webkit.org>
2380
2381         REGRESSION: Tooltip for analysis tasks doesn't show up on charts
2382         https://bugs.webkit.org/show_bug.cgi?id=160221
2383
2384         Rubber-stamped by Chris Dumez.
2385
2386         The bug was caused by ChartPaneBase resetting annotation bars every time the current point has moved.
2387         Avoid doing this in ChartPaneBase's _renderAnnotations().
2388
2389         * public/v3/components/chart-pane-base.js:
2390         (ChartPaneBase):
2391         (ChartPaneBase.prototype.fetchAnalysisTasks):
2392         (ChartPaneBase.prototype._renderAnnotations):
2393
2394 2016-07-26  Ryosuke Niwa  <rniwa@webkit.org>
2395
2396         REGRESSION: The arrow indicating the current page doesn't get updated
2397         https://bugs.webkit.org/show_bug.cgi?id=160185
2398
2399         Reviewed by Chris Dumez.
2400
2401         The bug was caused by Heading's render() function not updating the DOM more than once. I don't understand
2402         how this has ever worked. Fixed the bug by rendering DOM whenever the current page has changed.
2403
2404         * public/v3/pages/heading.js:
2405         (Heading):
2406         (Heading.prototype.render):
2407
2408 2016-07-25  Ryosuke Niwa  <rniwa@webkit.org>
2409
2410         Build fix for Safari 9.
2411
2412         * public/v3/models/build-request.js:
2413         (BuildRequest.prototype.waitingTime): Don't use "const" in strict mode.
2414
2415 2016-07-23  Ryosuke Niwa  <rniwa@webkit.org>
2416
2417         Perf dashboard should show the list of a pending A/B testing jobs
2418         https://bugs.webkit.org/show_bug.cgi?id=160138
2419
2420         Rubber-stamped by Chris Dumez.
2421
2422         Add a page to show the list of A/B testing build requests per triggerable. Ideally, we would like to
2423         see a queue per builder but that would require changes to database tables and syncing scripts.
2424
2425         Because this page is most useful when the analysis task with which each build request is associated,
2426         JSON API at /api/build-requests/ has been modified to return the analysis task ID for each request.
2427
2428         Also streamlined the page that shows the list of analysis tasks per Chris' feedback by consolidating
2429         "Bisecting" and "Identified" into "Investigated" and moving the toolbar from the upper left corner
2430         inside the heading to right beneath the heading above the table. Also made the category page serialize
2431         the filter an user had typed in so that reloading the page doesn't clear it.
2432
2433         * public/api/analysis-tasks.php:
2434         (fetch_associated_data_for_tasks): Removed 'category' from the list of columns returned as the notion
2435         of 'category' is only relevant in UI, and it's better computed in the front-end.
2436         (format_task): Ditto.
2437         (determine_category): Deleted.
2438
2439         * public/api/test-groups.php:
2440         (main):
2441
2442         * public/include/build-requests-fetcher.php:
2443         (BuildRequestsFetcher::fetch_for_task): Include the analysis task ID in the rows.
2444         (BuildRequestsFetcher::fetch_for_group): Ditto. Ditto.
2445         (BuildRequestsFetcher::fetch_incomplete_requests_for_triggerable): Ditto.
2446         (BuildRequestsFetcher::results_internal): Ditto.
2447
2448         * public/v3/index.html:
2449
2450         * public/v3/main.js:
2451         (main): Create a newly introduced BuildRequestQueuePage as a subpage of AnalysisCategoryPage.
2452
2453         * public/v3/components/ratio-bar-graph.js:
2454         (RatioBarGraph.prototype.update): Fixed a bogus assertion here. ratio can be any number. The coercion
2455         into [-1, 1] is done inside RatioBarGraph's render() function.
2456
2457         * public/v3/models/analysis-task.js:
2458         (AnalysisTask.prototype.category): Moved the code to compute the analysis task's category from
2459         determine_category in analysis-tasks.php. Also merged "bisecting" and "identified" into "investigated".
2460         (AnalysisTask.categories): Merged "bisecting" and "identified" into "investigated".
2461
2462         * public/v3/models/build-request.js:
2463         (BuildRequest): Remember the triggerable and the analysis task associated with this request as well as
2464         the time at when this request was created.        
2465         (BuildRequest.prototype.analysisTaskId): Added.
2466         (BuildRequest.prototype.statusLabel): Use a shorter label: "Waiting" for "pending" status.
2467         (BuildRequest.prototype.createdAt): Added.
2468         (BuildRequest.prototype.waitingTime): Added. Returns a human readable time duration since the creation
2469         of this build request such as "2 hours 21 minutes" against a reference time.
2470         (BuildRequest.fetchTriggerables): Added.
2471         (BuildRequest.cachedRequestsForTriggerableID): Added. Used when navigating back to 
2472
2473         * public/v3/pages/analysis-category-page.js:
2474         (AnalysisCategoryPage): Construct AnalysisCategoryToolbar and store it in this._categoryToolbar since it
2475         no longer inherits from Toolbar class, which PageWithHeading recognizes and stores.
2476         (AnalysisCategoryPage.prototype.title):
2477         (AnalysisCategoryPage.prototype.serializeState): Added.
2478         (AnalysisCategoryPage.prototype.stateForCategory): Added. Include the filter in the serialization.
2479         (AnalysisCategoryPage.prototype.updateFromSerializedState): Restore the filter from the URL state.
2480         (AnalysisCategoryPage.prototype.filterDidChange): Added. Called by AnalysisCategoryToolbar to update
2481         the URL state in addition to calling render() as done previously via setFilterCallback.
2482         (AnalysisCategoryPage.prototype.render): Always call _categoryToolbar.render() since the hyperlinks for
2483         the category pages now include the filter, which can be updated in each call.
2484         (AnalysisCategoryPage.cssTemplate):
2485
2486         * public/v3/pages/analysis-category-toolbar.js:
2487         (AnalysisCategoryToolbar): Inherits from ComponentBase instead of Toolbar since AnalysisCategoryToolbar
2488         no longer works with Heading class unlike other subclasses of Toolbar class.
2489         (AnalysisCategoryToolbar.prototype.setCategoryPage): Added.
2490         (AnalysisCategoryToolbar.prototype.setFilterCallback): Deleted.
2491         (AnalysisCategoryToolbar.prototype.setFilter): Added. Used to restore from a serialized URL state.
2492         (AnalysisCategoryToolbar.prototype.render): Don't recreate the input element as it clears the value as
2493         well as the selection of the element. Also use AnalysisCategoryPage's stateForCategory to serialize the
2494         category name and the current filter for each hyperlink.
2495         (AnalysisCategoryToolbar.prototype._filterMayHaveChanged): Now takes an boolean argument specifying
2496         whether the URL state should be updated or not. We update the URL only when a change event is fired to
2497         avoid constantly updating it while an user is still typing.
2498         (AnalysisCategoryToolbar.cssTemplate): Added.
2499         (AnalysisCategoryToolbar.htmlTemplate): Added a button to open the newly added queue page.
2500
2501         * public/v3/pages/build-request-queue-page.js:
2502         (BuildRequestQueuePage): Added.
2503         (BuildRequestQueuePage.prototype.routeName): Added.
2504         (BuildRequestQueuePage.prototype.pageTitle): Added.
2505         (BuildRequestQueuePage.prototype.open): Added. Fetch open build requests for every triggerables using
2506         the same API as the syncing scripts.
2507         (BuildRequestQueuePage.prototype.render): Added.
2508         (BuildRequestQueuePage.prototype._constructBuildRequestTable): Added. Construct a table for the list of
2509         pending, scheduled or running build requests in the order syncing scripts would see. Note that the list
2510         of build requests returned by /api/build-requests/* can contain completed, canceled, or failed requests
2511         since the JSON returns all build requests associated with each test group if one of the requests of the
2512         group have not finished. This helps syncing scripts picking the right builder for A/B testing when it
2513         had previously been unloaded or crashed in the middle of processing a test group. This characteristics
2514         of the API actually helps us here because we can reliably compute the total number of build requests in
2515         the group. The first half of this function does this counting as well as collapses all but the first
2516         unfinished build requests into a "contraction" row, which just shows the number of build requests that
2517         are remaining in the group.
2518         (BuildRequestQueuePage.cssTemplate): Added.
2519         (BuildRequestQueuePage.htmlTemplate): Added.
2520
2521         * public/v3/pages/summary-page.js:
2522         (SummaryPage.prototype.open): Use one-day median instead of seven-day median to compute the status.
2523         (SummaryPageConfigurationGroup): Initialize _ratio to NaN. This was causing assertion failures in
2524         RatioBarGraph's update() while measurement sets are being fetched.
2525
2526         * server-tests/api-build-requests-tests.js: Updated the tests per change in BuildRequest's statusLabel.
2527         * unit-tests/analysis-task-tests.js: Ditto.
2528         * unit-tests/test-groups-tests.js: Ditto.
2529         * unit-tests/build-request-tests.js: Added tests for BuildRequest's waitingTime.
2530
2531 2016-07-22  Ryosuke Niwa  <rniwa@webkit.org>
2532
2533         REGRESSION(r203035): Marking points as an outlier no longer updates charts
2534         https://bugs.webkit.org/show_bug.cgi?id=160106
2535
2536         Reviewed by Darin Adler.
2537
2538         The bug was caused by MeasurementSet's fetchBetween clearing previously registered callbacks when noCache
2539         option is specified.
2540
2541         * public/v3/components/time-series-chart.js:
2542         (TimeSeriesChart.prototype.setSourceList): Clear this._fetchedTimeSeries when changing chart options.
2543         e.g. need to start including or excluding outliers.
2544         (TimeSeriesChart.prototype.fetchMeasurementSets): Don't skip the fetching when noCache is true.
2545
2546         * public/v3/models/measurement-set.js:
2547         (MeasurementSet): Added this._callbackMap as an instance variable to keep track of all callbacks on every
2548         cluster since we may need to call each callback multiple times per cluster when noCache option is used.
2549         (MeasurementSet.prototype.fetchBetween): Moved the code to add _primaryClusterPromise to _allFetches here
2550         so that now this function and _ensureClusterPromise are only functions that touch _allFetches.
2551         (MeasurementSet.prototype._ensureClusterPromise): Extracted out of fetchBetween. Queue up all callbacks
2552         for each cluster when creating a new promise.
2553         (MeasurementSet.prototype._fetchPrimaryCluster): Removed the code to add _primaryClusterPromise now that
2554         it's done in fetchBetween.
2555
2556         * public/v3/remote.js:
2557         (RemoteAPI.postJSONWithStatus): Removed superfluous call to console.log.
2558
2559         * unit-tests/measurement-set-tests.js: Updated the test case for noCache. The callback registered before
2560         fetchBetween is called with noCache=true is now invoked so callCount must be 3 instead of 2.
2561
2562 2016-07-19  Ryosuke Niwa  <rniwa@webkit.org>
2563
2564         Perf dashboard always re-generate measurement set JSON
2565         https://bugs.webkit.org/show_bug.cgi?id=159951
2566
2567         Reviewed by Chris Dumez.
2568
2569         The bug was caused by manifest.json reporting the last modified date of a measurement set in floating point,
2570         and a measurement set JSON reporting it as an integer. Fixed the bug by always using an integer.
2571
2572         * public/api/measurement-set.php:
2573         (main): Return 404 when the results is empty.
2574         (MeasurementSetFetcher::execute_query): Use "extract(epoch from commit_time)" like ManifestGenerator to improve
2575         the generation speed. This is ~10% runtime improvement.
2576         (MeasurementSetFetcher::format_map): Updated to reflect the above change.
2577         (MeasurementSetFetcher::parse_revisions_array): Ditto.
2578
2579         * public/include/manifest.php:
2580         (ManifestGenerator::platforms): Fixed the bug by coercing lastModified to integer (instead of float).
2581
2582         * server-tests/api-measurement-set-tests.js: Added a test case for returning empty results, and a test case for
2583         making sure lastModified dates in manifest.json and measurement sets match.
2584
2585         * tools/js/remote.js:
2586         (RemoteAPI.prototype.sendHttpRequest): Reject the promise when HTTP status code is not 200.
2587
2588 2016-07-09  Ryosuke Niwa  <rniwa@webkit.org>
2589
2590         Perf dashboard can consume 50-70% of CPU on MacBook even if user is not interacting at all
2591         https://bugs.webkit.org/show_bug.cgi?id=159597
2592
2593         Reviewed by Chris Dumez.
2594
2595         TimeSeriesChart and InteractiveTimeSeriesChart had been relying on continually polling on requestAnimationFrame
2596         to update itself in response to its canvas resizing. Even though there as an early exit in the case there was
2597         nothing to update, this is still causing a significant power drain when the user is not interacting at all.
2598
2599         Let TimeSeriesChart use the regular top-down render path like other components with exceptions of listening to
2600         window's resize eventas well as when new JSONs are fetched from the server. The render() call to the latter case
2601         will be coerced into a single callback on requestAnimationFrame to avoid DOM-mutation-layout churn.
2602
2603         * public/v3/components/base.js:
2604         (ComponentBase.isElementInViewport): Deleted.
2605         * public/v3/components/chart-pane-base.js:
2606         (ChartPaneBase.prototype.render): Enqueue charts to render.
2607         * public/v3/components/chart-styles.js:
2608         (ChartStyles.dashboardOptions): Removed updateOnRequestAnimationFrame which is no longer an available option.
2609         * public/v3/components/time-series-chart.js:
2610         (TimeSeriesChart): Replaced the code to register itself for rAF by the code to listen to resize events on window.
2611         (TimeSeriesChart._updateOnRAF): Deleted.
2612         (TimeSeriesChart._updateAllCharts): Added.
2613         (TimeSeriesChart.prototype._enqueueToRender): Added.
2614         (TimeSeriesChart._renderEnqueuedCharts): Added.
2615         (TimeSeriesChart.prototype.fetchMeasurementSets): Avoid calling fetchBetween when the range had been fetched.
2616         Without this change, we can incur a significant number of redundant calls to render() when adjusting the domain
2617         in charts page by the slider. When no new JSON is fetched, simply enqueue this chart to render on rAF.
2618         (TimeSeriesChart.prototype._didFetchMeasurementSet): Enqueue this chart to render on rAF.
2619         (TimeSeriesChart.prototype.render): Removed the check for isElementInViewport since we no longer get render() call
2620         when this chart moves into the viewport (as we no longer listen to every rAF or scroll event).
2621         * public/v3/models/measurement-set.js:
2622         (MeasurementSet.prototype.hasFetchedRange): Fixed various bugs revealed by the new use in fetchMeasurementSets.
2623         * public/v3/pages/chart-pane-status-view.js:
2624         (ChartPaneStatusView.prototype._updateRevisionListForNewCurrentRepository): Removed the dead code. It was probably
2625         copied from when this code was in InteractiveTimeSeries chart. There is no this._forceRender in this component.
2626         * public/v3/pages/dashboard-page.js:
2627         (DashboardPage.prototype.render): Enqueue charts to render. 
2628         * public/v3/pages/heading.js:
2629         (SummaryPage.prototype.open): Removed the call to isElementInViewport. This wasn't really doing anything useful in
2630         this component.
2631         * unit-tests/measurement-set-tests.js: Added tests for hasFetchedRange.
2632         (.waitForMeasurementSet): Moved to be used in a newly added test case.
2633
2634 2016-07-09  Ryosuke Niwa  <rniwa@webkit.org>
2635
2636         REGRESSION: manifest.json generation takes multiple seconds on perf dashboard
2637         https://bugs.webkit.org/show_bug.cgi?id=159596
2638
2639         Reviewed by Chris Dumez.
2640
2641         The most of CPU time was spent looking for a duplicate entry in an array of metrics by array_search.
2642         This patch moves to postgres by using aggregate functions in the query. Also moved the code to convert
2643         datetime to UNIX epoch timestamp from PHP to within postgres query.
2644
2645         These improvements reduce total runtime of Manifest::generate from ~4s to ~350ms on my machine.
2646
2647         * public/include/manifest.php:
2648         (Manifest::generate): No longer fetches test_configurations table as this is done in Manifest::platforms now.
2649         Also moved calls to each method in the class to separate lines for easier instrumentation.
2650         (Manifest::platforms): Group test configurations (current, baseline, target) by platform and metric.
2651         Use the max of the last modified dates in UNIX epoch timestamps (ms to be compatible with JS's representation).
2652         A given platform, metric pair is considered to be in the v1 dashboard if any test configuration is in.
2653
2654 2016-07-08  Ryosuke Niwa  <rniwa@webkit.org>
2655
2656         bundle-v3-scripts.py should compress HTML/CSS templates
2657         https://bugs.webkit.org/show_bug.cgi?id=159582
2658
2659         Reviewed by Joseph Pecoraro.
2660
2661         Strip leading and trailing whitespaces from HTML and CSS templates. This is a 8% progression on the file size.
2662
2663         * Install.md: Updated the list of MIME types to apply deflate for newer versions of Apache.
2664         * tools/bundle-v3-scripts.py:
2665         (main):
2666         (compress_template): Added.
2667
2668 2016-06-13  Ryosuke Niwa  <rniwa@webkit.org>
2669
2670         Build fix. Strip out "use strict" everywhere so that the perf dashboard works on the shipping Safari.
2671
2672         * tools/bundle-v3-scripts.py:
2673         (main):
2674
2675 2016-06-13  Ryosuke Niwa  <rniwa@webkit.org>
2676
2677         Invalid token error when trying to create an A/B analysis for a range
2678         https://bugs.webkit.org/show_bug.cgi?id=158679
2679
2680         Reviewed by Chris Dumez.
2681
2682         The problem in this particular case was due to another website overriding cookies for our subdomain.
2683         Make PrivilegedAPI robust against its token becoming invalid in general to fix the bug since the cookie
2684         is only available under /privileged-api/ and the v3 UI can't access it for security reasons.
2685
2686         This patch factors out PrivilegedAPI out of remote.js so that it can be tested separately in server tests
2687         as well as unit tests even though RemoteAPI itself is implemented differently in each case.
2688
2689         * init-database.sql: Added a forgotten default value "false" to run_marked_outlier.
2690         * public/v3/index.html:
2691         * public/v3/privileged-api.js: Added. Extracted out of public/v3/remote.js.
2692         (PrivilegedAPI.sendRequest): Fixed the bug. When the initial request fails with "InvalidToken" error,
2693         re-generate the token and re-issue the request.
2694         (PrivilegedAPI.requestCSRFToken):
2695         * public/v3/remote.js:
2696         (RemoteAPI.postJSON): Added to match tools/js/remote.js.
2697         (RemoteAPI.postJSONWithStatus): Ditto.
2698         (PrivilegedAPI): Moved to privileged-api.js.
2699         * server-tests/api-measurement-set-tests.js: Removed the unused require for crypto.
2700         * server-tests/privileged-api-upate-run-status.js: Added tests for /privileged-api/update-run-status.
2701         * server-tests/resources/test-server.js:
2702         (TestServer.prototype.inject): Clear the cookies as well as tokens in PrivilegedAPI.
2703         * tools/js/remote.js:
2704         (RemoteAPI): Added the support for PrivilegedAPI by making cookie set by the server persist.
2705         (RemoteAPI.prototype.clearCookies): Added for tests.
2706         (RemoteAPI.prototype.postJSON): Make sure sendHttpRequest always sends a valid JSON.
2707         (RemoteAPI.prototype.postJSONWithStatus): Added since this API is used PrivilegedAPI.
2708         (RemoteAPI.prototype.sendHttpRequest): Retain the cookie set by the server and send it back in each request.
2709         * tools/js/v3-models.js:
2710         * unit-tests/privileged-api-tests.js: Added unit tests for PrivilegedAPI.
2711         * unit-tests/resources/mock-remote-api.js:
2712         (MockRemoteAPI.postJSON): Added for unit testing.
2713         (MockRemoteAPI.postJSONWithStatus): Ditto.
2714
2715 2016-06-13  Ryosuke Niwa  <rniwa@webkit.org>
2716
2717         /admin/tests is very slow
2718         https://bugs.webkit.org/show_bug.cgi?id=158682
2719
2720         Reviewed by Chris Dumez.
2721
2722         The slowness came from TestNameResolver::__construct, which was fetching the entire table of test_configurations,
2723         which at this point contains more than 32,000 rows. Don't fetch the entire table in the constructor. Instead,
2724         fetch a subset of rows as needed in configurations_for_metric_and_platform. Even though this results in many SQL
2725         queries being issued, that's a lot more efficient in practice because we only fetch a few dozen rows in practice.
2726
2727         Also removed a whole bunch of features from /admin/tests to simplify the page. In particular, the ability to update
2728         the list of triggerables has been removed now that sync-buildbot.js automatically updates that for us. This removed
2729         the last use of test_exists_on_platform, which was also dependent on fetching test_configurations upfront.
2730
2731         * public/admin/tests.php:
2732         * public/include/test-name-resolver.php:
2733         (TestNameResolver::__construct): Don't fetch the entire table of test_configurations.
2734         (TestNameResolver::configurations_for_metric_and_platform): Just issue a SQL query for the specified platform and metric.
2735         (TestNameResolver::test_exists_on_platform): Removed.
2736
2737 2016-06-08  Ryosuke Niwa  <rniwa@webkit.org>
2738
2739         sync-buildbot.js should update the list of tests and platforms associated with a triggerable
2740         https://bugs.webkit.org/show_bug.cgi?id=158406
2741
2742         Reviewed by Chris Dumez.
2743
2744         Add /api/update-triggerable and a test for it, which were supposed to be added in r201718
2745         but for which I forgot to run svn add.
2746
2747         * public/api/update-triggerable.php: Added.
2748         (main):
2749         * server-tests/api-update-triggerable.js: Added.
2750
2751 2016-06-07  Ryosuke Niwa  <rniwa@webkit.org>
2752
2753         Build fix after r201739. attachShadow was throwing an exception on this component.
2754
2755         * public/v3/pages/analysis-category-toolbar.js:
2756         (AnalysisCategoryToolbar):
2757
2758 2016-06-06  Ryosuke Niwa  <rniwa@webkit.org>
2759
2760         sync-buildbot.js should update the list of tests and platforms associated with a triggerable
2761         https://bugs.webkit.org/show_bug.cgi?id=158406
2762         <rdar://problem/26185737>
2763
2764         Reviewed by Darin Adler.
2765
2766         Added /api/update-triggerable to update the list of configurations (platform and test pairs)
2767         associated with a given triggerable, and make sync-buildbot.js use this JSON API before each
2768         syncing cycle so that the association gets updated automatically by simply updating the JSON.
2769
2770         * server-tests/api-manifest.js: Use const for imported modules.
2771         * server-tests/api-report-commits-tests.js: Removed unnecessary importing of crypto.
2772         * server-tests/resources/mock-data.js:
2773         (MockData.someTestId): Added.
2774         (MockData.somePlatformId): Added.
2775         (MockData.addMockData):
2776         * server-tests/tools-buildbot-triggerable-tests.js: Use const for imported modules. Also added
2777         a test for BuildbotTriggerable's updateTriggerable.
2778         * tools/js/buildbot-triggerable.js:
2779         (BuildbotTriggerable.prototype.updateTriggerable): Added. Find the list of all configurations
2780         associated with this triggeerable and post it to /api/update-triggerable.
2781         * tools/js/database.js: Added triggerable_configurations to the list of tables.
2782         * tools/js/remote.js:
2783         (RemoteAPI.prototype.postJSON): Print the whole response when JSON parsing fails for debugging.
2784         * tools/sync-buildbot.js:
2785         (syncLoop): Call BuildbotTriggerable's updateTriggerable before syncing.
2786
2787 2016-06-02  Ryosuke Niwa  <rniwa@webkit.org>
2788
2789         Build fix after r201564.
2790
2791         * public/v3/pages/analysis-category-page.js:
2792         (AnalysisCategoryPage.prototype.updateFromSerializedState):
2793         * public/v3/pages/create-analysis-task-page.js:
2794         (CreateAnalysisTaskPage.prototype.updateFromSerializedState):
2795         (CreateAnalysisTaskPage.prototype.render):
2796
2797 2016-05-31  Ryosuke Niwa  <rniwa@webkit.org>
2798
2799         v3 UI should support marking and unmarking outliers as well as hiding them
2800         https://bugs.webkit.org/show_bug.cgi?id=158248
2801
2802         Rubber-stamped by Chris Dumez.
2803
2804         Added the support for marking and unmarking a sequence of points as outliers. Unlike v2, we now support marking
2805         multiple points as outliers in a single click. Also fixed a bug that outliers are never explicitly hidden in v3 UI.
2806
2807         This patch splits ChartStyles.createChartSourceList into two functions: resolveConfiguration and createSourceList
2808         to separate the work of resolving platform and metric IDs to their respective model objects, and creating a source
2809         list used by TimeSeriesChart to fetch measurement sets. createSourceList is called again when filtering options are
2810         changed.
2811
2812         It also adds noCache option to TimeSeriesChart's fetchMeasurementSets, MeasurementSet's fetchBetween and
2813         _fetchPrimaryCluster to update the measurement sets after marking or unmarking points as outliers. In addition, it
2814         fixes a bug that the annotation bars for analysis tasks are not updated in charts page after creating an analysis
2815         task by adding noCache option to ChartPaneBase's fetchAnalysisTasks, AnalysisTask's fetchByPlatformAndMetric and
2816         _fetchSubset.
2817
2818         Finally, this patch splits ChartPane._makeAnchorToOpenPane into _makePopoverActionItem, _makePopoverOpenOnHover and
2819         _setPopoverVisibility for clarity.
2820
2821         * public/v3/components/chart-pane-base.js:
2822         (ChartPaneBase): Added _disableSampling and _showOutliers as instance variables.
2823         (ChartPaneBase.prototype.configure):
2824         (ChartPaneBase.prototype.isSamplingEnabled): Added.
2825         (ChartPaneBase.prototype.setSamplingEnabled): Added. When a filtering option is updated, recreate the source list
2826         so that TimeSeriesChart.setSourceList can re-fetch the measurement set JSONs.
2827         (ChartPaneBase.prototype.isShowingOutliers): Added.
2828         (ChartPaneBase.prototype.setShowOutliers): Added. Ditto for calling _updateSourceList.
2829         (ChartPaneBase.prototype._updateSourceList): Added.
2830         (ChartPaneBase.prototype.fetchAnalysisTasks): Renamed from _fetchAnalysisTasks. Now takes noCache as an argument
2831         instead of platform and metric IDs since they're on instance variables.
2832
2833         * public/v3/components/chart-styles.js:
2834         (ChartStyles.resolveConfiguration): Renamed from createChartSourceList. Just resolves platform and metric IDs.
2835         (ChartStyles.createSourceList): Extracted from createChartSourceList since it needs to be called when a filtering
2836         option is changed as well as when ChartPaneBase.prototype.configure is called.
2837         (ChartStyles.baselineStyle): Now takes filtering options.
2838         (ChartStyles.targetStyle): Ditto.
2839         (ChartStyles.currentStyle): Ditto.
2840
2841         * public/v3/components/interactive-time-series-chart.js:
2842         (InteractiveTimeSeriesChart.prototype.currentPoint): Find the point in _fetchedTimeSeries when
2843         _sampledTimeSeriesData hasn't been computed yet as a fallback (e.g. when the chart hasn't been rendered yet).
2844         (InteractiveTimeSeriesChart.prototype.selectedPoints): Added.
2845         (InteractiveTimeSeriesChart.prototype.firstSelectedPoint): Added.
2846         (InteractiveTimeSeriesChart.prototype.lockedIndicator): Added. Returns the current point if it's locked.
2847
2848         * public/v3/components/time-series-chart.js:
2849         (TimeSeriesChart.prototype.setDomain):
2850         (TimeSeriesChart.prototype.setSourceList): Added. Re-create _fetchedTimeSeries when filtering options have changed.
2851         Don't re-fetch measurement set JSONs here since showing outliers can be done entirely in the front end.
2852         (TimeSeriesChart.prototype.fetchMeasurementSets): Extracted out of setDomain. Now takes noCache as an argument.
2853         ChartPane._markAsOutlier
2854         (TimeSeriesChart.prototype.firstSampledPointBetweenTime): Added.
2855
2856         * public/v3/models/analysis-task.js:
2857         (AnalysisTask.fetchByPlatformAndMetric): Added noCache as an argument.
2858         (AnalysisTask._fetchSubset): Ditto.
2859
2860         * public/v3/models/measurement-adaptor.js:
2861         (MeasurementAdaptor.prototype.isOutlier): Added.
2862         (MeasurementAdaptor.prototype.applyToAnalysisResults): Add markedOutlier as a property on each point.
2863
2864         * public/v3/models/measurement-cluster.js:
2865         (MeasurementCluster.prototype.addToSeries): Fixed the bug that filtering outliers was broken as _markedOutlierIndex
2866         is undefined here. Use MeasurementAdaptor's isOutlier instead.
2867
2868         * public/v3/models/measurement-set.js:
2869         (MeasurementSet.prototype.fetchBetween): Added noCache as an argument. Reset _primaryClusterPromise and _allFetches
2870         when noCache is true since we need to re-fetch the primary cluster as well as all secondary clusters now.
2871         (MeasurementSet.prototype._fetchPrimaryCluster): Added noCache as an argument. Directly invoke the JSON API at
2872         /api/measurement-set to re-generate all clusters' JSON files instead of first fetching the cached version.
2873         (MeasurementSet.prototype._fetchSecondaryCluster):
2874         (MeasurementSet.prototype._didFetchJSON): Removed a bogus assertion since this function is called on secondary
2875         clusters as well as primary clusters.
2876         (MeasurementSet.prototype._addFetchedCluster): Reimplemented this function using an insertion sort. Also remove the
2877         existing entry if the fetch cluster should replace it.
2878
2879         * public/v3/models/time-series.js:
2880         (TimeSeries.prototype.dataBetweenPoints): Removed the dead code to filter out outliers. This is done in addToSeries
2881         of MeasurementCluster instead.
2882
2883         * public/v3/pages/chart-pane.js:
2884         (ChartPane): Renamed pane to popover since it was confusing to have a pane inside a pane class. As such, renamed
2885         _paneOpenedByClick to _lockedPopover.
2886         (ChartPane.prototype.serializeState): Added the code to serialize filtering options in the serialized state URL.
2887         (ChartPane.prototype.updateFromSerializedState): Ditto for parsing.
2888         (ChartPane.prototype._analyzeRange): Extracted out of render(). Also fixed a bug that the charts page don't show
2889         the newly created analysis task by invoking fetchAnalysisTasks with noCache set to true.
2890         (ChartPane.prototype._markAsOutlier): Added.
2891         (ChartPane.prototype._renderActionToolbar): A bunch of changes due to pane -> popover rename. Also added a popover
2892         for filtering options.
2893         (ChartPane.prototype._makePopoverActionItem): Extracted from _makeAnchorToOpenPane.
2894         (ChartPane.prototype._makePopoverOpenOnHover): Ditto.
2895         (ChartPane.prototype._setPopoverVisibility): Ditto.
2896         (ChartPane.prototype._renderFilteringPopover): Added.
2897         (ChartPane.htmlTemplate): Added a popover for specifying filtering options. Also added .popover on each popover.
2898         (ChartPane.cssTemplate): Updated the style to make use of .popover.
2899
2900         * public/v3/pages/charts-page.js:
2901         (ChartsPage.prototype.graphOptionsDidChange): Added. Updates the URL state when a filtering option is modified.
2902
2903         * public/v3/pages/dashboard-page.js:
2904         (DashboardPage.prototype._createChartForCell):
2905
2906         * public/v3/pages/page-router.js:
2907         (PageRouter.prototype._serializeHashQueryValue): Serialize a set of strings as | separated tokens.
2908         (PageRouter.prototype._deserializeHashQueryValue): Rewrote the function as the serialized URL can no longer be
2909         parsed as a JSON as | separated tokens can't be converted into a valid JSON construct with a simple regex.
2910
2911         * unit-tests/measurement-set-tests.js: Added a test case for fetchBetween with noCache=true.
2912
2913 2016-05-24  Ryosuke Niwa  <rniwa@webkit.org>
2914
2915         Another build fix after r201307.
2916
2917         * public/v3/pages/page-router.js:
2918         (PageRouter.prototype._deserializeHashQueryValue):
2919         (PageRouter.prototype._countOccurrences): Moved from _deserializeHashQueryValue.
2920
2921 2016-05-23  Ryosuke Niwa  <rniwa@webkit.org>
2922
2923         Build fix after r201307.
2924
2925         * public/v3/pages/chart-pane.js:
2926         (ChartPane.prototype.serializeState):
2927
2928 2016-05-23  Ryosuke Niwa  <rniwa@webkit.org>
2929
2930         Some applications truncates the last closing parenthesis in perf dashboard URL
2931         https://bugs.webkit.org/show_bug.cgi?id=157976
2932
2933         Reviewed by Tim Horton.
2934
2935         Unfortunately, different applications use different heuristics to determine the end of each URL. Two trailing
2936         parentheses, for example, is just fine in Radar as well as Apple Mail if the URL is short enough. Using other
2937         characters such as ] and } wouldn't work either because they would be %-escaped. At that point, we might as well
2938         as %-escape everything.
2939
2940         Work around the bug by parsing the URL as if it had one extra ')' if the parsing had failed. Also shorten the charts
2941         page's URL by avoid emitting "-null" for each pane when the pane doesn't have a currently selected point or selection.
2942         This improves the odds of the entire URL being recognized by various applications.
2943
2944         We could, in theory, implement some sort of a URL shorter but that can wait until when we support real user accounts.
2945
2946         * public/v3/pages/chart-pane.js:
2947         (ChartPane.prototype.serializeState): Don't serialize the selection or the current point if nothing is selected.
2948         * public/v3/pages/page-router.js:
2949         (PageRouter.prototype._deserializeHashQueryValue): Try parsing the value again with one extra ] at the end if
2950         the JSON parsing had failed.
2951
2952 2016-05-18  Ryosuke Niwa  <rniwa@webkit.org>
2953
2954         Perf dashboard "Add pane" should list first by test, then by machine
2955         https://bugs.webkit.org/show_bug.cgi?id=157880
2956
2957         Reviewed by Stephanie Lewis.
2958
2959         Reversed the order which tests and platforms are selected. Also split .pane-selector-container into #tests and
2960         #platform for the ease of DOM node manipulations.
2961
2962         * public/v3/components/pane-selector.js:
2963         (PaneSelector):
2964         (PaneSelector.prototype._renderPlatformList): Renamed from _renderPlatformLists since there is a single list
2965         for platforms. This list now disappears while a non-metric item is selected in the collection of test lists.
2966         e.g. "Speedometer" instead of its "Score" metric. Remember the last metric we rendered to avoid churning.
2967         (PaneSelector.prototype._renderTestLists): Render the top level tests once. The index of lists have been
2968         decreased by one since test lists are now inside #tests instead of appearing after the platform list.
2969         (PaneSelector.prototype._buildTestList): Don't filter tests since platform is chosen after tests now.
2970         (PaneSelector.prototype._replaceList):
2971         (PaneSelector.prototype._selectedItem): Don't reset the test path (specifies which subtest or metric is picked)
2972         when a platform is selected since it happens after a test metric is chosen now.
2973         (PaneSelector.prototype._clickedItem): Add a pane when a platform is clicked, not when a metric is clicked.
2974         (PaneSelector.cssTemplate):
2975
2976 2016-05-18  Ryosuke Niwa  <rniwa@webkit.org>
2977
2978         Analysis task should look for a git commit based on abridged hashes
2979         https://bugs.webkit.org/show_bug.cgi?id=157877
2980         <rdar://problem/26254374>
2981
2982         Reviewed by Chris Dumez.
2983
2984         Made /privileged-api/associate-commit look for commits using LIKE instead of an exact match.
2985         Associate the commit when there is exactly one match.
2986
2987         * public/include/commit-log-fetcher.php:
2988         (CommitLogFetcher::fetch_between):
2989         * public/include/db.php:
2990         (Database::escape_for_like): Extracted from CommitLogFetcher::fetch_between.
2991         * public/privileged-api/associate-commit.php:
2992         (main): Look for the commits using LIKE. Reject whenever there are multiple commits. We limit the number of
2993         matches to two for performance when the user specifies something that almost thousands of commits: e.g. "1".
2994         * public/v3/pages/analysis-task-page.js:
2995         (AnalysisTaskPage.prototype._associateCommit): Added human friendly error messages for mismatching commits.
2996
2997 2016-05-18  Ryosuke Niwa  <rniwa@webkit.org>
2998
2999         Unreviewed build fix. Use --date-order so that every child commit appears after its parent.
3000         Otherwise we'll hit a FailedToFindParentCommit error while submitting a commit that appears before its parent.
3001
3002         * tools/sync-commits.py:
3003         (GitRepository._fetch_all_hashes):
3004
3005 2016-05-18  Ryosuke Niwa  <rniwa@webkit.org>
3006
3007         Removed the erroneously committed debug code.
3008
3009         * tools/sync-commits.py:
3010         (GitRepository.fetch_commit):
3011
3012 2016-05-18  Ryosuke Niwa  <rniwa@webkit.org>
3013
3014         Perf dashboard should have a script to sync git commits
3015         https://bugs.webkit.org/show_bug.cgi?id=157867
3016
3017         Reviewed by Chris Dumez.
3018
3019         Added the support to pull from a Git repo to pull-svn.py and renamed it to sync-commits.py.
3020
3021         Added two classes SVNRepository and GitRepository which inherits from an abstract class, Repository.
3022         The code that fetches commit and format revision number / git hash is specialized in each.
3023
3024         * Install.md:
3025         * tools/pull-svn.py: Removed.
3026         * tools/sync-commits.py: Renamed from Websites/perf.webkit.org/tools/pull-svn.py.
3027         (main): Renamed --svn-config-json to --repository-config-json. Also made it robust against exceptions
3028         inside fetch_commits_and_submit of each Repository class.
3029         (load_repository): A factory function for SVNRepository and GitRepository.
3030         (Repository): Added.
3031         (Repository.__init__): Added.
3032         (Repository.fetch_commits_and_submit): Extracted from standalone fetch_commits_and_submit.
3033         (Repository.fetch_commit): Added. Implemented by a subclass.
3034         (Repository.format_revision): Ditto.
3035         (Repository.determine_last_reported_revision): Extracted from alonealone
3036         determine_first_revision_to_fetch. The fallback to use "oldest" has been moved to SVNRepository's
3037         fetch_commit since it doesn't work in Git.
3038         (Repository.fetch_revision_from_dasbhoard): Extracted from fetch_revision_from_dasbhoard.
3039         (SVNRepository): Added.
3040         (SVNRepository.__init__): Added.
3041         (SVNRepository.fetch_commit): Extracted from standalone fetch_commit_and_resolve_author and fetch_commit.
3042         (SVNRepository._resolve_author_name): Renamed from resolve_author_name_from_account.
3043         (SVNRepository.format_revision): Added.
3044         (GitRepository): Added.
3045         (GitRepository.__init__):
3046         (GitRepository.fetch_commit): Added. Fetches the list of all git hashes if needed, and finds the next hash.
3047         (GitRepository._find_next_hash): Added. Finds the first commit that appears after the specified hash.
3048         (GitRepository._fetch_all_hashes): Added. Gets the list of all git hashs chronologically (old to new).
3049         (GitRepository._run_git_command): Added.
3050         (GitRepository.format_revision): Added. Use the first 8 characters of the hash.
3051
3052 2016-05-17  Ryosuke Niwa  <rniwa@webkit.org>
3053
3054         Add a subtitle under platform name in the summary page
3055         https://bugs.webkit.org/show_bug.cgi?id=157809
3056
3057         Reviewed by Chris Dumez.
3058
3059         Add a description beneath the platform names.
3060
3061         * public/v3/pages/summary-page.js:
3062         (SummaryPage.prototype._constructTable): Add a br and a span if subtitle is present.
3063         (SummaryPage.cssTemplate): Added CSS rules for .subtitle.
3064
3065 2016-05-13  Ryosuke Niwa  <rniwa@webkit.org>
3066
3067         v3 UI shows full git hash instead of the first 8 characters for a blame range
3068         https://bugs.webkit.org/show_bug.cgi?id=157691
3069
3070         Reviewed by Stephanie Lewis.
3071
3072         Fixed the bug that v3 UI shows the full 40 character git hash instead of the first 8 character as done in v2 UI.
3073
3074         * public/v3/models/commit-log.js:
3075         (CommitLog.prototype.diff): Fixed the bug.
3076         * tools/run-tests.py:
3077         (main): Add the support for running a subset of tests as mocha does.
3078         * unit-tests/commit-log-tests.js: Added.
3079
3080 2016-05-13  Ryosuke Niwa  <rniwa@webkit.org>
3081
3082         Unreviewed. Added the missing executable bits.
3083
3084         * tools/bundle-v3-scripts.py: Added property svn:executable.
3085         * tools/detect-changes.js: Added property svn:executable.
3086         * tools/process-maintenance-backlog.py: Added property svn:executable.
3087
3088 2016-05-13  Ryosuke Niwa  <rniwa@webkit.org>
3089
3090         Summary page doesn't report some missing platforms
3091         https://bugs.webkit.org/show_bug.cgi?id=157670
3092
3093         Reviewed by Darin Adler.
3094
3095         This patch improves the warning text for missing platforms and fixes the bug that platforms that don't have
3096         any data reported for a given test would not be reported as missing.
3097
3098         * public/v3/pages/summary-page.js:
3099         (SummaryPage.prototype.render): Added instrumentations.
3100         (SummaryPage.prototype._constructRatioGraph): Always create both the ratio bar graph and the spinner icon.
3101         (SummaryPage.prototype._renderCell): Extracted from _constructRatioGraph. Toggle the displayed-ness of the
3102         spinner and the ratio bar graph in the cell by CSS for better performance.
3103         (SummaryPage.prototype._warningTextForGroup): Extracted from _constructRatioGraph. Rephrased warning text
3104         for clarity and adopted new API of SummaryPageConfigurationGroup.
3105         (SummaryPage.prototype._warningTextForGroup.mapAndSortByName): Added.
3106         (SummaryPage.prototype._warningTextForGroup.pluralizeIfNeeded): Added.
3107         (SummaryPage.cssTemplate): Added rules to toggle the visibility of spinner icons and bar graphs.
3108         (SummaryPageConfigurationGroup): Replaced this._warnings by more explicitly named this._missingPlatforms
3109         and this._platformsWithoutBaseline. Also add a platform to this._missingPlatforms if it didn't appear in
3110         any metrics. Note that adding a platform whenever it doesn't in any one metric would be incorrect since
3111         some tests uses a different test name on different platforms: e.g. PLT-Mac and PLT-iPhone.
3112         (SummaryPageConfigurationGroup.prototype.missingPlatforms): Added.
3113         (SummaryPageConfigurationGroup.prototype.platformsWithoutBaseline): Added.
3114         (SummaryPageConfigurationGroup.prototype._fetchAndComputeRatio):
3115
3116 2016-05-13  Ryosuke Niwa  <rniwa@webkit.org>