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