061f395ab907527f6750d8a7432b71c70c8fdb2e
[WebKit-https.git] / Websites / perf.webkit.org / ChangeLog
1 2017-05-31  Ryosuke Niwa  <rniwa@webkit.org>
2
3         Allow sync-buildbot.js to set a buildbot property only when patches are built
4         https://bugs.webkit.org/show_bug.cgi?id=172743
5
6         Rubber-stamped by Chris Dumez.
7
8         Added the ability to specify a buildbot property only when there are build requests to build a patch.
9
10         * tools/js/buildbot-syncer.js:
11         (BuildbotSyncer.prototype.scheduleRequest): Pass in the list of build requests that belong to the same test group.
12         (BuildbotSyncer.prototype.scheduleRequestInGroupIfAvailable): Ditto.
13         (BuildbotSyncer.prototype._propertiesForBuildRequest): Added the support for specifying a conditional property.
14         For the condition type of "built", we check if there was any other 
15         (BuildbotSyncer._parseRepositoryGroup): Added the support for "ifBuilt" conditional.
16
17         * tools/js/buildbot-triggerable.js:
18         (BuildbotTriggerable.prototype._scheduleRequestIfSlaveIsAvailable): Pass in the list of build requests that
19         belong to the same test group.
20         (BuildbotTriggerable.prototype._scheduleRequestWithLog): Ditto.
21
22         * unit-tests/buildbot-syncer-tests.js:  Added test case for newly added "ifBuilt" as well as specifying a patch.
23         Updated the various test cases per the addition of new argument to scheduleRequest, _propertiesForBuildRequest,
24         and scheduleRequestInGroupIfAvailable.
25         (createSampleBuildRequestWithPatch): Added.
26
27         * unit-tests/resources/mock-v3-models.js:
28         (MockModels.inject): Made "ios-svn-webkit" accept a WebKit patch and roots to allow new testing.
29
30 2017-05-30  Ryosuke Niwa  <rniwa@webkit.org>
31
32         sync-builedbot.js fails to schedule the second request to test with a patch
33         https://bugs.webkit.org/show_bug.cgi?id=172701
34
35         Reviewed by Antti Koivisto.
36
37         The bug was caused by an assertion failure in BuildbotTriggerable's _pullBuildbotOnAllSyncers failing to
38         take into account that for a test group with a patch could be associated with two syncers, one to build
39         a patch and another to run tests. Fixed the bug by differentiating the two types of syncers by buildSyncer
40         and testSyncer per test group.
41
42         * server-tests/tools-sync-buildbot-integration-tests.js: Extended a test case so that it would hit the
43         assertion without the fix.
44
45         * tools/js/buildbot-triggerable.js:
46         (BuildbotTriggerable.prototype.syncOnce): Use the right kind of the syncer to schedule a build or a test.
47         (BuildbotTriggerable.prototype._pullBuildbotOnAllSyncers): Associate a given syncer based on the kind of
48         the build request it processed, and assert accordingly.
49
50 2017-05-29  Ryosuke Niwa  <rniwa@webkit.org>
51
52         Fix UI glitches with a custom analysis test group with a patch
53         https://bugs.webkit.org/show_bug.cgi?id=172694
54
55         Reviewed by Sam Weinig.
56
57         Fix the following UI glitches with perf try bots:
58          - Retrying an A/B testing with a patch fails.
59          - A patch specified in an test group does not get specified in the configurator.
60          - Drag & dropping a patch doesn't work.
61          - Results for custom analysis tasks don't get shown.
62
63         * public/api/test-groups.php:
64         (main): Fix a bug that test group's platform does not match that of the request'ed platform. Since each test
65         group is associated with platform, just use that instead of querying test_configurations. This resulted in
66         the configurator not being able to find a triggerable in some cases.
67
68         * public/v3/components/custom-analysis-task-configurator.js:
69         (CustomAnalysisTaskConfigurator):
70         (CustomAnalysisTaskConfigurator.prototype.setCommitSets): Add patches in the commit set.
71         (CustomAnalysisTaskConfigurator.prototype._setUploadedFilesToUploader): Now clears the exiting uploaded files
72         Also renamed from _setUploadedFilesIfEmpty.
73         (CustomAnalysisTaskConfigurator.prototype._setPatchFiles): Added.
74         (CustomAnalysisTaskConfigurator.prototype.didConstructShadowTree): We no longer update the list of roots
75         for the comparsion when a new root is added to the baseline.
76         (CustomAnalysisTaskConfigurator.prototype._configureComparison): Copy over the list of patches and roots when
77         starting to configure the comparsion.
78
79         * public/v3/components/instant-file-uploader.js:
80         (InstantFileUploader.prototype.clear): Added.
81         (InstantFileUploader.prototype.didConstructShadowTree): Added event handlers for dragover & drop events to
82         allow specifying a patch and root using drag & drop. Unfortunately, this still doesn't work in WebKit due to
83         a bug in our shadow DOM implementation.
84         (InstantFileUploader.prototype._didFileInputChange):
85         (InstantFileUploader.prototype._uploadFiles): Extracted from _didFileInputChange.
86
87         * public/v3/pages/analysis-task-page.js:
88         (AnalysisTaskTestGroupPane.prototype.setAnalysisResults): No longer takes metric.
89         (AnalysisTaskTestGroupPane.cssTemplate): Removed unused rules. Also disallow flexing on the list of test groups
90         to avoid the name of a test froup from overflowing on top of the results pane.
91         (AnalysisTaskPage.prototype._assignTestResultsIfPossible): Set setAnalysisResults even when metric is not set
92         as is the case for a custom analysis task.
93         (AnalysisTaskPage.prototype._retryCurrentTestGroup): Use createWithCustomConfiguration to allow retrying of
94         an A/B testing with a patch in a custom analysis task.
95         (AnalysisTaskPage.prototype._createTestGroupAfterVerifyingCommitSetList):
96
97 2017-05-26  Ryosuke Niwa  <rniwa@webkit.org>
98
99         Show patches applied in each A/B testing build requests
100         https://bugs.webkit.org/show_bug.cgi?id=172636
101
102         Reviewed by Antti Koivisto.
103
104         List patches applied along side revisions inn the list of revisions for an A/B tesing build requests if there
105         are any patches applied.
106
107         * public/v3/components/test-group-revision-table.js:
108         (TestGroupRevisionTable.prototype._renderTable): Indicate which request is to build a patch and which one is
109         to run tests.
110         (TestGroupRevisionTable.prototype._buildCommitCell): Include the patch file's information when there is one.
111         We need to use the requested commit set instead of the one reported by testers or builders since they don't
112         include patch or root information.
113         (TestGroupRevisionTable.prototype._buildCustomRootsCell):
114         (TestGroupRevisionTable.prototype._buildFileInfo): Extracted from _buildCustomRootsCell.
115
116 2017-05-26  Ryosuke Niwa  <rniwa@webkit.org>
117
118         The queue page is broke when there is a custom analysis task
119         https://bugs.webkit.org/show_bug.cgi?id=172631
120
121         Reviewed by Antti Koivisto.
122
123         Fix the bug that we were always assuming each build request to have a test associated.
124
125         * public/v3/models/test-group.js:
126         (TestGroup.createAndRefetchTestGroups): Fixed the bug that we were referring to a non-existent variable task.
127         * public/v3/pages/build-request-queue-page.js:
128         (BuildRequestQueuePage.prototype._constructBuildRequestTable): Fixed the bug. Collect every request in the group
129         and then find the first test request's test name. Make it clear that we're waiting for a build as needed.
130
131 2017-05-25  Ryosuke Niwa  <rniwa@webkit.org>
132
133         Syncing script shouldn't schedule a build request when there is a build from another test group in progress
134         https://bugs.webkit.org/show_bug.cgi?id=172577
135         <rdar://problem/32395049>
136
137         Reviewed by Chris Dumez.
138
139         When a buildbot master gets restarted while there is an in-progress build and a pending build, the master will
140         re-schedule the currently running build, and this can result in multiple build requests from different test
141         groups being scheduled simultaneously.
142
143         sync-buildbot.js was supposed to recover from this state by only processing build requests from one test group
144         at a time and eventually come back to a state where only a single test group is running per buildbot slave.
145
146         We had a test for this particular case but it wasn't testing what it claimed to test. Rewriten the test case
147         and fixed the bug by explicitly checking this condition and treating it as if there is a pending build already
148         scheduled in the builder in this case.
149
150         * public/api/test-groups.php:
151         (main): Fixed a regression from r217397. Return the platform ID of the first request when none of the requets
152         have been processed yet or all of them had failed.
153         * server-tests/tools-buildbot-triggerable-tests.js: Rewritten a test case intended to cover this bug.
154         (.assertRequestAndResolve): Added.
155         * tools/js/buildbot-syncer.js:
156         (BuildbotSyncer.prototype.scheduleRequestInGroupIfAvailable): Fixed the bug. Avoid scheduling a new request on
157         this syncer if there is a build in progress for a test group different from that of the new request. Reuse the
158         code we had to deal with a pending build for this purpose.
159
160 2017-05-24  Ryosuke Niwa  <rniwa@webkit.org>
161
162         Opening an analysis task from the queue page is broken
163         https://bugs.webkit.org/show_bug.cgi?id=172559
164         <rdar://problem/32389708>
165
166         Rubber-stamped by Chris Dumez.
167
168         Fix the bug that opening the analysis task page from the queue page results in multiple assertion failures
169         as well as the list of test groups in the analysis task page not getting updated.
170
171         * public/v3/models/build-request.js:
172         (BuildRequest.prototype.updateSingleton): Because /api/build-requests/ do not include test groups, it's
173         possible for testGroup to be dynamically updated upon loading an analysis task page. Update _testGroup in
174         such instances instead of asserting that it doesn't happen.
175
176         * public/v3/models/data-model.js:
177         (DataModelObject.cachedFetch): Because various code to create model objects from the result of a JSON API
178         modify the fetched content in irreversible manner, e.g. `object.platform = Platform.findById(object.platform)`
179         we must return a fresh new content each time even if the result had been cached.
180
181         * public/v3/models/test-group.js:
182         (TestGroup.prototype.platform): Return this._platform as that's not available.
183
184         * public/v3/pages/analysis-task-page.js:
185         (AnalysisTaskPage):
186         (AnalysisTaskPage.prototype._resetVariables): Extracted from the constructor.
187         (AnalysisTaskPage.prototype.updateFromSerializedState): Reset all instance variables when opening a new
188         analysis task page. This would avoid showing the stale result even when fetching new test groups had failed.
189
190         * unit-tests/test-groups-tests.js: Added a test case for fetching the same test group twice. This used to hit
191         a problem in BuildRequest.constructBuildRequestsFromData which overrode platform property of each raw content
192         with a Platform model object because in the case of a cached fetch, we end up trying to look up the platform
193         again using the result of stringifying the Platform object instead of the platform ID included in the original
194         fetched content.
195         (sampleTestGroup): Added "platform" as included in the JSON API's response now.
196
197 2017-05-24  Ryosuke Niwa  <rniwa@webkit.org>
198
199         The commit log viewer can overlap the analysis results viewer
200         https://bugs.webkit.org/show_bug.cgi?id=172534
201
202         Rubber-stamped by Chris Dumez.
203
204         Allocate the padding on the right for the commit log viewer, and add a horizontal scrollbar
205         to the analysis results viewer instead of letting it expand beneath the commit log viewer.
206
207         * public/v3/pages/analysis-task-page.js:
208         (AnalysisTaskResultsPane.htmlTemplate):
209         (AnalysisTaskResultsPane.cssTemplate):
210
211 2017-05-24  Ryosuke Niwa  <rniwa@webkit.org>
212
213         Sycning script build fix after r217378.
214
215         * tools/sync-buildbot.js:
216         (syncLoop):
217
218 2017-05-23  Ryosuke Niwa  <rniwa@webkit.org>
219
220         Add the support for perf try bots to sync-buildbot.js
221         https://bugs.webkit.org/show_bug.cgi?id=172529
222
223         Rubber-stamped by Chris Dumez.
224
225         Make sync-buildbot.js schedule an A/B testing job with a patch or roots to buildbot.
226
227         Change the buildbot property format in the syncing script's configuration again to use a dictionary
228         with a single key of "revision", "patch", or "roots" to specify a revision, a patch, or a set of roots,
229         and simplified the structure of the configuration by always having "types" and "builders", and
230         make each entry in "configurations" refer to a list of types, platforms, and builders.
231
232         Since now there are build requests to build patches and run tests, "configurations" has been renamed to
233         "testConfigurations" and "buildConfigurations" have been added. Each entry in "buildConfigurations"
234         specifies a list of platforms and builders. Similarly in repository group configurations, the buildbot
235         properties for testing is now specified as "testProperties" and ones for building a patch is specified
236         in newly introduced "buildProperties".
237
238         * public/api/build-requests.php:
239         (update_builds): When a build request to build a patch fails, mark all subsequent requests as failed
240         since there is no way to run tests without a successful build.
241
242         * public/api/update-triggerable.php:
243         (main): Re-generate manifest.json after updating the triggerable. The lack of this re-generation was
244         the reason we had to manually GET /api/manifest in api-update-triggerable-tests.js.
245
246         * public/v3/models/build-request.js:
247         (BuildRequest.prototype.hasCompleted): Added.
248
249         * public/v3/models/manifest.js:
250         (Manifest.reset): Added. Extracted from MockData.resetV3Models in unit-tests/mock-data.js and
251         syncLoop in tools/sync-buildbot.js
252         (Manifest.fetch): Reset V3 models before fetching the manifest. This eliminates the need to manually
253         reset V3 models in syncLoop.
254
255         * public/v3/models/uploaded-file.js:
256         (UploadedFile.prototype.url): Use RemoteAPI.url to get the full URL instead of just a path.
257
258         * public/v3/remote.js:
259         (BrowserRemoteAPI.prototype.url): Added. Constructs the full URL.
260
261         * server-tests/api-update-triggerable-tests.js:
262         (.refetchManifest): Deleted. Now that /api/manifest re-generates manifest.json, we can simply call
263         Manifest.fetch instead.
264
265         * server-tests/resources/mock-data.js:
266         (MockData.resetV3Models): Calls Manifest.reset().
267         (MockData.addMockConfiguration): Extracted from addMockData.
268         (MockData.addMockData): Updated per the format change.
269         (MockData.mockTestSyncConfigWithSingleBuilder): Ditto.
270         (MockData.mockTestSyncConfigWithTwoBuilders): Ditto.
271         (MockData.runningBuild): Make buildNumber specifiable.
272         (MockData.finishedBuild): Ditto.
273
274         * server-tests/tools-buildbot-triggerable-tests.js: Updated configurations per the format change.
275         Now that now acceptsCustomRoots() for "system-and-webkit" must be true since we can't have a
276         repository group that which accepts a patch and not take roots.
277
278         * server-tests/tools-sync-buildbot-integration-tests.js: Added.
279         (createTriggerable): Added.
280         (createTestGroupWihPatch): Added.
281         (uploadRoot): Added.
282         (.assertAndResolveRequest): Added.
283         (.assertTestBuildHasFailed): Added.
284
285         * tools/js/buildbot-syncer.js:
286         (BuildbotSyncer): Added. _type as an instance variable to identify whether this buildbot builder
287         is a "builder" which builds a patch, builder, or a "tester" which runs a test. Also renamed
288         _testConfigurations to _configurations.
289         (BuildbotSyncer.prototype.addTestConfiguration): Assert that either the type of this syncer hasn't
290         been set or it's a tester.
291         (BuildbotSyncer.prototype.testConfigurations): Return [] when it's a builder.
292         (BuildbotSyncer.prototype.addBuildConfiguration): Added. Adds a platform to a builder.
293         (BuildbotSyncer.prototype.buildConfigurations): Added. Returns the list of configurations if this
294         syncer is a builder. Otherwise returns [].
295         (BuildbotSyncer.prototype.isTester): Added.
296         (BuildbotSyncer.prototype.matchesConfiguration):
297         (BuildbotSyncer.prototype._propertiesForBuildRequest): Updated to support the new format.
298         (BuildbotSyncer._loadConfig): Ditto. Optionally parse buildConfigurations.
299         (BuildbotSyncer._resolveBuildersWithPlatforms): Added. For each test or build configuration entry,
300         creates the list of configurations per builder and platform.
301         (BuildbotSyncer._parseRepositoryGroup): Added the support for parsing the new format with revision,
302         roots, and patch option types with a lot of validations as we're seeing a bit of combinatorial
303         explosion in the number of things that can go wrong. Also parse buildProperties optionally.
304         (BuildbotSyncer._parseRepositoryGroupPropertyTemplate): Added. A helper function to parse a set of
305         buildbot properties, validates its content, and invokes a callback if it's an dynamically resolved
306         type such as "revision" and "patch".
307         (BuildbotSyncer._validateAndMergeConfig): Updated per the format change. No longer allows "types",
308         "type", "platforms", and "platform" as they're explicity resolved in _resolveBuildersWithPlatforms.
309
310         * tools/js/buildbot-triggerable.js:
311         (BuildbotTriggerable.prototype.syncOnce):
312         (BuildbotTriggerable.prototype._validateRequests): Handle the case when a build request is not
313         associated with any test.
314         (BuildbotTriggerable.prototype._nextRequestInGroup): Return null when there is a build request to
315         build a patch which has not been completed (pending, scheduled, running, or failed). Since all
316         requests to build a patch has a negative order, those requests should all show up at the beginning.
317         (BuildbotTriggerable.prototype._scheduleRequestIfSlaveIsAvailable): Pick a new buildbot syncer when
318         scheduling the first request to build a patch or the first request to run a test. The first request
319         to run a test will always have order of 0, so it's a sufficient condition to find such a request.
320         On the other hand, the first request to build a patch can have a negative order number so we must
321         explicitly check if it's the first item in the ordered list of requests in the test group.
322
323         * tools/remote-server-relay.log: Added.
324
325         * tools/sync-buildbot.js:
326         (syncLoop): Fixed a bug we were not re-fetching the triggerable after updating the triggerable so
327         that Triggerable and related objects we have in the memory may not reflect what we just synced to
328         the perf dashboard. Also, we don't reset V3 models manually any more since Manifest.fetch does that.
329
330         * unit-tests/buildbot-syncer-tests.js: Added more test cases and updated existing test cases to test
331         exception messages explicitly since allowing any exception was resulting in some tests passing a
332         result of unrelated parsing error being thrown, etc...
333         (sampleiOSConfig): Updated per the format change.
334         (sampleiOSConfigWithExpansions): Ditto.
335         (smallConfiguration): Ditto.
336
337 2017-05-22  Dewei Zhu  <dewei_zhu@apple.com>
338
339         Fix the bug that sometimes analysis task results pane is missing.
340         https://bugs.webkit.org/show_bug.cgi?id=172404
341
342         Reviewed by Ryosuke Niwa.
343
344         AnalysisTaskPage._didFetchTask and AnalaysisTaskPage._fetchRelatedInfoForTaskId should be called in order.
345         The race between those two functions causes the analysis task results pane sometimes missing.
346
347         * public/v3/components/analysis-results-viewer.js:
348         (AnalysisResultsViewer.prototype.render): Fix the bug in r217173 that commitSet can be undefined.
349         * public/v3/pages/analysis-task-page.js:
350         (AnalysisTaskPage.prototype.updateFromSerializedState): Use arrow function to get rid of self variable.
351         Use `const` instead of var for constant variable. And call _didFetchTask before calling _fetchRelatedInfoForTaskId.
352         (AnalysisTaskPage.prototype._renderTaskNameAndStatus):
353         (AnalysisTaskPage.cssTemplate):
354
355 2017-05-19  Ryosuke Niwa  <rniwa@webkit.org>
356
357         Add a commit log viewer next to the analysis results viewer
358         https://bugs.webkit.org/show_bug.cgi?id=172399
359
360         Reviewed by Chris Dumez.
361
362         Add a commit log viewer next to the analysis results viewer, which visualizes the A/B testing results.
363
364         Also linkify the revisions in the table that shows the status of each A/B testing job,
365         and allow the prefix of "r" when associating a Subversion revision.
366
367         Finally, Fixed a bug that the list of commits associated with the analysis task were not re-rendered
368         when the list was updated by the user.
369
370         * public/v3/components/analysis-results-viewer.js:
371         (AnalysisResultsViewer): Added _selectorRadioButtonList as an instance variable. It's a list of radio
372         buttons to select a configuration (A/B) with a commit set. It's added to update the checked status of
373         radio buttons upon changing the currently selected test group.
374         (AnalysisResultsViewer.prototype.setTestGroups): Update the selected range to that of the currently
375         selected group.
376         (AnalysisResultsViewer.prototype.render): Fill _selectorRadioButtonList with radio buttons.
377
378         * public/v3/components/commit-log-viewer.js:
379         (CommitLogViewer): Added _showRepositoryName as an instance variable.
380         (CommitLogViewer.prototype.setShowRepositoryName): Added.
381         (CommitLogViewer.prototype.render): Hide the repository name when _showRepositoryName is false. This
382         is used in the newly added commit log viewer for the analysis results since we're showing a select
383         element with all the names of repositories above this component.
384
385         * public/v3/components/test-group-revision-table.js:
386         (TestGroupRevisionTable.prototype._buildCommitCell): Linkify the revisions if possible.
387
388         * public/v3/models/analysis-task.js:
389         (AnalysisTask.prototype.associateCommit): Strip "r" at the beginning for a Subversion like r12345
390         since that's the format we use to show to the user. This makes copy & paste easier.
391
392         * public/v3/pages/analysis-task-page.js:
393         (AnalysisTaskResultsPane): Added a bunch of new instance variables to show and update the commit log
394         viewer next to the analysis results viewer.
395         (AnalysisTaskResultsPane.prototype.setPoints): Create the list of repositories to show details.
396         (AnalysisTaskResultsPane.prototype.didConstructShadowTree): Re-render when the current selected test
397         group changes since that may have updated the selected range for A/B testing. Also re-render when
398         a new repository is selected to show details.
399         (AnalysisTaskResultsPane.prototype.render): Update the list of repositories and the commit log viewer.
400         (AnalysisTaskResultsPane.prototype._renderRepositoryList): Renders the list of repositories.
401         (AnalysisTaskResultsPane.prototype._updateCommitViewer): Updates the commit log viewer given the range
402         selected in the analysis results viewer.
403         (AnalysisTaskResultsPane.htmlTemplate): Updated the template.
404         (AnalysisTaskResultsPane.cssTemplate): Ditto.
405         (AnalysisTaskTestGroupPane.cssTemplate): Add a little space between the list of results and the table
406         of A/B testing jobs with revisions.
407         (AnalysisTaskPage.prototype.render): Fixed the bug that the list of commits associated with the task
408         is not updated when the list changes the task or the start point never changed when the list of commits
409         associated with the task changed. Make the lazily evaluated function compare the actual list of commits
410         so that it will invoke _renderCauseAndFixes when the list changes.
411         (AnalysisTaskPage.prototype._renderCauseAndFixes): Now renders a specific list.
412
413 2017-05-16  Ryosuke Niwa  <rniwa@webkit.org>
414
415         Another build fix. Added a missing null check.
416
417         * public/v3/components/custom-analysis-task-configurator.js:
418         (CustomAnalysisTaskConfigurator.prototype._setUploadedFilesIfEmpty):
419
420 2017-05-14  Ryosuke Niwa  <rniwa@webkit.org>
421
422         Build fix. Added a missing null check.
423
424         * public/v3/pages/analysis-task-page.js:
425         (AnalysisTaskConfiguratorPane.prototype.setTestGroups):
426
427 2017-05-11  Ryosuke Niwa  <rniwa@webkit.org>
428
429         Remove the code for old syncing script configuration in BuildbotSyncer
430         https://bugs.webkit.org/show_bug.cgi?id=171963
431
432         Reviewed by Chris Dumez.
433
434         Removed the code for specifying {"root": ~}, {"rootOptions": [~]}, and {"rootsExcluding": [~]} in buildbot
435         properties in the syncing script's configurations since they are no longer used after r215061.
436
437         Also removed the support for using "arguments" as an alias to "properties", and updated the tests accordingly.
438
439         * tools/js/buildbot-syncer.js:
440         (BuildbotSyncer._parseRepositoryGroup): Removed the unused code.
441         (BuildbotSyncer._validateAndMergeConfig): Just allow string values in properties.
442         (BuildbotSyncer._validateAndMergeProperties): Deleted.
443
444         * unit-tests/buildbot-syncer-tests.js:
445         (sampleiOSConfig): Use "properties" instead of "arguments" to specify the buildbot properties.
446         (sampleiOSConfigWithExpansions): Ditto.
447
448 2017-05-10  Ryosuke Niwa  <rniwa@webkit.org>
449
450         Another build fix after r215633 to make the bar graphs render even when the confidence intervals aren't available.
451
452         * public/v3/components/bar-graph-group.js:
453         (BarGraphGroup.prototype._computeRange):
454
455 2017-05-10  Ryosuke Niwa  <rniwa@webkit.org>
456
457         Build fix after r215633.
458
459         * public/v3/models/test-group.js:
460         (TestGroup.prototype._computeRequestedCommitSets):
461         (TestGroup.prototype.requestsForCommitSet):
462
463 2017-05-10  Ryosuke Niwa  <rniwa@webkit.org>
464
465         Add API to upload a patched build for a custom A/B testing
466         https://bugs.webkit.org/show_bug.cgi?id=171956
467
468         Reviewed by Chris Dumez.
469
470         Added /api/upload-root to upload a root file, the build product of a patch associated with a commit set.
471
472         Extracted more functions out of privileged-api/upload-file.php to uploaded-file-helpers.php to share code
473         with /api/upload-root.php.
474
475         * public/api/upload-root.php: Added.
476         (main):
477         (compute_commit_set_items_to_update): Find the list of commit set items to associate this root with.
478         A root can be associated with multiple repositories and there fore commit set items; e.g. if a software
479         is built from multiple repositories and there is a patch associated with one of them, the built product
480         must be associated with all those repositories.
481
482         * public/include/build-requests-fetcher.php:
483         (BuildRequestsFetcher::fetch_commits_for_set_if_needed): Include the root file is there is one.
484
485         * public/include/json-header.php:
486         (validate_arguments): Added the support for validating json string.
487         (verify_slave): Return the slave ID found.
488
489         * public/include/uploaded-file-helpers.php:
490         (validate_uploaded_file): Extracted from /privileged-api/upload-file to be shared with /api/upload-root.
491         (query_total_file_size): Ditto.
492         (create_uploaded_file_from_form_data): Ditto.
493         (upload_file_in_transaction): Ditto. Takes a lambda to do the extra work inside the transaction.
494
495         * public/privileged-api/upload-file.php:
496         (main):
497
498         * public/v3/models/build-request.js:
499         (BuildRequest.constructBuildRequestsFromData): Resolve the rootFIle of each commit set item.
500
501         * public/v3/models/commit-set.js:
502         (CommitSet): Added _repositoryToRootMap and _allRootFiles as instance variables.
503         (CommitSet.prototype.updateSingleton): Added. Previously, each commit set's states never changed after
504         its creation. After this patch, each item can be newly associated with a root so we must update its
505         _repositoryToRootMap and _allRootFiles. For simplicity, we update all states.
506         (CommitSet.prototype._updateFromObject): Extracted from the constructor.
507         (CommitSet.prototype.allRootFiles): Added. Includes custom roots and roots created for patches.
508         (CommitSet.prototype.rootForRepository): Added.
509         (CommitSet.prototype.equals): Fixed the bug that we were comparing _repositoryToPatchMap to
510         _repositoryToCommitMap, and added a check for _repositoryToRootMap.
511
512         * public/v3/models/test-group.js:
513         (TestGroup.prototype.task): Added.
514         (TestGroup.createWithTask):
515         (TestGroup.createWithCustomConfiguration):
516         (TestGroup.createAndRefetchTestGroups):
517         (TestGroup._fetchTestGroupsForTask): Deleted. Now fetchForTask takes a boolean argument: ignoreCache.
518         (TestGroup.findAllByTask): Added.
519         (TestGroup.fetchForTask): Renamed from fetchByTask.
520
521         * public/v3/pages/analysis-task-page.js:
522         (AnalysisTaskPage.prototype._fetchRelatedInfoForTaskId):
523
524         * server-tests/api-build-requests-tests.js:
525
526         * server-tests/api-upload-root-tests.js: Added. Added tests for /api/upload-root.
527         (makeReport): Added.
528         (addSlaveAndCreateRootFile): Added.
529         (createTestGroupWihPatch): Added.
530
531         * server-tests/privileged-api-create-test-group-tests.js:
532
533         * server-tests/resources/mock-data.js:
534         (MockData.sharedRepositoryId): Added.
535         (MockData.addMockData): Added "Shared" repository along with commits.
536
537 2017-05-10  Ryosuke Niwa  <rniwa@webkit.org>
538
539         Rename server-tests/api-update-triggerable.js to server-tests/api-update-triggerable-tests.js
540         https://bugs.webkit.org/show_bug.cgi?id=171905
541
542         Reviewed by Chris Dumez.
543
544         * server-tests/api-update-triggerable-tests.js: Renamed from server-tests/api-update-triggerable.js.
545
546 2017-04-30  Ryosuke Niwa  <rniwa@webkit.org>
547
548         Add the support for scheduling a A/B testing with a patch.
549         https://bugs.webkit.org/show_bug.cgi?id=171209
550
551         Reviewed by Chris Dumez.
552
553         Added the support for creating a custom test group with a patch applied.
554
555         First, each repository in a repository group has a boolean indicating whether a given repository can have
556         a patch applied or not. When any configuration in a test group contains a patch, we create build requests
557         without a test specified in order to "build" those patches. These build requests have negative order numbers
558         to differentiate them from regular build requests. We can't simply build ones with patches since there could
559         be differences in SDK, build options, etc... when patches are applied.
560
561         The JSON format for commit sets returned by /api/build-requests have been changed from using an array of
562         commit IDs to an array of dictionaries indicate commit and acceptsPatch boolean. /api/update-triggerable now
563         uses a dictionary with two keys: repository and acceptsPatch to specify a set of repositories associated with
564         a repository group, and /privileged-api-create-test-group uses a dictionary with two keys: revision and patch
565         instead of a revision string to specify commit sets.
566
567         Furthermore, the syncing script's configuration have been updated to use a dictionary of repository names to
568         an options dictionary instead of an array of repositories names. For now, the only supported option is
569         acceptsPatch but will be extended when we add the support for rolling back system components.
570         e.g. {"WebKit": {acceptsPatch: true}, "macOS": {}} instead of ["WebKit", "macOS"]
571
572         On the UI side, InstantFileUploader has been changed to accept only one file by default, and added a new method
573         allowMultipleFiles() to allow multiple files to be selected for custom roots. Also replaced the input element
574         with type=file by a button with a custom label to show labels such as "Apply a patch" or "Add a new root"
575         instead of the generic label like "choose a file".
576
577
578         * init-database.sql: Added trigrepo_accepts_patch to triggerable_repositories to indicate whether a given
579         repository can have a patch applied or not. Made request_test optional in build_requests for when a build
580         request is created to build patches. Such a build request have a negative request_order. Updated the related
581         constraints accordingly.
582
583         * public/admin/triggerables.php: Added the support for updating whether a given repository can have a patch
584         applied in each repository group. Only show the repositories in the repository group for this purpose since
585         there is no way to accept a patch on a repository without it being a part of the group.
586         (generate_repository_form): Now takes the markup for checkboxes instead of generating one itself.
587         (generate_repository_checkboxes): Now takes an array of repositories to generate checkboxes. The checkbox is
588         shown when the repository ID exists as a key in this array, and is checked when its value is true. The new
589         capability to skip repositories not in the array is used to hide repositories not associated with the group
590         in the list of checkboxes to indicate a repository accepts a patch.
591
592         * public/api/update-triggerable.php:
593         (main): Now updates the description and acceptsRoots states of each repository group, and sets acceptsPatch
594         boolean for each repository in the group if set in the update.
595         (validate_repository_groups): Use a reference to $repository_groups in order to set repository_id_list, which
596         contains an array of repository IDs to find the existing repository group that matches the set via
597         RepositoryGroupFinder's find_by_repositories. Also added a various validations for acceptsRoots, a dictionary
598         specifying repository and acceptsPatch.
599
600         * public/include/build-requests-fetcher.php:
601         (BuildRequestsFetcher::fetch_commits_for_set_if_needed): Instead of returning an array of commit IDs as
602         "commits", it now returns an array of dictionaries with "commit" and "patch" keys specifying the commit ID
603         and the patch file's ID respectively as "revisionItems". 
604         (BuildRequestsFetcher::add_uploaded_file): Added. Extracted from fetch_commits_for_set_if_needed. Used to
605         add either a patch file or a custom root file in the list of uploaded files in the result.
606
607         * public/include/manifest-generator.php:
608         (fetch_triggerables): Each element in repository group's "repositories" field is now an array of dictionaries
609         with "repository" and "acceptsPatch" as keys.
610
611         * public/include/repository-group-finder.php:
612         (RepositoryGroupFinder::__construct): Added a map for boolean indicating whether a given repository group
613         allows a patch on a repository. Used in /privileged-api/create-test-group.
614         (RepositoryGroupFinder::accepts_patch): Added.
615         (RepositoryGroupFinder::populate_map): Build up the map for acceptsPatch boolean per repository per group.
616
617         * public/privileged-api/create-test-group.php:
618         (main): Fixed a bug that we were not explicitly checking for a duplicate test group name (with a test). Create
619         build requests to "build" patches if there is any patch file specified.
620         (commit_sets_from_revision_sets): Updated to take a dictionary with "revision" and "patch" as keys to specify
621         a revision and a patch if any instead of just a revision string for each repository. Also validate that each
622         repository is allowed to have a patch once the repository group has been found for the set of repositories.
623         (ensure_commit_sets):
624
625         * public/v3/components/custom-analysis-task-configurator.js:
626         (CustomAnalysisTaskConfigurator): Added _patchUploaders as an instance variable, which is a dictionary of
627         configuration names to a map of InstantFileUploader's used to upload a patch. Also renamed _fileUploaders to
628         _customRootUploaders for clarity.
629         (CustomAnalysisTaskConfigurator.prototype.setCommitSets):
630         (CustomAnalysisTaskConfigurator.prototype.didConstructShadowTree.createRootUploader): Added.
631         (CustomAnalysisTaskConfigurator.prototype.didConstructShadowTree):
632         (CustomAnalysisTaskConfigurator.prototype._ensurePatchUploader): Added. Creates an instant file uploader for
633         patches. We only allow a single patch per repository.
634         (CustomAnalysisTaskConfigurator.prototype._computeCommitSet): Include a patch in the commit set as needed.
635         (CustomAnalysisTaskConfigurator.prototype._buildRevisionTable): Show the patch file uploader for repositories
636         which can have patches in the current repository group.
637         (CustomAnalysisTaskConfigurator.cssTemplate): Show borders between every rows instead of just between tbody's
638         now that each row can have a patch file uploader.
639
640         * public/v3/components/instant-file-uploader.js:
641         (InstantFileUploader): Added _fileInput and _allowMultipleFiles as instance variables. We now show a button
642         in the UI instead of an input with type=file. _fileInput is a hidden input with type=file used inside a click
643         event of the button to let the user pick a file.
644         (InstantFileUploader.prototype.allowMultipleFiles): Added. Allows this instance to accept multiple files.
645         (InstantFileUploader.prototype.didConstructShadowTree): Synthetically click on the hidden input element when
646         the newly added button element is clicked to open the browser's file picker.
647         (InstantFileUploader.prototype.render): Hide the button to add a file if this instance can only select one file
648         and there is already some file being uploaded in this instance.
649         (InstantFileUploader.htmlTemplate): Replaced the input element with type=file with a button. Its label comes
650         from the default slot content.
651
652         * public/v3/models/build-request.js:
653         (BuildRequest): Made the test optional.
654         (BuildRequest.prototype.isBuild): Returns true if this is a build request for building a patch.
655         (BuildRequest.prototype.isTest): Returns true if this is a build request for running tests.
656         (BuildRequest.constructBuildRequestsFromData): Create each commit log here instead of relying on CommitSet's
657         constructor to construct its commit logs. Also updated per the replacement of an array of commit IDs by
658         an array of dictionaries with commit and patch properties.
659
660         * public/v3/models/commit-set.js:
661         (CommitSet): Made _repositoryToCommitMap a real Map object. Also added _repositoryToPatchMap. Also got rid of
662         the code to instantiate commit logs since that's now done in BuildRequest.constructBuildRequestsFromData.
663         (CommitSet.prototype.commitForRepository):
664         (CommitSet.prototype.revisionForRepository):
665         (CommitSet.prototype.patchForRepository): Added.
666         (CommitSet.prototype.latestCommitTime): Modernized the code.
667         (CommitSet.prototype.equals): Modernized the code. Also added the check for patches.
668         (MeasurementCommitSet): Updated per the change to make _repositoryToCommitMap a real Map.
669         (CustomCommitSet.prototype.setRevisionForRepository):
670         (CustomCommitSet.prototype.equals): Added the check for patches.
671         (CustomCommitSet.prototype.revisionForRepository):
672         (CustomCommitSet.prototype.patchForRepository): Added.
673
674         * public/v3/models/manifest.js:
675         (Manifest._didFetchManifest): Updated per the replacement of an array of commit IDs by an array of dictionaries
676         with commit and patch properties.
677
678         * public/v3/models/repository.js:
679         (Repository.prototype.ownerId): Renamed from owner for clarity.
680
681         * public/v3/models/test-group.js:
682         (TestGroup): Modernized the code by using LazilyEvaluatedFunction. Removed _requestsAreInOrder since it's not
683         necessary anymore with LazilyEvaluatedFunction.
684         (TestGroup.prototype.addBuildRequest):
685         (TestGroup.prototype.test): Use the last build request's test since the first few requests could be requests to
686         build patches.
687         (TestGroup.prototype.platform): Ditto.
688         (TestGroup.prototype._lastRequest): Added.
689         (TestGroup.prototype._orderedBuildRequests): Added.
690         (TestGroup.prototype.repetitionCount): Only count the build requests for testing (skipping any requests to
691         build patches).
692         (TestGroup.prototype.requestedCommitSets): Simply call _computeRequestedCommitSetsLazily.
693         (TestGroup.prototype._computeRequestedCommitSets): Extracted from requestedCommitSets.
694         (TestGroup.prototype.requestsForCommitSet):
695         (TestGroup.prototype.labelForCommitSet): Rewritten. Just compute the label here instead of relying on
696         _commitSetToLabel since requestedSets is always of the length two at the moment.
697         (TestGroup._revisionSetsFromCommitSets): Specify both the revision and the patch in the revision set.        
698
699         * public/v3/models/triggerable.js:
700         (TriggerableRepositoryGroup): Added _patchAcceptingSet as an instance variable. Use
701         sortByNamePreferringOnesWithURL to sort repositories instead of simple sortByName.
702         (TriggerableRepositoryGroup.prototype.accepts): Added checks for the custom roots and patches.
703         (TriggerableRepositoryGroup.prototype.acceptsPatchForRepository): Added.
704
705         * server-tests/api-build-requests-tests.js: Updated the test cases per the replacement of an array of commit
706         IDs by an array of dictionaries with commit and patch properties.
707
708         * server-tests/api-manifest-tests.js: Updated the test case per the name of Repository's owner to ownerId.
709
710         * server-tests/api-update-triggerable.js: Updated the test case per the name of Repository's owner to ownerId,
711         and added a test case for updating whether a given repository group allows custom roots as well as patches
712         on repositories via /api/update-triggerable. 
713         (.updateWithOSXRepositoryGroup): Updated the sample syncing script configuration per the format change.
714         (.refetchManifest): Added.
715
716         * server-tests/privileged-api-create-test-group-tests.js: Updated per the syncing script configuration format
717         change. Also added a test for creating a test group with a duplicate name, which is expected to fail with 
718         DuplicateTestGroupName, and creating a test group with a patch both when it's allowed and when it's not allowed
719         in the matching repository group.
720         (.addTriggerableAndCreateTask): Updated per the format change.
721
722         * server-tests/resources/mock-data.js:
723         (MockData.addEmptyTriggerable): Added a metric and its configuration to make it appear in the manifest file.
724         The new test case in api-update-triggerable.js requires this.
725         (MockData.mockTestSyncConfigWithSingleBuilder): Updated per the syncing script configuration format change.
726         (MockData.mockTestSyncConfigWithTwoBuilders): Ditto.
727
728         * server-tests/tools-buildbot-triggerable-tests.js: Removed the useless assertions about test configurations,
729         and added assertions about custom roots and patches in the test case for updateTriggerables.
730
731         * tools/js/buildbot-syncer.js:
732         (BuildbotSyncer._parseRepositoryGroup): Made each assertion explicitly refer to the specific repository group
733         to make it more user friendly. Now each repository group uses a dictionary of repository names to its options
734         in the syncing script configurations. When parsed, we insert it as an array of dictionaries with repository ID
735         and acceptsPatch boolean specified separately since this is the format /api/update-triggerable expects.
736
737         * tools/js/buildbot-triggerable.js:
738         (BuildbotTriggerable.prototype.updateTriggerable):
739
740         * unit-tests/build-request-tests.js:
741         (sampleBuildRequestData): Updated per the commit sets format change in /api/build-requests.
742
743         * unit-tests/buildbot-syncer-tests.js: Updated the existing tests per various format changes and added a couple
744         of new test cases for the syncing script's configuration validation.
745         (sampleiOSConfig):
746         (smallConfiguration):
747         (createSampleBuildRequest):
748
749         * unit-tests/resources/mock-v3-models.js:
750         (MockModels.inject): Updated per the repository group format change.
751
752         * unit-tests/test-groups-tests.js:
753         (sampleTestGroup): Updated per the commit sets format change in /api/build-requests. 
754
755 2017-04-21  Ryosuke Niwa  <rniwa@webkit.org>
756
757         Rename commit_set_relationships to commit_set_items
758         https://bugs.webkit.org/show_bug.cgi?id=171143
759
760         Reviewed by Joseph Pecoraro.
761
762         Renamed commit_set_relationships to commit_set_items. Also added commitset_patch_file in the preparation to add
763         the support for applying patches in custom test groups. To migrate an existing database, run:
764
765         ```sql
766         BEGIN;
767         ALTER TABLE commit_set_relationships RENAME TO commit_set_items;
768         ALTER TABLE commit_set_items ADD COLUMN commitset_patch_file integer REFERENCES uploaded_files;
769         ALTER TABLE commit_set_items ADD CONSTRAINT commitset_with_patch_must_have_commit
770             CHECK (commitset_patch_file IS NULL OR commitset_commit IS NOT NULL);
771         END;
772         ```
773
774         * init-database.sql:
775         * public/include/build-requests-fetcher.php:
776         * public/privileged-api/create-test-group.php:
777         * server-tests/resources/mock-data.js:
778         (MockData.addMockData):
779         (MockData.addMockTestGroupWithGitWebKit):
780         * tools/js/database.js:
781
782 2017-04-21  Ryosuke Niwa  <rniwa@webkit.org>
783
784         Add the support for creating a custom test group in the analysis task page
785
786         Make it possible to create more custom test groups in the analysis task page
787         https://bugs.webkit.org/show_bug.cgi?id=171138
788
789         Rubber-stamped by Chris Dumez.
790
791         Extracted CustomConfigurationTestGroupForm out of CreateAnalysisTaskPage and added it to AnalysisTaskPage inside
792         AnalysisTaskConfiguratorPane. This allows configuration of a new test group within a custom analysis task.
793
794         * public/privileged-api/create-test-group.php:
795         (main): Fixed the bug that the triggerable wasn't resolved when creating a test group in a custom analysis task.
796
797         * public/v3/components/custom-analysis-task-configurator.js:
798         (CustomAnalysisTaskConfigurator.prototype.selectTests): Added. Used by CustomConfigurationTestGroupForm's
799         setConfigurations.
800         (CustomAnalysisTaskConfigurator.prototype.selectPlatform): Ditto.
801         (CustomAnalysisTaskConfigurator.prototype.setCommitSets): Ditto. 
802         (CustomAnalysisTaskConfigurator.prototype._setUploadedFilesIfEmpty): Added.
803         (CustomAnalysisTaskConfigurator.prototype._revisionMapFromCommitSet): Added.
804         (CustomAnalysisTaskConfigurator.prototype.render): Update the currently selected platforms and tests now that
805         they can be set externally via selectTests and selectPlatform.
806         (CustomAnalysisTaskConfigurator.prototype._renderTriggerableTests): Return the result of _renderRadioButtonList
807         so that the caller can update the currently selected tests without having to reconstruct the list.
808         (CustomAnalysisTaskConfigurator.prototype._renderTriggerablePlatforms): Ditto.
809         (CustomAnalysisTaskConfigurator.prototype._renderRadioButtonList): Renamed from _buildCheckboxList. Now returns
810         a function which updates the currently selected items. We still pretend that multiple items can be selected to
811         make it future-proof.
812
813         * public/v3/components/custom-configuration-test-group-form.js: Added.
814         (CustomConfigurationTestGroupForm): Added. Inherits from TestGroupForm. Extracted from CreateAnalysisTaskPage.
815         (CustomConfigurationTestGroupForm.prototype.setHasTask): Added.
816         (CustomConfigurationTestGroupForm.prototype.hasCommitSets): Added.
817         (CustomConfigurationTestGroupForm.prototype.setConfigurations): Added. Used by AnalysisTaskConfiguratorPane to
818         set the default configuration to what the latest test group used.
819         (CustomConfigurationTestGroupForm.prototype.startTesting): Added. Dispatches "startTesting" action with
820         platform, test, taskName in addition to what CustomizedTestGroupForm emits.
821         (CustomConfigurationTestGroupForm.prototype.didConstructShadowTree): Added.
822         (CustomConfigurationTestGroupForm.prototype.render): Added.
823         (CustomConfigurationTestGroupForm.prototype._updateTestGroupName): Added.
824         (CustomConfigurationTestGroupForm.cssTemplate): Added.
825         (CustomConfigurationTestGroupForm.htmlTemplate): Added.
826
827         * public/v3/components/test-group-form.js:
828         (TestGroupForm.cssTemplate): Make the form display: block.
829
830         * public/v3/index.html:
831
832         * public/v3/models/test-group.js:
833         (TestGroup.prototype.test): Added.
834         (TestGroup.prototype.platform): Added.
835         (TestGroup.createWithCustomConfiguration): Added. Creates a custom test group with an existing analysis task.
836
837         * public/v3/models/uploaded-file.js:
838         (UploadedFile): Fixed a bug that _deletedAt was set to a Date object even when object.deletedAt is null.
839
840         * public/v3/pages/analysis-task-page.js:
841         (AnalysisTaskConfiguratorPane): Added.
842         (AnalysisTaskConfiguratorPane.prototype.didConstructShadowTree): Added. Dispatch createCustomTestGroup action
843         in turn when receiving startTesting from CustomConfigurationTestGroupForm.
844         (AnalysisTaskConfiguratorPane.prototype.setTestGroups): Added.
845         (AnalysisTaskConfiguratorPane.prototype.render): Added.
846         (AnalysisTaskConfiguratorPane.htmlTemplate): Added. We override this instead of formContent to display the
847         "Start" button at the end instead of at the beginnning.
848         (AnalysisTaskConfiguratorPane.cssTemplate): Added.
849         (AnalysisTaskPage.prototype.didConstructShadowTree): Listen to createCustomTestGroup.
850         (AnalysisTaskPage.prototype.render): Hide AnalysisTaskConfiguratorPane when the analysis task is not custom.
851         (AnalysisTaskPage.prototype._showTestGroup): Let AnalysisTaskConfiguratorPane know of the current test group
852         so that it can update the default configuration if the user hasn't modified yet.
853         (AnalysisTaskPage.prototype._createCustomTestGroup): Added. 
854
855         * public/v3/pages/create-analysis-task-page.js:
856         (CreateAnalysisTaskPage.prototype.didConstructShadowTree):
857         (CreateAnalysisTaskPage.prototype._createAnalysisTaskWithGroup):
858         (CreateAnalysisTaskPage.prototype.render):
859         (CreateAnalysisTaskPage.prototype._renderMessage):
860         (CreateAnalysisTaskPage.htmlTemplate):
861         (CreateAnalysisTaskPage.cssTemplate):
862
863         * server-tests/privileged-api-create-test-group-tests.js: Added a test case for creating a custom test group for
864         an existing analysis task.
865
866         * server-tests/resources/mock-data.js:
867         (MockData.otherPlatformId): Added.
868         (MockData.addMockData): Added a test configuration for otherPlatformId.
869
870 2017-04-21  Ryosuke Niwa  <rniwa@webkit.org>
871
872         Make it possible to view results for sub tests and metrics in A/B testing
873         https://bugs.webkit.org/show_bug.cgi?id=170975
874
875         Reviewed by Chris Dumez.
876
877         Replaced TestGroupResultsTable, which was a single table that presented the test results with a set of revisions
878         each build request used, with TestGroupResultsViewer and TestGroupRevisionTable. TestGroupResultsViewer provides
879         an UI to look the results of sub-tests and sub-metrics and TestGroupRevisionTable provides an UI to display
880         the set of revisions each build request used. TestGroupRevisionTable can also show the list of custom roots now
881         that we've added UI to schedule an analysis task with a custom test group.
882
883         This patch extends BarGraphGroup to show multiple bars per SingleBarGraph using a canvas with bars indicating
884         their mean and confidence interval.
885
886         * browser-tests/index.html:
887         (ChartTest.importChartScripts): Include lazily-evaluated-function.js now that Test model object uses
888         LazilyEvaluatedFunction.
889
890         * public/v3/components/analysis-results-viewer.js:
891         (AnalysisResultsViewer.TestGroupStackingBlock.prototype._valuesForCommitSet):
892         (AnalysisResultsViewer.TestGroupStackingBlock.prototype._computeTestGroupStatus):
893
894         * public/v3/components/bar-graph-group.js:
895         (BarGraphGroup): No longer takes formatter. Added _computeRangeLazily and _showLabels as instance variables.
896         (BarGraphGroup.prototype.addBar): Now takes a list of values, their labels, mean, confidence interval, and
897         the colors of bar graphs shown for each value and the mean indicator.
898         (BarGraphGroup.prototype.showLabels): Added.
899         (BarGraphGroup.prototype.setShowLabels): Added.
900         (BarGraphGroup.prototype.range): Added.
901         (BarGraphGroup.prototype._computeRange): Renamed from updateGroupRendering. Now returns the range instead off
902         setting it to each bar, and each SingleBarGraph's render function uses the value via BarGraphGroup's range.
903         (BarGraph): Renamed from SingleBarGraph. Added various arguments introduced in addBar, and now stores various
904         lazily evaluated functions used for rendering.
905         (BarGraph.prototype.render): Rewritten to use canvas to draw bar graphs and show a label when group's
906         showLabels() returns true.
907         (BarGraph.prototype._resizeCanvas): Added.
908         (BarGraph.prototype._renderCanvas): Added.
909         (BarGraph.prototype._renderLabels): Added. We align the top of each label to the middle of each bar and shift it
910         back up by half the height of the label (0.4rem) using margin-top in css.
911         (BarGraph.htmlTemplate): Uses a canvas now.
912         (BarGraph.cssTemplate):
913
914         * public/v3/components/results-table.js:
915         (ResultsTable.prototype.renderTable): Updated per code changes to BarGraphGroup.
916         (ResultsTableRow.prototype.resultContent): Ditto.
917
918         * public/v3/components/test-group-results-table.js: Removed.
919         * public/v3/components/test-group-results-viewer.js: Added.
920         (TestGroupResultsViewer): Added. Shows a list of test results with bar graphs with mean and confidence interval
921         indicators. The results of sub tests and metrics can be expanded via "(Breakdown)" link shown below each test. 
922         (TestGroupResultsViewer.prototype.setTestGroup): Added.
923         (TestGroupResultsViewer.prototype.setAnalysisResults): Added.
924         (TestGroupResultsViewer.prototype.render): Added.
925         (TestGroupResultsViewer.prototype._renderResultsTable): Compute the depth of the test tree we show, and construct
926         the header rows. Each sub test is "indented" by a new column.
927         (TestGroupResultsViewer.prototype._buildRowForTest): Added. Build rows for metrics of the given test. Expand the
928         list of its child tests if it's in expandedTests. Otherwise add a link to "Breakdown" if it has any child tests.
929         (TestGroupResultsViewer.prototype._buildRowForMetric): Added. Builds rows of table cells to show the results for
930         the given metric for each configuration.
931         (TestGroupResultsViewer.prototype._buildRowForMetric.createConfigurationRow): Added. A helper to build cells for
932         a given configuration represented by a requested commit set.
933         (TestGroupResultsViewer.prototype._buildValueMap): Added. Creates a mappting between a requested commit set, and
934         the list of values, mean, etc... associated with the results for the commit set.
935         (TestGroupResultsViewer.prototype._buildEmptyCells): Added. A helper to create empty cells to indent sub tests.
936         (TestGroupResultsViewer.prototype._expandCurrentMetrics): Added. Highlights the current metrics and renders the
937         label for each bar in the results.
938         (TestGroupResultsViewer.htmlTemplate): Added.
939         (TestGroupResultsViewer.cssTemplate): Added.
940
941         * public/v3/components/test-group-revision-table.js: Added.
942         (TestGroupRevisionTable): Added. Renders the list of revisions requested for each test configuration as well as
943         ones used in actual testing, and additional repositories being reported (e.g. repositories for helper scripts).
944         (TestGroupRevisionTable.prototype.setTestGroup): Added.
945         (TestGroupRevisionTable.prototype.setAnalysisResults): Added.
946         (TestGroupRevisionTable.prototype.render): Added.
947         (TestGroupRevisionTable.prototype._renderTable): Added. The basic algorithm here is to first create a row entry
948         object for each build request, merge cells that use the same revision of the same repository, and then render
949         the entire table.
950         (TestGroupRevisionTable.prototype._buildCommitCell): Added.
951         (TestGroupRevisionTable.prototype._buildCustomRootsCell): Added.
952         (TestGroupRevisionTable.prototype._mergeCellsWithSameCommitsAcrossRows): Added. Compute rowspan for each cell
953         by traversing the rows that use the same revision per repository, and store it in rowCountByRepository while
954         adding the repository to each succeeding row's repositoriesToSkip.
955         (TestGroupRevisionTable.htmlTemplate): Added.
956         (TestGroupRevisionTable.cssTemplate): Added.
957
958         * public/v3/index.html:
959         * public/v3/models/analysis-results.js:
960         (AnalysisResults): Added _metricIds and _lazilyComputedHighestTests as instance variables.
961         (AnalysisResults.prototype.findResult): Renamed from find.
962         (AnalysisResults.prototype.highestTests): Added.
963         (AnalysisResults.prototype._computeHighestTests): Added. Finds the root tests for this analysis result.
964         (AnalysisResults.prototype.add): Update _metricIds.
965         (AnalysisResults.prototype.commitSetForRequest): Added. Returns the reported commit set for the build request.
966         This commit set contains the set of revisions reported to /api/report by A/B testers.
967         (AnalysisResultsView.prototype.resultForRequest): Renamed from resultForBuildId.
968
969         * public/v3/models/metric.js:
970         (Metric.prototype.relativeName): Added. Computes the relative name given the test/metric path. This function is
971         used to determine the label for each test/metric in TestGroupResultsViewer.
972         (Metric.prototype.aggregatorLabel): Extracted from label.
973         (Metric.prototype.label):
974         (Metric.makeFormatter): Added the default value of false to alwaysShowSign.
975
976         * public/v3/models/test-group.js:
977         (TestGroup.prototype.compareTestResults): Now takes a metric instead of retrieving it from the analysis task
978         since a custom analysis task may not have a metric associated with it.
979
980         * public/v3/models/test.js:
981         (Test): Added _computePathLazily as an instance variable.
982         (Test.prototype.path): Lazily computes the path now that this function can be called on the same test for many
983         times in TestGroupResultsViewer while computing relative names of tests and metrics.
984         (Test.prototype._computePath): Extracted path.
985         (Test.prototype.fullName): Modernized the code.
986         (Test.prototype.relativeName): Added.
987
988         * public/v3/models/uploaded-file.js:
989         (UploadedFile):
990         (UploadedFile.prototype.deletedAt): Added.
991         (UploadedFile.prototype.label): Added.
992         (UploadedFile.prototype.url): Added.
993
994         * public/v3/pages/analysis-task-page.js:
995         (AnalysisTaskTestGroupPane.prototype.setTestGroups):
996         (AnalysisTaskTestGroupPane.prototype.setAnalysisResults): Replaced setAnalysisResultsView. Now takes an
997         analysisResults instead of its view.
998         (AnalysisTaskTestGroupPane.prototype.render): No longer enqueues the results table and the retry form to render
999         since the results table no longer exists, and the retry form re-renders itself as needed.
1000         (AnalysisTaskTestGroupPane.htmlTemplate): Now uses test-group-results-viewer and test-group-revision-table
1001         instead of test-group-results-table, which has been removed.
1002         (AnalysisTaskTestGroupPane.cssTemplate):
1003         (AnalysisTaskPage.prototype._assignTestResultsIfPossible):
1004
1005         * public/v3/pages/create-analysis-task-page.js:
1006         (CreateAnalysisTaskPage.prototype._createAnalysisTaskWithGroup): Removed superflous console.log's.
1007
1008         * tools/js/v3-models.js: Import LazilyEvaluatedFunction now that it's used in the Test model.
1009
1010         * unit-tests/test-model-tests.js: Added.
1011
1012 2017-04-19  Ryosuke Niwa  <rniwa@webkit.org>
1013
1014         Another build fix after r215061. Clear TriggerableRepositoryGroup's static map in each iteration.
1015
1016         * tools/sync-buildbot.js:
1017         (syncLoop):
1018
1019 2017-04-18  Ryosuke Niwa  <rniwa@webkit.org>
1020
1021         Build fix after r215061.
1022
1023         There was a mismatch between the format updateTriggerable and /api/update-triggerable were using.
1024         Namely, each repository group was assumed to contain a name field in /api/update-triggerable
1025         but updateTriggerable was not including that at all.
1026
1027         We didn't catch this because the test for updateTriggerable also used the wrong format :(
1028
1029         * server-tests/tools-buildbot-triggerable-tests.js:
1030         * tools/js/buildbot-triggerable.js:
1031         (BuildbotTriggerable.prototype.updateTriggerable):
1032
1033 2017-04-14  Dewei Zhu  <dewei_zhu@apple.com>
1034
1035         Add sub-commit UI in commit log viewer.
1036         https://bugs.webkit.org/show_bug.cgi?id=170379
1037
1038         Reviewed by Ryosuke Niwa.
1039
1040         Add an API to return sub-commits for a given commit.
1041         Add sub-commit difference viewer into commit log viewer to show changed sub-commits between two commits.
1042         Add 'ownsSubCommits' info in 'api/commits' return values.
1043         Extend 'api/manifest' to include whether a repositories owns other repositories.
1044         Only show this sub-commit difference viewer when a repository owns other repositories and both commits owns sub-commits.
1045         Add unit tests for those new features.
1046
1047         * browser-tests/commit-log-viewer-tests.js: Updated test cases.
1048         * public/api/commits.php: Added 'sub-commits' to provide sub-commit for a given commit.
1049         * public/include/commit-log-fetcher.php: Added function to query sub-commit from database. Added 'repository' and 'ownsSubCommits' fields in returning commits.
1050         * public/v3/components/expand-collapse-button.js: Added.
1051         (ExpandCollapseButton):
1052         (ExpandCollapseButton.prototype.didConstructShadowTree): Changes state on click and dispatches 'toggle' event.
1053         (ExpandCollapseButton.sizeFactor):
1054         (ExpandCollapseButton.buttonContent):
1055         (ExpandCollapseButton.cssTemplate):
1056         * public/v3/components/commit-log-viewer.js:
1057         (CommitLogViewer.prototype._renderCommitList): Added sub-commit viewer if two adjacent commits both have sub-commits.
1058         (CommitLogViewer.cssTemplate):
1059         * public/v3/components/sub-commit-viewer.js: Added.
1060         (SubCommitViewer): Added 'SubCommitViewer' class to represent the sub-commit differences between two given commits.`
1061         (SubCommitViewer.prototype.didConstructShadowTree): Makes 'expand-collapse' button listen to 'toggle' event.
1062         (SubCommitViewer.prototype._toggleVisibility): Updates UI once 'expand-collapse' button is clicked.
1063         (SubCommitViewer.prototype.render): Render sub-commit view based on the state.
1064         (SubCommitViewer.prototype._renderSubcommitTable): Generates sub-commits difference table entries.
1065         (SubCommitViewer.htmlTemplate):
1066         (SubCommitViewer.cssTemplate):
1067         * public/v3/index.html: Added 'sub-commit-viewer.js' and 'expand-collapse-button.js'.
1068         * public/v3/models/commit-log.js:
1069         (CommitLog): Added '_subCommits'.
1070         (CommitLog.prototype.updateSingleton): Updates 'rawData.ownsSubCommits' as well.
1071         (CommitLog.prototype.ownsSubCommits):
1072         (CommitLog.prototype.subCommits): Added. Returns sub-commits.
1073         (CommitLog.prototype.fetchSubCommits): Added. Fetches sub-commits if haven't fetched them before.
1074         (CommitLog.prototype._buildSubCommitMap): Added. Creates a map which maps repositories to commits.
1075         (CommitLog.diffSubCommits): Added. Finds difference between two given commits.
1076         (CommitLog.fetchBetweenRevisions): Updated due to '_constructFromRawData' change.
1077         (CommitLog.fetchForSingleRevision): Updated due to '_constructFromRawData' change.
1078         (CommitLog._constructFromRawData): Removed first argument 'repository' as it can be determined by calling 'Repository.findById'.
1079         * public/v3/models/repository.js:
1080         (Repository):
1081         (Repository.prototype.owner): Returns the owner id.
1082         (Repository.prototype.ownedRepositories): Returns a list of repositories owned by this repository.
1083         * server-tests/api-commits-tests.js: Added tests for 'sub-commits' filter.
1084         * server-tests/api-manifest-tests.js: Added a test.
1085         * unit-tests/commit-log-tests.js: Added tests for 'fetchSubCommits' and 'diffSubCommits'.
1086         * unit-tests/resources/mock-v3-models.js: Added 'ownerRepository' and 'ownedRepository'.
1087
1088 2017-04-11  Ryosuke Niwa  <rniwa@webkit.org>
1089
1090         Retrying an A/B testing does not set the repetition count in some cases
1091         https://bugs.webkit.org/show_bug.cgi?id=170695
1092
1093         Reviewed by Joseph Pecoraro.
1094
1095         When selecting an existing A/B test group, the analysis task page automatically sets the repetition count
1096         of its retry to be that of the original test group. However, this information wasn't being passed correctly
1097         to the code that actually created a test group. As a result, the retried test group's repetition count does
1098         not match that of the original group or the number shown to the user on UI.
1099
1100         Fixed the bug by updating this._repetitionCount in setRepetitionCount.
1101
1102         * browser-tests/index.html:
1103         * browser-tests/test-group-form-tests.js: Added. Added tests.
1104         (.createTestGroupFormWithContext): Added.
1105         * public/v3/components/test-group-form.js:
1106         (TestGroupForm.prototype.setRepetitionCount):
1107         (TestGroupForm.formContent):
1108         (TestGroupForm):
1109
1110 2017-04-10  Ryosuke Niwa  <rniwa@webkit.org>
1111
1112         Add the UI for scheduling a A/B testing with a custom root
1113         https://bugs.webkit.org/show_bug.cgi?id=170622
1114
1115         Reviewed by Anders Carlsson.
1116
1117         This patch adds the support for creating a new analysis task with a custom darwinup roots. A follow up patch
1118         would update the syncing script to schedule such an A/B testing job to a buildbot instance.
1119
1120
1121         * ReadMe.md: Updated instructions for backing up and restoring the database so that it's easier to replace
1122         the file path for the backup.
1123
1124         * init-database.sql: Make task_platform and task_metric optional in each analysis task. Also added a column
1125         to store the root file in commit_set_relationships.
1126
1127         * public/api/build-requests.php:
1128         (main): Include the uploaded files.
1129
1130         * public/api/commits.php:
1131         (main): Added the support for querying the latest commits for a given platform. This is used in a new page
1132         to create a custom analysis task to autofill the latest revisions for a given platform.
1133
1134         * public/api/test-groups.php:
1135         (main): Include the uploaded files.
1136
1137         * public/include/build-requests-fetcher.php:
1138         (BuildRequestsFetcher::__construct): Added a list of uploaded_files and a map from its id.
1139         (BuildRequestsFetcher::uploaded_files): Added.
1140         (BuildRequestsFetcher::fetch_commits_for_set_if_needed): Added the support for including custom roots' id in
1141         each commit set, and inserting its meta data in the list of uplaoded files.
1142
1143         * public/include/commit-log-fetcher.php:
1144         (CommitLogFetcher::fetch_latest_for_platform): Added. Finds the latest commit for a given platform. Ideally,
1145         we should be finding the latest commit for a given platform, but this is very slow so instead find the commit
1146         of the latest build for a given platform.
1147
1148         * public/privileged-api/create-test-group.php:
1149         (main): Added the support for creating an analysis task along with a group.
1150         (commit_sets_from_revision_sets): Added the support for custom roots. Verify the specified uploaded file exists
1151         and include it in commit_set_relationships. Because commits and upload files are stored in a different column
1152         in commit_set_relationships, this function now stores the information for each row of commit_set_relationships
1153         except the commit set ID, which is unknown until the set is created, instead of a commit ID.
1154         (ensure_commit_sets): Made the each entry in a commit set a row instead of a commit ID as done. As this format
1155         is only by v2 UI and detect-changes.js, we don't add the support for specifying custom roots here.
1156
1157         * public/privileged-api/upload-file.php:
1158         (main): Fixed a typo. Also added one more error check.
1159
1160         * public/v3/components/custom-analysis-task-configurator.js: Added. The UI for selecting a test, a platform,
1161         and a set of revisions, as well as custom roots for a custom A/B testing job. The first set of revision with
1162         custom roots is referred as "baseline", and the second configuration is referred as "comparison" in this class.
1163         (CustomAnalysisTaskConfigurator):
1164         (CustomAnalysisTaskConfigurator.prototype.tests): Added.
1165         (CustomAnalysisTaskConfigurator.prototype.platform): Added.
1166         (CustomAnalysisTaskConfigurator.prototype.commitSets): Added. Returns a pair of baseline and comparsion if both
1167         have been configured by the user.
1168         (CustomAnalysisTaskConfigurator.prototype.didConstructShadowTree): Added.
1169         (CustomAnalysisTaskConfigurator.prototype._configureComparison): Added. Called when the user is to configu the
1170         "comparison" configuration.
1171         (CustomAnalysisTaskConfigurator.prototype.render): Added.
1172         (CustomAnalysisTaskConfigurator.prototype._renderTriggerableTests): Added. Renders the list of top-level tests
1173         that can be scheduled by a triggerable.
1174         (CustomAnalysisTaskConfigurator.prototype._renderTriggerablePlatforms): Added. Renders the list of platforms
1175         that can be schedule with the currently selected list of tests by a triggerable. Note that the current UI only
1176         lets the user select a single test but the intent is to allow multiple tests to be selected in the near future.
1177         (CustomAnalysisTaskConfigurator.prototype._buildCheckboxList): Added. Creates a list of radio boxes to select
1178         an item with a callback for each. It automatically sets "selected" class on the selected item. It's used to
1179         render both the list of tests and platforms.
1180         (CustomAnalysisTaskConfigurator.prototype._updateTriggerable): Added. Finds the triggerable for a given list of
1181         tests and platforms. Returns an error when some tests belong to another triggearalbe.
1182         (CustomAnalysisTaskConfigurator.prototype._updateRepositoryGroups): Added. Finds a repository group to use when
1183         the current triggerable has changed. We try to use the repository group of the same name if there is any, and
1184         defaults to the first repository group if there is none. This allows the set of repositories to be specified to
1185         more or less persist across different triggerables. For example, if iOS platforms and Mac platforms use two
1186         distinct triggerables , and both triggerables have two repository groups: one that only specify the OS and the
1187         other that specifies both teh OS and WebKit revision, then this code allows the choice the user had made to
1188         specify either just the OS or the OS and WebKit will be preserved when the user switches from an iOS platform
1189         to a Mac platform.
1190         (CustomAnalysisTaskConfigurator.prototype._updateCommitSetMap): Added. Create a commit set map, the format that
1191         TestGroup.createWithTask accepts given "baseline" and "comparison" commit sets. Pretend "comparison" is not set
1192         if two sets are identical since it makes no sense to schedule an A/B testing job when A and B are identical.
1193         (CustomAnalysisTaskConfigurator.prototype._computeCommitSet): Added. Creates a commit set using the revisions
1194         and the csutom roots the user had specified.
1195         (CustomAnalysisTaskConfigurator.prototype._renderRepositoryPanes): Added. Renders the pane to specify revisions
1196         and custom roots for "baseline" and "comparison".
1197         (CustomAnalysisTaskConfigurator.prototype._renderBaselineRevisionTable): Added.
1198         (CustomAnalysisTaskConfigurator.prototype._renderComparisonRevisionTable): Added.
1199         (CustomAnalysisTaskConfigurator.prototype._optionalRepositoryList): Added.
1200         (CustomAnalysisTaskConfigurator.prototype._buildRevisionTable): Added. Creates a table for specifying revisions
1201         and custom roots along with a list of repository groups to pick. The set of repositories and custom roots are
1202         shown at the all if all repository groups require them. Otherwise, they are grouped at the bottom as optional.
1203         (CustomAnalysisTaskConfigurator.prototype._buildRepositoryGroupList): Added.
1204         (CustomAnalysisTaskConfigurator.prototype._selectRepositoryGroup): Added.
1205         (CustomAnalysisTaskConfigurator.prototype._buildRevisionInput): Added. Creates an input element to specify
1206         a revision for a given repository. Autofills it with the latest commit for the currently selected platform if
1207         the user had not modified the field by the time the revisions are fetched.
1208         (CustomAnalysisTaskConfigurator.htmlTemplate): Added.
1209         (CustomAnalysisTaskConfigurator.cssTemplate): Added.
1210
1211         * public/v3/components/instant-file-uploader.js: Added. A form to upload a custom darwinup root in "baseline"
1212         or "comparison" configurations of CustomAnalysisTaskConfigurator. It's "instant" because it auto-detects when a
1213         file to be uploaded had already been uploaded elsewhere by checking its SHA-256 hash.
1214         (InstantFileUploader):
1215         (InstantFileUploader.prototype.hasFileToUpload): Added.
1216         (InstantFileUploader.prototype.uploadedFiles): Added.
1217         (InstantFileUploader.prototype.addUploadedFile): Added. It's called on the uploader for "comparison"
1218         configuration when the uploader for "baseline" configuration dipsatches "uploadedFile" action to automatically
1219         mirror the newly uploaded custom root to "comparision" configuration.
1220         (InstantFileUploader.prototype.didConstructShadowTree): Added.
1221         (InstantFileUploader.prototype.render): Added.
1222         (InstantFileUploader.prototype._renderUploadedFiles): Added. Renders the list of the uploaded files.
1223         (InstantFileUploader.prototype._renderPreuploadFiles): Added. Renders the list of the files to be uploaded with
1224         a progress bar.
1225         (InstantFileUploader.prototype._updateUploadStatus): Added. Updates the progress bar for uploading the file.
1226         (InstantFileUploader.prototype._formatUploadError): Added.
1227         (InstantFileUploader.prototype._didFileInputChange): Added. Called when the user picks a file to uploaded on
1228         the input element. Fetch the meta data for the uploaded file with the same SHA-256 hash if there is any, and
1229         start uploading the file if there isn't one.
1230         (InstantFileUploader.prototype._removeUploadedFile): Added.
1231         (InstantFileUploader.prototype._didUploadFile): Added. Move a file from the list of files to be uploaded to
1232         the list of uploaded files.
1233         (InstantFileUploader.htmlTemplate): Added.
1234         (InstantFileUploader.cssTemplate): Added.
1235
1236         * public/v3/index.html:
1237
1238         * public/v3/models/analysis-task.js:
1239         (AnalysisTask): Made platform and metric optional as it is now.
1240         (AnalysisTask.findByPlatformAndMetric): Skip analysis tasks without a platform or a metric.
1241         (AnalysisTask.prototype.isCustom): Added. Returns true for a custom analysis task.
1242         (AnalysisTask.fetchRelatedTasks): Skip custom analysis tasks.
1243         (AnalysisTask._constructAnalysisTasksFromRawData): Construct analysis tasks even if they were missing a metric
1244         or a platform instead of silently skipping them.
1245
1246         * public/v3/models/build-request.js:
1247         (BuildRequest.constructBuildRequestsFromData): Construct uploaded file objects returned by /api/build-requests.
1248
1249         * public/v3/models/commit-log.js:
1250         (CommitLog.fetchLatestCommitForPlatform): Added.
1251
1252         * public/v3/models/commit-set.js:
1253         (CommitSet): Added this._customRoots.
1254         (CommitSet.prototype.customRoots): Returns this._customRoots.
1255         (CommitSet.prototype.equals): Returns false when the set of custom roots are not equal.
1256         (CommitSet.areCustomRootsEqual): Added.
1257         (CustomCommitSet):
1258         (CustomCommitSet.prototype.equals): Added.
1259         (CustomCommitSet.prototype.customRoots): Added.
1260         (CustomCommitSet.prototype.addCustomRoot): Added.
1261
1262         * public/v3/models/manifest.js:
1263         (Manifest._didFetchManifest): Store fileUploadSizeLimit in the manifest as UploadedFile.fileUploadSizeLimit.
1264         This allows a file size check in the client size instead of uploading it to the server and receiving an error.
1265
1266         * public/v3/models/metric.js:
1267         (Metric.formatTime): Moved from ChartPaneStatusView to be also used by InstantFileUploader._renderUploadedFiles.
1268
1269         * public/v3/models/test-group.js:
1270         (TestGroup.prototype.createWithTask): Added.
1271         (TestGroup.prototype.createAndRefetchTestGroups):
1272         (TestGroup.prototype._revisionSetsFromCommitSets): Added. Extracted from createAndRefetchTestGroups.
1273         (TestGroup.prototype._fetchTestGroupsForTask): Added. Extracted from createAndRefetchTestGroups.
1274
1275         * public/v3/models/triggerable.js:
1276         (Triggerable.triggerablePlatformsForTests): Added.
1277         (Triggerable.sortByNamePreferringSmallerRepositories): Added.
1278
1279         * public/v3/models/uploaded-file.js:
1280         (UploadedFile.prototype.createdAt): Added.
1281         (UploadedFile.prototype.filename): Added.
1282         (UploadedFile.prototype.author): Added.
1283         (UploadedFile.prototype.size): Added.
1284         (UploadedFile.uploadFile): Added a client-side check for the file size using UploadedFile.fileUploadSizeLimit.
1285         (UploadedFile.fetchUnloadedFileWithIdenticalHash): Ditto. Also fixed a bug that 404 was resulting in a rejected
1286         promise instead of a resolved promise with null.
1287
1288         * public/v3/pages/analysis-category-page.js:
1289         (AnalysisCategoryPage.prototype._reconstructTaskList): Modernized the code. Added the support for platform and
1290         metric being null for some analysis tasks.
1291
1292         * public/v3/pages/analysis-task-page.js:
1293         (AnalysisTaskPage.prototype._didFetchTask): Don't fetch the measurement set or create a chart for custom tasks.
1294         (AnalysisTaskPage.prototype.render): Don't display the charts or the stacking table for custom tasks.
1295         (AnalysisTaskPage.prototype._renderTaskNameAndStatus): Don't try to show the full test name for custom tasks
1296         since it's not associated with exactly one pair.
1297
1298         * public/v3/pages/chart-pane-status-view.js:
1299         (ChartPaneStatusView.prototype._renderBuildRevisionTable):
1300         (ChartPaneStatusView.prototype._formatTime): Moved to Metric.formatTime.
1301
1302         * public/v3/pages/chart-pane.js:
1303         (ChartPane.prototype._analyzeRange): Set inProgress to true to hide CustomAnalysisTaskConfigurator in
1304         CreateAnalysisTaskPage when creating a non-custom analysis task for a specific range.
1305
1306         * public/v3/pages/create-analysis-task-page.js:
1307         (CreateAnalysisTaskPage): This page now shows CustomAnalysisTaskConfigurator by default, and lets a user create
1308         a custom analysis task by picking a test, a platform, and a set of revisions and custom darwinup roots.
1309         (CreateAnalysisTaskPage.prototype.updateFromSerializedState): Show a message when inProgress is set. This is
1310         the old behavior of this page.
1311         (CreateAnalysisTaskPage.prototype.didConstructShadowTree): Added.
1312         (CreateAnalysisTaskPage.prototype._createAnalysisTaskWithGroup): Added.
1313         (CreateAnalysisTaskPage.prototype.render):
1314         (CreateAnalysisTaskPage.prototype._renderMessage): Added. Hides CustomAnalysisTaskConfigurator and the select
1315         element to specify the numebr of iterations when a message is set.
1316         (CreateAnalysisTaskPage.htmlTemplate):
1317         (CreateAnalysisTaskPage.cssTemplate):
1318
1319         * public/v3/pages/page-router.js:
1320         (PageRouter.prototype.route): Always enqueue the page to re-render when the route has changed.
1321
1322         * server-tests/api-build-requests-tests.js: Updated test cases now that the response contains a list of
1323         uploaded files associated with build requests.
1324
1325         * server-tests/privileged-api-create-test-group-tests.js: Added test cases for creating a custom analysis task
1326         and a test group with custom roots. 
1327
1328         * server-tests/resources/mock-data.js:
1329         (MockData.addMockData): Updated the mock data to satisfy new constraint on analysis-tasks table.
1330
1331         * tools/js/remote.js: Include global.FormData from form-data.js.
1332
1333         * unit-tests/build-request-tests.js:
1334         (sampleBuildRequestData): Updated the mock response.
1335         * unit-tests/buildbot-syncer-tests.js:
1336         (createSampleBuildRequest): Ditto.
1337         * unit-tests/test-groups-tests.js:
1338         (sampleTestGroup): Ditto.
1339
1340 2017-04-10  Commit Queue  <commit-queue@webkit.org>
1341
1342         Unreviewed, rolling out r215202.
1343         https://bugs.webkit.org/show_bug.cgi?id=170694
1344
1345         Committed incorrectly (Requested by rniwa on #webkit).
1346
1347         Reverted changeset:
1348
1349         "Add the UI for scheduling a A/B testing with a custom root"
1350         https://bugs.webkit.org/show_bug.cgi?id=170622
1351         http://trac.webkit.org/changeset/215202
1352
1353 2017-04-10  Ryosuke Niwa  <rniwa@webkit.org>
1354
1355         Add the UI for scheduling a A/B testing with a custom root
1356         https://bugs.webkit.org/show_bug.cgi?id=170622
1357
1358         Reviewed by Anders Carlsson.
1359
1360         This patch adds the support for creating a new analysis task with a custom darwinup roots. A follow up patch
1361         would update the syncing script to schedule such an A/B testing job to a buildbot instance.
1362
1363
1364         * ReadMe.md: Updated instructions for backing up and restoring the database so that it's easier to replace
1365         the file path for the backup.
1366
1367         * init-database.sql: Make task_platform and task_metric optional in each analysis task. Also added a column
1368         to store the root file in commit_set_relationships.
1369
1370         * public/api/build-requests.php:
1371         (main): Include the uploaded files.
1372
1373         * public/api/commits.php:
1374         (main): Added the support for querying the latest commits for a given platform. This is used in a new page
1375         to create a custom analysis task to autofill the latest revisions for a given platform.
1376
1377         * public/api/test-groups.php:
1378         (main): Include the uploaded files.
1379
1380         * public/include/build-requests-fetcher.php:
1381         (BuildRequestsFetcher::__construct): Added a list of uploaded_files and a map from its id.
1382         (BuildRequestsFetcher::uploaded_files): Added.
1383         (BuildRequestsFetcher::fetch_commits_for_set_if_needed): Added the support for including custom roots' id in
1384         each commit set, and inserting its meta data in the list of uplaoded files.
1385
1386         * public/include/commit-log-fetcher.php:
1387         (CommitLogFetcher::fetch_latest_for_platform): Added. Finds the latest commit for a given platform. Ideally,
1388         we should be finding the latest commit for a given platform, but this is very slow so instead find the commit
1389         of the latest build for a given platform.
1390
1391         * public/privileged-api/create-test-group.php:
1392         (main): Added the support for creating an analysis task along with a group.
1393         (commit_sets_from_revision_sets): Added the support for custom roots. Verify the specified uploaded file exists
1394         and include it in commit_set_relationships. Because commits and upload files are stored in a different column
1395         in commit_set_relationships, this function now stores the information for each row of commit_set_relationships
1396         except the commit set ID, which is unknown until the set is created, instead of a commit ID.
1397         (ensure_commit_sets): Made the each entry in a commit set a row instead of a commit ID as done. As this format
1398         is only by v2 UI and detect-changes.js, we don't add the support for specifying custom roots here.
1399
1400         * public/privileged-api/upload-file.php:
1401         (main): Fixed a typo. Also added one more error check.
1402
1403         * public/v3/components/custom-analysis-task-configurator.js: Added. The UI for selecting a test, a platform,
1404         and a set of revisions, as well as custom roots for a custom A/B testing job. The first set of revision with
1405         custom roots is referred as "baseline", and the second configuration is referred as "comparison" in this class.
1406         (CustomAnalysisTaskConfigurator):
1407         (CustomAnalysisTaskConfigurator.prototype.tests): Added.
1408         (CustomAnalysisTaskConfigurator.prototype.platform): Added.
1409         (CustomAnalysisTaskConfigurator.prototype.commitSets): Added. Returns a pair of baseline and comparsion if both
1410         have been configured by the user.
1411         (CustomAnalysisTaskConfigurator.prototype.didConstructShadowTree): Added.
1412         (CustomAnalysisTaskConfigurator.prototype._configureComparison): Added. Called when the user is to configu the
1413         "comparison" configuration.
1414         (CustomAnalysisTaskConfigurator.prototype.render): Added.
1415         (CustomAnalysisTaskConfigurator.prototype._renderTriggerableTests): Added. Renders the list of top-level tests
1416         that can be scheduled by a triggerable.
1417         (CustomAnalysisTaskConfigurator.prototype._renderTriggerablePlatforms): Added. Renders the list of platforms
1418         that can be schedule with the currently selected list of tests by a triggerable. Note that the current UI only
1419         lets the user select a single test but the intent is to allow multiple tests to be selected in the near future.
1420         (CustomAnalysisTaskConfigurator.prototype._buildCheckboxList): Added. Creates a list of radio boxes to select
1421         an item with a callback for each. It automatically sets "selected" class on the selected item. It's used to
1422         render both the list of tests and platforms.
1423         (CustomAnalysisTaskConfigurator.prototype._updateTriggerable): Added. Finds the triggerable for a given list of
1424         tests and platforms. Returns an error when some tests belong to another triggearalbe.
1425         (CustomAnalysisTaskConfigurator.prototype._updateRepositoryGroups): Added. Finds a repository group to use when
1426         the current triggerable has changed. We try to use the repository group of the same name if there is any, and
1427         defaults to the first repository group if there is none. This allows the set of repositories to be specified to
1428         more or less persist across different triggerables. For example, if iOS platforms and Mac platforms use two
1429         distinct triggerables , and both triggerables have two repository groups: one that only specify the OS and the
1430         other that specifies both teh OS and WebKit revision, then this code allows the choice the user had made to
1431         specify either just the OS or the OS and WebKit will be preserved when the user switches from an iOS platform
1432         to a Mac platform.
1433         (CustomAnalysisTaskConfigurator.prototype._updateCommitSetMap): Added. Create a commit set map, the format that
1434         TestGroup.createWithTask accepts given "baseline" and "comparison" commit sets. Pretend "comparison" is not set
1435         if two sets are identical since it makes no sense to schedule an A/B testing job when A and B are identical.
1436         (CustomAnalysisTaskConfigurator.prototype._computeCommitSet): Added. Creates a commit set using the revisions
1437         and the csutom roots the user had specified.
1438         (CustomAnalysisTaskConfigurator.prototype._renderRepositoryPanes): Added. Renders the pane to specify revisions
1439         and custom roots for "baseline" and "comparison".
1440         (CustomAnalysisTaskConfigurator.prototype._renderBaselineRevisionTable): Added.
1441         (CustomAnalysisTaskConfigurator.prototype._renderComparisonRevisionTable): Added.
1442         (CustomAnalysisTaskConfigurator.prototype._optionalRepositoryList): Added.
1443         (CustomAnalysisTaskConfigurator.prototype._buildRevisionTable): Added. Creates a table for specifying revisions
1444         and custom roots along with a list of repository groups to pick. The set of repositories and custom roots are
1445         shown at the all if all repository groups require them. Otherwise, they are grouped at the bottom as optional.
1446         (CustomAnalysisTaskConfigurator.prototype._buildRepositoryGroupList): Added.
1447         (CustomAnalysisTaskConfigurator.prototype._selectRepositoryGroup): Added.
1448         (CustomAnalysisTaskConfigurator.prototype._buildRevisionInput): Added. Creates an input element to specify
1449         a revision for a given repository. Autofills it with the latest commit for the currently selected platform if
1450         the user had not modified the field by the time the revisions are fetched.
1451         (CustomAnalysisTaskConfigurator.htmlTemplate): Added.
1452         (CustomAnalysisTaskConfigurator.cssTemplate): Added.
1453
1454         * public/v3/components/instant-file-uploader.js: Added. A form to upload a custom darwinup root in "baseline"
1455         or "comparison" configurations of CustomAnalysisTaskConfigurator. It's "instant" because it auto-detects when a
1456         file to be uploaded had already been uploaded elsewhere by checking its SHA-256 hash.
1457         (InstantFileUploader):
1458         (InstantFileUploader.prototype.hasFileToUpload): Added.
1459         (InstantFileUploader.prototype.uploadedFiles): Added.
1460         (InstantFileUploader.prototype.addUploadedFile): Added. It's called on the uploader for "comparison"
1461         configuration when the uploader for "baseline" configuration dipsatches "uploadedFile" action to automatically
1462         mirror the newly uploaded custom root to "comparision" configuration.
1463         (InstantFileUploader.prototype.didConstructShadowTree): Added.
1464         (InstantFileUploader.prototype.render): Added.
1465         (InstantFileUploader.prototype._renderUploadedFiles): Added. Renders the list of the uploaded files.
1466         (InstantFileUploader.prototype._renderPreuploadFiles): Added. Renders the list of the files to be uploaded with
1467         a progress bar.
1468         (InstantFileUploader.prototype._updateUploadStatus): Added. Updates the progress bar for uploading the file.
1469         (InstantFileUploader.prototype._formatUploadError): Added.
1470         (InstantFileUploader.prototype._didFileInputChange): Added. Called when the user picks a file to uploaded on
1471         the input element. Fetch the meta data for the uploaded file with the same SHA-256 hash if there is any, and
1472         start uploading the file if there isn't one.
1473         (InstantFileUploader.prototype._removeUploadedFile): Added.
1474         (InstantFileUploader.prototype._didUploadFile): Added. Move a file from the list of files to be uploaded to
1475         the list of uploaded files.
1476         (InstantFileUploader.htmlTemplate): Added.
1477         (InstantFileUploader.cssTemplate): Added.
1478
1479         * public/v3/index.html:
1480
1481         * public/v3/models/analysis-task.js:
1482         (AnalysisTask): Made platform and metric optional as it is now.
1483         (AnalysisTask.findByPlatformAndMetric): Skip analysis tasks without a platform or a metric.
1484         (AnalysisTask.prototype.isCustom): Added. Returns true for a custom analysis task.
1485         (AnalysisTask.fetchRelatedTasks): Skip custom analysis tasks.
1486         (AnalysisTask._constructAnalysisTasksFromRawData): Construct analysis tasks even if they were missing a metric
1487         or a platform instead of silently skipping them.
1488
1489         * public/v3/models/build-request.js:
1490         (BuildRequest.constructBuildRequestsFromData): Construct uploaded file objects returned by /api/build-requests.
1491
1492         * public/v3/models/commit-log.js:
1493         (CommitLog.fetchLatestCommitForPlatform): Added.
1494
1495         * public/v3/models/commit-set.js:
1496         (CommitSet): Added this._customRoots.
1497         (CommitSet.prototype.customRoots): Returns this._customRoots.
1498         (CommitSet.prototype.equals): Returns false when the set of custom roots are not equal.
1499         (CommitSet.areCustomRootsEqual): Added.
1500         (CustomCommitSet):
1501         (CustomCommitSet.prototype.equals): Added.
1502         (CustomCommitSet.prototype.customRoots): Added.
1503         (CustomCommitSet.prototype.addCustomRoot): Added.
1504
1505         * public/v3/models/manifest.js:
1506         (Manifest._didFetchManifest): Store fileUploadSizeLimit in the manifest as UploadedFile.fileUploadSizeLimit.
1507         This allows a file size check in the client size instead of uploading it to the server and receiving an error.
1508
1509         * public/v3/models/metric.js:
1510         (Metric.formatTime): Moved from ChartPaneStatusView to be also used by InstantFileUploader._renderUploadedFiles.
1511
1512         * public/v3/models/test-group.js:
1513         (TestGroup.prototype.createWithTask): Added.
1514         (TestGroup.prototype.createAndRefetchTestGroups):
1515         (TestGroup.prototype._revisionSetsFromCommitSets): Added. Extracted from createAndRefetchTestGroups.
1516         (TestGroup.prototype._fetchTestGroupsForTask): Added. Extracted from createAndRefetchTestGroups.
1517
1518         * public/v3/models/triggerable.js:
1519         (Triggerable.triggerablePlatformsForTests): Added.
1520         (Triggerable.sortByNamePreferringSmallerRepositories): Added.
1521
1522         * public/v3/models/uploaded-file.js:
1523         (UploadedFile.prototype.createdAt): Added.
1524         (UploadedFile.prototype.filename): Added.
1525         (UploadedFile.prototype.author): Added.
1526         (UploadedFile.prototype.size): Added.
1527         (UploadedFile.uploadFile): Added a client-side check for the file size using UploadedFile.fileUploadSizeLimit.
1528         (UploadedFile.fetchUnloadedFileWithIdenticalHash): Ditto. Also fixed a bug that 404 was resulting in a rejected
1529         promise instead of a resolved promise with null.
1530
1531         * public/v3/pages/analysis-category-page.js:
1532         (AnalysisCategoryPage.prototype._reconstructTaskList): Modernized the code. Added the support for platform and
1533         metric being null for some analysis tasks.
1534
1535         * public/v3/pages/analysis-task-page.js:
1536         (AnalysisTaskPage.prototype._didFetchTask): Don't fetch the measurement set or create a chart for custom tasks.
1537         (AnalysisTaskPage.prototype.render): Don't display the charts or the stacking table for custom tasks.
1538         (AnalysisTaskPage.prototype._renderTaskNameAndStatus): Don't try to show the full test name for custom tasks
1539         since it's not associated with exactly one pair.
1540
1541         * public/v3/pages/chart-pane-status-view.js:
1542         (ChartPaneStatusView.prototype._renderBuildRevisionTable):
1543         (ChartPaneStatusView.prototype._formatTime): Moved to Metric.formatTime.
1544
1545         * public/v3/pages/chart-pane.js:
1546         (ChartPane.prototype._analyzeRange): Set inProgress to true to hide CustomAnalysisTaskConfigurator in
1547         CreateAnalysisTaskPage when creating a non-custom analysis task for a specific range.
1548
1549         * public/v3/pages/create-analysis-task-page.js:
1550         (CreateAnalysisTaskPage): This page now shows CustomAnalysisTaskConfigurator by default, and lets a user create
1551         a custom analysis task by picking a test, a platform, and a set of revisions and custom darwinup roots.
1552         (CreateAnalysisTaskPage.prototype.updateFromSerializedState): Show a message when inProgress is set. This is
1553         the old behavior of this page.
1554         (CreateAnalysisTaskPage.prototype.didConstructShadowTree): Added.
1555         (CreateAnalysisTaskPage.prototype._createAnalysisTaskWithGroup): Added.
1556         (CreateAnalysisTaskPage.prototype.render):
1557         (CreateAnalysisTaskPage.prototype._renderMessage): Added. Hides CustomAnalysisTaskConfigurator and the select
1558         element to specify the numebr of iterations when a message is set.
1559         (CreateAnalysisTaskPage.htmlTemplate):
1560         (CreateAnalysisTaskPage.cssTemplate):
1561
1562         * public/v3/pages/page-router.js:
1563         (PageRouter.prototype.route): Always enqueue the page to re-render when the route has changed.
1564
1565         * server-tests/api-build-requests-tests.js: Updated test cases now that the response contains a list of
1566         uploaded files associated with build requests.
1567         *server-tests/api-commits-tests.js: Added a test case for /api/commits/<repository-name>/latest?platform=X.
1568         * server-tests/privileged-api-create-test-group-tests.js: Added test cases for creating a custom analysis task
1569         and a test group with custom roots. 
1570         * server-tests/resources/mock-data.js:
1571         (MockData.addMockData): Updated the mock data to satisfy new constraint on analysis-tasks table. Also inserted
1572         more commits, builds, and build_commits rows for testing /api/commits/<repository-name>/latest?platform=X.
1573
1574         * tools/js/remote.js: Include global.FormData from form-data.js.
1575
1576         * unit-tests/analysis-task-tests.js: Added a test for calling findByPlatformAndMetric when there is a custom
1577         analysis task.
1578         (sampleAnalysisTask): Removed the category since /api/analysis-tasks/ no longer generate this property.
1579         (sampleCustomAnalysisTask): Added.
1580         * unit-tests/build-request-tests.js:
1581         (sampleBuildRequestData): Updated the mock response. Added a test case for fetcing custom roots.
1582         * unit-tests/buildbot-syncer-tests.js:
1583         (createSampleBuildRequest): Ditto.
1584         * unit-tests/test-groups-tests.js:
1585         (sampleTestGroup): Ditto.
1586
1587 2017-04-07  Ryosuke Niwa  <rniwa@webkit.org>
1588
1589         Make cycler page scroll down when a dashboard is too tall for the current viewport size
1590         https://bugs.webkit.org/show_bug.cgi?id=170588
1591
1592         Rubber-stamped by Chris Dumez.
1593
1594         Updated the cycler page to scroll down smoothly over 500ms and scroll up again before moving to the next page
1595         when a dashboard page is too tall to be shown at once. For now, we assume that each dashboard's height is no
1596         more than 2x the height of the viewport.
1597
1598         * public/cycler.html:
1599
1600 2017-04-06  Ryosuke Niwa  <rniwa@webkit.org>
1601
1602         Each build request should be associated with a repository group
1603         https://bugs.webkit.org/show_bug.cgi?id=170528
1604
1605         Rubber-stamped by Chris Dumez.
1606
1607         Make the buildbot syncing script use the concept of repository groups so that each repository group can post
1608         a different set of properties to buildbot. In order to do this, we associate each build request with
1609         a repository group to use. Each triggerable's repository groups is now updated by the syncing scripts via
1610         /api/update-triggerable just the same way the set of the supported platform, test pairs are updated.
1611
1612         Each repository group specifies the list of repositories, a dictionary that maps the buildbot property name
1613         to either a string value or a repository name enclosed in < and >:
1614
1615         ```js
1616         "repositoryGroups": {
1617             "webkit-svn": {
1618                 "repositories": ["WebKit", "macOS"],
1619                 "properties": {"os": "<macOS>", "wk": "<WebKit>"}
1620             }
1621         }
1622         ```
1623
1624         With this, removed the support for specifying a repository to use in generic dictionary of properties via
1625         a dictionary with a single key of "root", "rootOptions", and "rootsExcluding". We now validate that the list of
1626         repositories in each repository group matches exactly the ones used in buildbot properties as well as ones in
1627         build requests.
1628
1629         After this patch, sync-with-buildbot.js will no longer schedule a build request without a repository group.
1630         Run the appropriate database queries to set the repository group on each build request. Because of this change,
1631         this patch also makes BuildbotTriggerable.prototype.syncOnce more robust against invalid build requests.
1632         Instead of throwing an exception and exiting early, it simply skips all build requests that belong to the same
1633         test group if the next build request to be scheduled does not specify a repository group.
1634
1635         * init-database.sql: Add request_repository_group column to build_requests table, and a unique constraint for
1636         repository and group pair in triggerable_repositories table.
1637
1638         * public/api/update-triggerable.php:
1639         (main): Validate and insert repository groups.
1640         (validate_configurations): Extracted from main.
1641         (validate_repository_groups): Added.
1642
1643         * public/v3/models/repository.js:
1644         (Repository.findTopLevelByName): Added.
1645
1646         * public/include/build-requests-fetcher.php:
1647         (BuildRequestsFetcher::results_internal): Include the repository group of each request in the JSON response.
1648
1649         * public/include/repository-group-finder.php: Added. A helper class to find the repository group for a given
1650         triggerable for a list of repositories.
1651         (RepositoryGroupFinder): Added. 
1652         (RepositoryGroupFinder::__construct): Added.
1653         (RepositoryGroupFinder::find_by_repositories): Added.
1654         (RepositoryGroupFinder::populate_map): Added.
1655
1656         * public/privileged-api/create-test-group.php:
1657         (main): Each element in an array returned by ensure_commit_sets and commit_sets_from_revision_sets now contains
1658         "set", the list of commit IDs, and "repository_group", the repository group identified for each commit set.
1659         Use that to set the repository group in each new build request. 
1660         (commit_sets_from_revision_sets): Use RepositoryGroupFinder to find the right repository group.
1661         (ensure_commit_sets): Ditto. There is no need to find a repository group for each commit set here since its
1662         argument is keyed by the repository name. e.g. {"WebKit": [123, 456], "macOS": ["16A323", "16A323"]}
1663
1664         * public/v3/models/build-request.js:
1665         (BuildRequest):
1666         (BuildRequest.prototype.triggerable): Added.
1667         (BuildRequest.prototype.repositoryGroup): Added.
1668         (BuildRequest.constructBuildRequestsFromData): Resolve the triggerable and the repository group.
1669
1670         * public/v3/models/triggerable.js:
1671         (Triggerable.prototype.name): Added.
1672         (Triggerable.prototype.acceptedRepositories): Deleted.
1673         (TriggerableRepositoryGroup):
1674         (TriggerableRepositoryGroup.prototype.accepts): Added. Retruns true if the repository group
1675
1676         * server-tests/api-build-requests-tests.js: Added a test for getting the repository group of a build request.
1677         * server-tests/api-manifest-tests.js: Added assertions for the repository groups.
1678         * server-tests/api-report-tests.js:
1679         (.emptyReport):
1680         (.reportWithTwoLevelsOfAggregations):
1681         * server-tests/api-update-triggerable.js: Added test cases for updating the repository groups associated with
1682         a triggerable.
1683         (.updateWithOSXRepositoryGroup):
1684         (.mapRepositoriesByGroup):
1685         * server-tests/privileged-api-create-test-group-tests.js:
1686         (addTriggerableAndCreateTask): Add two repository groups for testing. Added assertions for repository groups
1687         in existing test cases, and added a test case for creating a test group with two different repository groups.
1688
1689         * server-tests/resources/mock-data.js:
1690         (MockData.resetV3Models): Reset TriggerableRepositoryGroup's static maps.
1691         (MockData.emptyTriggeragbleId): Added.
1692         (MockData.macosRepositoryId): Added.
1693         (MockData.webkitRepositoryId): Added.
1694         (MockData.gitWebkitRepositoryId): Added.
1695         (MockData.addMockData): Create repository groups as needed. Renamed the "OS X" repository to "macOS" since some
1696         tests were using the latter, and now we need mock data to be consistent across tests due to stricter checks.
1697         (MockData.addEmptyTriggerable): Added. Used in api-update-triggerable.js.
1698         (MockData.addMockTestGroupWithGitWebKit): Added. Used in api-build-requests-tests.js.
1699         (MockData.addAnotherMockTestGroup): Cleanup.
1700         (MockData.mockTestSyncConfigWithSingleBuilder): Updated the mock configuration per code changes.
1701         (MockData.mockTestSyncConfigWithTwoBuilders): Ditto.
1702
1703         * server-tests/tools-buildbot-triggerable-tests.js: Updated a test case testing /api/update-triggerable to test
1704         updating the set of repository groups in addition to the set of test, platform pairs.
1705         (.refetchManifest): Added.
1706
1707         * tools/js/buildbot-syncer.js:
1708         (BuildbotSyncer): Now takes a set of configurations shared across syncers: repositoryGroups, slaveArgument,
1709         and buildRequestArgument as the third argument.
1710         (BuildbotSyncer.prototype.repositoryGroups): Added.
1711         (BuildbotSyncer.prototype._testGroupMapForBuildRequests): Cleaned up the code to use Array.prototype.find.
1712         Also added an assertion that the build request is associated with a repository group.
1713         (BuildbotSyncer.prototype._propertiesForBuildRequest): Removed the support for using an arbitary property to
1714         specify a revision in favor of explicity listing each property and repository name in a repository group.
1715         (BuildbotSyncer._loadConfig): Removed the support for "shared", which specified the set of buildbot properties
1716         shared across syncers, the name of properties which specifies the build slave name and build request ID. These
1717         values are not stored as top-level properties and superseded by the concept of repository groups.
1718         (BuildbotSyncer._parseRepositoryGroup): Parses and validates repository groups.
1719         (BuildbotSyncer._createTestConfiguration): We no longer expect each configuration to specify a dictionary of
1720         properties or buildRequestArgument (often inherited from shared).
1721         (BuildbotSyncer._validateAndMergeConfig): Removed "slaveArgument" and "buildRequestArgument" from the list of
1722         allowed proeprties in each configuration now that they're specified as top-level properties.
1723
1724         * tools/js/buildbot-triggerable.js:
1725         (BuildbotTriggerable.prototype.updateTriggerable): Update the associated repository groups.
1726         (BuildbotTriggerable.prototype.syncOnce): Skip test groups for which the next build request to be scheduled is
1727         not included in the list of valid build requests.
1728         (BuildbotTriggerable.prototype._validateRequests): Now returns the list of valid build requests, which excludes
1729         those that lack a repository group set.
1730         (BuildbotTriggerable.prototype._nextRequestInGroup): Extracted from _scheduleRequestIfSlaveIsAvailable. Finds
1731         the next build request to be scheduled for the test group.
1732         (BuildbotTriggerable.prototype._scheduleRequestIfSlaveIsAvailable): Renamed from
1733         _scheduleNextRequestInGroupIfSlaveIsAvailable. Now takes the syncer and the slave name as arguments instead of
1734         a test group information since syncOnce now calls _nextRequestInGroup to find the next build request.
1735
1736         * tools/js/v3-models.js:
1737
1738         * unit-tests/build-request-tests.js: Fixed the test name.
1739
1740         * unit-tests/buildbot-syncer-tests.js: Removed tests for "rootOptions" and "rootsExcluding", and added tests
1741         for parsing repository groups.
1742         (sampleiOSConfig): Updated the mock configuration per code changes.
1743         (sampleiOSConfigWithExpansions): Ditto.
1744         (smallConfiguration): Ditto. Now returns the entire configuration instead of a single builder configuration.
1745         Various test cases have been updated to reflect this.
1746         (createSampleBuildRequest): Removed the git hash of WebKit to match the repository groups listed in the mock
1747         configurations. The git hash was there to test "rootOptions", which this patch removed.
1748         (samplePendingBuild): Removed "root_dict" from the list of properties. This was used to test "rootsExcluding"
1749         which, again, this patch removed.
1750         (sampleInProgressBuild): Ditto.
1751         (sampleFinishedBuild): Ditto.
1752
1753         * unit-tests/resources/mock-v3-models.js:
1754         (MockModels.inject): Added ock repository groups so that existing tests will continue to function.
1755
1756 2017-04-05  Ryosuke Niwa  <rniwa@webkit.org>
1757
1758         Introduce the notion of repository groups to triggerables
1759         https://bugs.webkit.org/show_bug.cgi?id=170228
1760
1761         Reviewed by Chris Dumez.
1762
1763         On some triggerable, it's desirable to specify multiple sets of repositories that are accepted.
1764
1765         For example, if a repository X transitioned from Subversion to Git, and if a triggerable accepted X and
1766         some other repository Y, then it's desirable to two sets: (X-Subversion, Y) and (X-Git, Y) since neither
1767         (X-Subversion, X-Git) nor (X-Subversion, X-Git, Y) makes sense as a set.
1768
1769         This patch introduces triggerable_repository_groups table to represent a set of repositories accepted by
1770         a triggerable. It has many to one relationship to build_triggerables and triggerable_repositories in turn
1771         now has many to one relationship to triggerable_repository_groups instead of build_triggerables.
1772
1773         Also make it possible to disable a triggerable e.g. a set of tests and platforms are no longer supported.
1774         We don't want to delete the triggerable completely from the database since it would result in the associated
1775         A/B testing results being purged, which is not desirale.
1776
1777         To migrate an existing database, run the following transaction:
1778         ```sql
1779         BEGIN;
1780         ALTER TABLE build_triggerables ADD COLUMN triggerable_disabled boolean NOT NULL DEFAULT FALSE;
1781
1782         CREATE TABLE triggerable_repository_groups (
1783             repositorygroup_id serial PRIMARY KEY,
1784             repositorygroup_triggerable integer REFERENCES build_triggerables NOT NULL,
1785             repositorygroup_name varchar(256) NOT NULL,
1786             repositorygroup_description varchar(256),
1787             repositorygroup_accepts_roots boolean NOT NULL DEFAULT FALSE,
1788             CONSTRAINT repository_group_name_must_be_unique_for_triggerable
1789                 UNIQUE(repositorygroup_triggerable, repositorygroup_name));
1790         INSERT INTO triggerable_repository_groups (repositorygroup_triggerable, repositorygroup_name)
1791             SELECT triggerable_id, 'default' FROM build_triggerables;
1792
1793         ALTER TABLE triggerable_repositories ADD COLUMN trigrepo_group integer REFERENCES triggerable_repository_groups;
1794         UPDATE triggerable_repositories SET trigrepo_group = repositorygroup_id FROM triggerable_repository_groups
1795             WHERE trigrepo_triggerable = repositorygroup_triggerable;
1796         ALTER TABLE triggerable_repositories ALTER COLUMN trigrepo_group SET NOT NULL;
1797
1798         ALTER TABLE triggerable_repositories DROP COLUMN trigrepo_triggerable;
1799         ALTER TABLE triggerable_repositories DROP COLUMN trigrepo_sub_roots;
1800         END;
1801         ```
1802
1803         * init-database.sql:
1804         * public/admin/triggerables.php: Use a custom column to make forms to add and configure repository groups.
1805         (insert_triggerable_repositories): Added.
1806         (generate_repository_list): Added.
1807         (generate_repository_form): Added.
1808         (generate_repository_checkboxes): Now generates checkboxes for a repository group instead of a triggerable.
1809
1810         * public/include/manifest-generator.php:
1811         (fetch_triggerables): Fixed the bug that we were not filtering results with query in /api/triggerable.
1812         Rewrote it to include an array of repository groups, which in turn contains an array of repositories along
1813         with its name and a description, and a boolean indicating whether it accepts a custom root file or not.
1814         The boolean will be used when we're adding the support for perf try bots. We will keep acceptedRepositories
1815         since it's still used by detect-changes.js.
1816
1817         * public/v3/models/manifest.js:
1818         (Manifest._didFetchManifest): Resolve repositoriy, test, and platform IDs to their respective objects.
1819
1820         * public/v3/models/triggerable.js:
1821         (Triggerable):
1822         (Triggerable.prototype.isDisabled): Added.
1823         (Triggerable.prototype.repositoryGroups): Added.
1824         (Triggerable.prototype.acceptsTest): Added.
1825         (TriggerableRepositoryGroup): Added.
1826         (TriggerableRepositoryGroup.prototype.description): Added.
1827         (TriggerableRepositoryGroup.prototype.acceptsCustomRoots): Added.
1828         (TriggerableRepositoryGroup.prototype.repositories): Added.
1829
1830         * public/v3/pages/analysis-task-page.js:
1831         (AnalysisTaskPage.prototype._didFetchTask): Don't use a disabled triggerable.
1832
1833         * server-tests/api-manifest-tests.js: Updated a test case to test repository groups.
1834
1835         * tools/js/database.js:
1836         (tableToPrefixMap): Added triggerable_repository_groups.
1837
1838         * tools/js/v3-models.js: Imported TriggerableRepositoryGroup from triggerable.js.
1839
1840 2017-03-31  Ryosuke Niwa  <rniwa@webkit.org>
1841
1842         Build fix. For OS versions, we can end up with non-alphanumeric revision.
1843         Delete the code path only used by the v2 UI since nobody uses that now.
1844
1845         * public/api/commits.php:
1846         (main):
1847
1848 2017-03-30  Ryosuke Niwa  <rniwa@webkit.org>
1849
1850         sync-buildbot.js can schedule more than one build per builder
1851         https://bugs.webkit.org/show_bug.cgi?id=170318
1852
1853         Reviewed by Saam Barati.
1854
1855         The bug was caused by _scheduleNextRequestInGroupIfSlaveIsAvailable not returning a promise when
1856         scheduling the first build request of a test group. This resulted in _pullBuildbotOnAllSyncers
1857         to prematurely resolve before POST'ing new build had finished. That in turn could result in the
1858         next cycle of syncing to occur before POST'ing has actually taken place.
1859
1860         More precisely, when the nextRequest was the first request or its associated syncer object could
1861         not be identified, we were supposed to find the first available syncer, schedule the request,
1862         and then return the promise returned by scheduleRequestInGroupIfAvailable. However, the for loop
1863         which called scheduleRequestInGroupIfAvailable on every syncer was declaring its own variable
1864         named "promise" thereby shadowing the outer variable, which is returned to the caller.
1865
1866         Fixed the bug by not declaring a shadowing variable, and refactored the code. Namely, the only
1867         reason we had such a complicated logic with two local variables, promise and syncer, was so that
1868         we could log that we're scheduling a build. Extracted this code as _scheduleRequestWithLog.
1869
1870         _scheduleNextRequestInGroupIfSlaveIsAvailable can now simply exit early with a call to
1871         _scheduleRequestWithLog when the syncer is readily identified. When looping over syncers, it can
1872         simply return the first non-null result of _scheduleNextRequestInGroupIfSlaveIsAvailable.
1873
1874         * server-tests/tools-buildbot-triggerable-tests.js: Added a test case where we wait 10ms after
1875         receiving the request to POST a build. There should be no new network request until we resolve
1876         this request.
1877
1878         * tools/js/buildbot-triggerable.js:
1879         (BuildbotTriggerable.prototype._scheduleNextRequestInGroupIfSlaveIsAvailable): Fixed the bug.
1880         (BuildbotTriggerable.prototype._scheduleRequestWithLog): Extracted.
1881
1882 2017-03-30  Ryosuke Niwa  <rniwa@webkit.org>
1883
1884         Modernize BuildbotSyncer and BuildbotTriggerable
1885         https://bugs.webkit.org/show_bug.cgi?id=170310
1886
1887         Reviewed by Chris Dumez.
1888
1889         Modernized the code to use arrow functions and other modern idoms in ES2016.
1890
1891         * ReadMe.md: Added instructions on how to run tests, and moved the steps to configure postgres
1892         above the steps to configure Apache since only the former is needed to run tests.
1893         * tools/js/buildbot-syncer.js:
1894         * tools/js/buildbot-triggerable.js:
1895
1896 2017-03-30  Ryosuke Niwa  <rniwa@webkit.org>
1897
1898         Yet another build fix after r214502. Workaround webkit.org/b/169907 for now.
1899
1900         * public/v3/pages/analysis-task-page.js:
1901         (AnalysisTaskPage.cssTemplate):
1902
1903 2017-03-30  Ryosuke Niwa  <rniwa@webkit.org>
1904
1905         Revert an erronously change in the previous commit.
1906
1907         * public/v3/components/base.js:
1908
1909 2017-03-30  Ryosuke Niwa  <rniwa@webkit.org>
1910
1911         Build fix after r214280. Don't render components until its element is inserted into a document.
1912
1913         * public/v3/components/base.js:
1914         (ComponentBase):
1915
1916 2017-03-29  Ryosuke Niwa  <rniwa@webkit.org>
1917
1918         Another build fix after r214502.
1919
1920         * public/v3/components/analysis-results-viewer.js:
1921         (AnalysisResultsViewer.prototype.render): this._groupToCellMap.get may not contain the cell when startPoint
1922         or metric had not been fetched yet even if currentTestGroup is set.
1923
1924 2017-03-29  Ryosuke Niwa  <rniwa@webkit.org>
1925
1926         Build fix after r214502. Analysis tasks without any test groups are throwing exceptions.
1927
1928         * public/v3/components/results-table.js:
1929         (ResultsTable.prototype.renderTable): Don't show the header row when there are no content to show. 
1930         (ResultsTable.prototype._computeRepositoryList): Return a pair of arrays. The caller expects the repository
1931         list to be an array, not undefined.
1932
1933 2017-03-28  Ryosuke Niwa  <rniwa@webkit.org>
1934
1935         Modernize AnalysisTaskPage
1936         https://bugs.webkit.org/show_bug.cgi?id=170165
1937
1938         Reviewed by Antti Koivisto.
1939
1940         Modernized AnalysisTaskPage and related components. The main refactoring happened in AnalysisTaskPage
1941         from which AnalysisTaskResultsPane and AnalysisTaskTestGroupPane have been extracted.
1942
1943         Decoupled BuildRequest from its results. AnalysisResultsViewer and TestGroupResultsTable now stores
1944         a reference to AnalysisResultsView and Metric to find the results for each build request.
1945         This refactoring is necessary in order to view results of an arbitrary metric in the future.
1946
1947         Also refactored ResultsTable and its subclasses extensively. Instead of making its render() to invoke
1948         subclass' methods such as buildRowGroups, heading, and additionalHeading, rely on each subclass call
1949         to invoke renderTable(), renamed from render(), with callbacks to add extra headers and columns.
1950
1951         This patch also fixes a number of usability issues found by the user such as changing the test name
1952         resets the customized revisions by the virtue of the modern code being naturally more correct.
1953
1954         * public/v3/components/analysis-results-viewer.js:
1955         (AnalysisResultsViewer):
1956         (AnalysisResultsViewer.prototype.setTestGroupCallback): Deleted. Replaced by "testGroupClick" action.
1957         (AnalysisResultsViewer.prototype.setRangeSelectorLabels): Moved here from ResultsTable since it's
1958         never used in ResultsTable or TestGroupResultsTable.
1959         (AnalysisResultsViewer.prototype.selectedRange): Ditto.
1960         (AnalysisResultsViewer.prototype.setPoints): Now takes metric as the third argument.
1961         (AnalysisResultsViewer.prototype.setTestGroups): Now takes the current test group.
1962         (AnalysisResultsViewer.prototype.didUpdateResults): Deleted.
1963         (AnalysisResultsViewer.prototype.setAnalysisResultsView): Added.
1964         (AnalysisResultsViewer.prototype.render): Invoke _renderTestGroups lazily. Also simplified the logic
1965         to find the selected list item. Since we always use a shadow DOM now, we can simply look for an element
1966         with ".seleted" instead of crafting a unique class name.
1967         (AnalysisResultsViewer.prototype.renderTestGroups): Renamed from buildRowGroups. Specify callbacks to
1968         insert headers for A/B radio buttons, which has been moved from ResultsTable.prototype.render, and the
1969         stacked blocks of testing results.
1970         (AnalysisResultsViewer.prototype._classForTestGroup): Deleted.
1971         (AnalysisResultsViewer.prototype._openStackingBlock): Deleted.
1972         (AnalysisResultsViewer.prototype._expandBetween): Create a new set for expandedPoints to make
1973         _renderTestGroupsLazily.evaluate do the work.
1974         (AnalysisResultsViewer._layoutBlocks): Moved from TestGroupStackingGrid.layout.
1975         (AnalysisResultsViewer._sortBlocksByRow): Moved from AnalysisResultsViewer.TestGroupStackingGrid.
1976         (AnalysisResultsViewer._insertAfterBlockWithSameRange): Ditto.
1977         (AnalysisResultsViewer._insertBlockInFirstAvailableColumn): Ditto.
1978         (AnalysisResultsViewer._createCellsForRow): Ditto.
1979
1980         (AnalysisResultsViewer.TestGroupStackingBlock):
1981         (AnalysisResultsViewer.TestGroupStackingBlock.prototype.addRowIndex):
1982         (AnalysisResultsViewer.TestGroupStackingBlock.prototype.createStackingCell): No longer creates a unique
1983         class name here. See the inline comment for AnalysisResultsViewer.prototype.render.
1984         (AnalysisResultsViewer.TestGroupStackingBlock.prototype.isThin): Deleted. We used to collapse "failed"
1985         test groups as a thin vertical line, and we wanted to show them next to each other in _layoutBlock but
1986         we don't do that anymore.
1987         (AnalysisResultsViewer.TestGroupStackingBlock.prototype._valuesForCommitSet): Added. Uses
1988         this._analysisResultsView to extract the results for the current metrics.
1989         (AnalysisResultsViewer.TestGroupStackingBlock.prototype._computeTestGroupStatus):
1990
1991         * public/v3/components/analysis-task-bug-list.js: Added.
1992         (AnalysisTaskBugList): Added. Extracted from AnalysisTaskChartPane.
1993         (AnalysisTaskBugList.prototype.setTask): Added.
1994         (AnalysisTaskBugList.prototype.didConstructShadowTree): Added.
1995         (AnalysisTaskBugList.prototype.render): Added.
1996         (AnalysisTaskBugList.prototype._associateBug): Added.
1997         (AnalysisTaskBugList.prototype._dissociateBug): Added.
1998         (AnalysisTaskBugList.htmlTemplate): Added.
1999
2000         * public/v3/components/chart-pane-base.js:
2001         (ChartPaneBase.htmlTemplate): Added a hook to insert more content at the end in AnalysisTaskChartPane.
2002         (ChartPaneBase.paneFooterTemplate): Added.
2003
2004         * public/v3/components/customizable-test-group-form.js:
2005         (CustomizableTestGroupForm):
2006         (CustomizableTestGroupForm.prototype.setCommitSetMap):
2007         (CustomizableTestGroupForm.prototype.startTesting): Renamed from _submitted. Now dispatches an action
2008         by the name of "startTesting" instead of calling this._startCallback.
2009         (CustomizableTestGroupForm.prototype.didConstructShadowTree): Added. Moved the logic to attach event
2010         handlers here to avoid eagerly creating the shadow tree in the constructor.
2011         (CustomizableTestGroupForm.prototype._computeCommitSetMap): Use the newly added this._revisionEditorMap
2012         to find the relevant input element instead of running a querySelector.
2013         (CustomizableTestGroupForm.prototype.render): Lazily invoke _renderCustomRevisionTable. This avoids
2014         overriding the customized revisions when the user finally types in the test group name.
2015         (CustomizableTestGroupForm.prototype._renderCustomRevisionTable): Extracted from render.
2016         (CustomizableTestGroupForm.prototype._constructRevisionRadioButtons): Made this a non-static method
2017         since it needs to update this._revisionEditorMap now. Merged _constructRevisionRadioButtons.
2018         (CustomizableTestGroupForm.prototype._createRadioButton): Deleted. See above.
2019         (CustomizableTestGroupForm.cssTemplate):
2020         (CustomizableTestGroupForm.formContent): Use IDs instead of classes to make this.content(ID) work.
2021
2022         * public/v3/components/mutable-list-view.js:
2023         (MutableListView.prototype.setList):
2024         (MutableListView.prototype.setKindList):
2025         (MutableListView.prototype.setAddCallback): Deleted. Replaced by "addItem" action.
2026         (MutableListView.prototype.render):
2027         (MutableListItem.prototype.content):
2028
2029         * public/v3/components/results-table.js:
2030         (ResultsTable): Removed this._rangeSelectorLabels, this._rangeSelectorCallback, and this._selectedRange
2031         as they are only used by AnalysisResultsViewer. Also replaced this._valueFormatter by
2032         this._analysisResultsView which knows a metric.
2033         (ResultsTable.prototype.setValueFormatter): Deleted.
2034         (ResultsTable.prototype.setRangeSelectorLabels): Deleted.
2035         (ResultsTable.prototype.setRangeSelectorCallback): Deleted.
2036         (ResultsTable.prototype.selectedRange): Deleted.
2037         (ResultsTable.prototype._rangeSelectorClicked): Deleted.
2038         (ResultsTable.prototype.setAnalysisResultsView): Added.
2039         (ResultsTable.prototype.renderTable): Added. Removed the logic to add _rangeSelectorLabels since it has
2040         been moved to AnalysisResultsViewer.prototype.render inside buildColumns, which also inserts additional
2041         columns which used to be stored on each ResultsTableRow. Use the same technique to insert additional
2042         headers. Also take the name (thead tr th) of row header (tbody tr td) as an argument and automatically
2043         create a table cell of an appropriate colspan.
2044         (ResultsTable.prototype._createRevisionListCells):
2045         (ResultsTable.prototype.heading): Deleted. Superseded by buildHeaders callback.
2046         (ResultsTable.prototype.additionalHeading): Ditto.
2047         (ResultsTable.prototype.buildRowGroups): Deleted. It is now the responsibility of each subclass to call
2048         ResultsTable's renderTable() in the subclass' render() function.
2049         (ResultsTable.prototype._computeRepositoryList): No longer takes extraRepositories as an argument.
2050         Instead, this function now returns a pair of the repository list and the list of constant commits.
2051         (ResultsTable.htmlTemplate):
2052         (ResultsTable.cssTemplate):
2053
2054         * public/v3/components/test-group-form.js:
2055         (TestGroupForm): Avoid eagerly creating the shadow tree. Also removed the removed the dead code.
2056         (TestGroupForm.prototype.setRepetitionCount): Simply override the value of the select element.
2057         (TestGroupForm.prototype.didConstructShadowTree): Added. Attach event handlers here to avoid eagerly
2058         creating the shadow tree in the constructor.
2059         (TestGroupForm.prototype.startTesting): Renamed from _submitted. Dispatch "startTesting" action instead
2060         of invoking _startCallback which has been removed.
2061         (TestGroupForm.htmlTemplate):
2062         (TestGroupForm.formContent):
2063
2064         * public/v3/components/test-group-results-table.js:
2065         (TestGroupResultsTable):
2066         (TestGroupResultsTable.prototype.didUpdateResults): Deleted. No longer neeed per setAnalysisResultsView
2067         in ResultsTable.
2068         (TestGroupResultsTable.prototype.setTestGroup):
2069         (TestGroupResultsTable.prototype.heading): Deleted.
2070         (TestGroupResultsTable.prototype.render):
2071         (TestGroupResultsTable.prototype._renderTestGroup): Extracted from render.
2072         (TestGroupResultsTable.prototype._buildRowGroups): Renamed from buildRowGroups.
2073         (TestGroupResultsTable.prototype._buildRowGroupForCommitSet): Extracted from buildRowGroups.
2074         (TestGroupResultsTable.prototype._buildComparisonRow): Extracted from buildRowGroups.buildRowGroups
2075
2076         * public/v3/index.html: Include analysis-task-bug-list.js.
2077
2078         * public/v3/models/analysis-results.js:
2079         (AnalysisResults): Inverted the map so that we can easily create a view based on metric.
2080         (AnalysisResults.prototype.find): Ditto.
2081         (AnalysisResults.prototype.add): Ditto.
2082         (AnalysisResults.prototype.viewForMetric): Added.
2083         (AnalysisResults.fetch):
2084         (AnalysisResultsView): Added.
2085         (AnalysisResultsView.prototype.metric): Added.
2086         (AnalysisResultsView.prototype.resultForBuildId): Added.
2087
2088         * public/v3/models/build-request.js:
2089         (BuildRequest.result): Deleted.
2090         (BuildRequest.setResult): Deleted.
2091
2092         * public/v3/models/test-group.js:
2093         (TestGroup): Removed this._allCommitSets since it was never used.
2094         (TestGroup.prototype.didSetResult): Deleted since it was never used.
2095         (TestGroup.prototype.compareTestResults): Now takes an array of measurement set values.
2096         (TestGroup.prototype._valuesForCommitSet): Deleted.
2097
2098         * public/v3/pages/analysis-task-page.js:
2099         (AnalysisTaskChartPane): This class now includes the form to cutomize the revisions.
2100         (AnalysisTaskChartPane.prototype.setShowForm): Added.
2101         (AnalysisTaskChartPane.prototype._mainSelectionDidChange):
2102         (AnalysisTaskChartPane.prototype.didConstructShadowTree): Added. Dispatches "newTestGroup" action when
2103         the user presses the button to start a new A/B testing from the chart.
2104         (AnalysisTaskChartPane.prototype.render): Added.
2105         (AnalysisTaskChartPane.prototype.paneFooterTemplate): Added.
2106         (AnalysisTaskChartPane.cssTemplate):
2107
2108         (AnalysisTaskResultsPane): Added. Encapsulates AnalysisResultsViewer and CustomizableTestGroupForm.
2109         (AnalysisTaskResultsPane.prototype.setPoints): Added.
2110         (AnalysisTaskResultsPane.prototype.setTestGroups): Added.
2111         (AnalysisTaskResultsPane.prototype.setAnalysisResultsView): Added.
2112         (AnalysisTaskResultsPane.prototype.setShowForm): Added.
2113         (AnalysisTaskResultsPane.prototype.didConstructShadowTree): Added. Dispatches "newTestGroup" action
2114         when the user presses the button to start a new A/B testing from the chart.
2115         (AnalysisTaskResultsPane.prototype.render): Added.
2116         (AnalysisTaskResultsPane.htmlTemplate): Added.
2117         (AnalysisTaskResultsPane.cssTemplate): Added.
2118
2119         (AnalysisTaskTestGroupPane): Added. Encapsulates TestGroupResultsTable and CustomizableTestGroupForm.
2120         (AnalysisTaskTestGroupPane.prototype.didConstructShadowTree): Added.
2121         (AnalysisTaskTestGroupPane.prototype.setTestGroups): Added.
2122         (AnalysisTaskTestGroupPane.prototype.setAnalysisResultsView): Added.
2123         (AnalysisTaskTestGroupPane.prototype.render): Added.
2124         (AnalysisTaskTestGroupPane.prototype._renderTestGroups): Added. Updates the list of test groups. Hide
2125         the hidden groups unless showHiddenGroups is set. Updates this._testGroupMap so that the visibility of
2126         groups and their names can be updated without having to re-render the entire list.
2127         (AnalysisTaskTestGroupPane.prototype._renderTestGroupVisibility): Added.
2128         (AnalysisTaskTestGroupPane.prototype._renderTestGroupNames): Added.
2129         (AnalysisTaskTestGroupPane.prototype._renderCurrentTestGroup): Added. Update TestGroupResultsTable with
2130         the selected test group. Also highlight the list view, and update the hide-unhide toggle button's label
2131         as needed.
2132         (AnalysisTaskTestGroupPane.htmlTemplate): Added.
2133         (AnalysisTaskTestGroupPane.cssTemplate): Added.
2134
2135         (AnalysisTaskPage): Deleted a massive number of instance variables. They are now manged by newly added
2136         AnalysisTaskChartPane, AnalysisTaskResultsPane, and AnalysisTaskTestGroupPane
2137         (AnalysisTaskPage.prototype.didConstructShadowTree): Added. Attach various event handlers here to avoid
2138         eagerly creating the shadow tree in the constructor.
2139         (AnalysisTaskPage.prototype._fetchRelatedInfoForTaskId):
2140         (AnalysisTaskPage.prototype._didFetchTask): No longer sets the value formatter to the results viewer
2141         and the results table as they now recieve AnalysisResultsView later in _assignTestResultsIfPossible.
2142         (AnalysisTaskPage.prototype._didFetchMeasurement): Set the metric to the results viewer.
2143         (AnalysisTaskPage.prototype._didUpdateTestGroupHiddenState):
2144         (AnalysisTaskPage.prototype._assignTestResultsIfPossible): Create AnalysisResultsView from the newly
2145         retrieved AnalysisResults and pass it to AnalysisTaskResultsPane and AnalysisTaskTestGroupPane.
2146         (AnalysisTaskPage.prototype.render): Dramatically simplified.
2147         (AnalysisTaskPage.prototype._renderTaskNameAndStatus): Extracted from render.
2148         (AnalysisTaskPage.prototype._renderRelatedTasks): Ditto.
2149         (AnalysisTaskPage.prototype._renderCauseAndFixes): Ditto.
2150         (AnalysisTaskPage.prototype._showTestGroup):
2151         (AnalysisTaskPage.prototype._updateTaskName): Now takes the new name as an argument.
2152         (AnalysisTaskPage.prototype._updateTestGroupName): Now takes the new name as the second argument.
2153         (AnalysisTaskPage.prototype._hideCurrentTestGroup): Now takes the test group to hide.
2154         (AnalysisTaskPage.prototype._associateCommit): Moved to AnalysisTaskBugList.
2155         (AnalysisTaskPage.prototype._dissociateCommit): Ditto.
2156         (AnalysisTaskPage.prototype._retryCurrentTestGroup): Now takes the test group as the first argument.
2157         (AnalysisTaskPage.prototype._chartSelectionDidChange): Deleted.
2158         (AnalysisTaskPage.prototype._createNewTestGroupFromChart): Deleted.
2159         (AnalysisTaskPage.prototype._selectedRowInAnalysisResultsViewer): Deleted.
2160         (AnalysisTaskPage.prototype._createNewTestGroupFromViewer): Deleted.
2161         (AnalysisTaskPage.htmlTemplate):
2162         (AnalysisTaskPage.cssTemplate):
2163
2164         * unit-tests/test-groups-tests.js: Updated a test case which was expecting BuildReqeust's result, which
2165         has been removed, to exist.
2166
2167 2017-03-23  Ryosuke Niwa  <rniwa@webkit.org>
2168
2169         Share more code between ManifestGenerator and /api/triggerables
2170         https://bugs.webkit.org/show_bug.cgi?id=169993
2171
2172         Reviewed by Chris Dumez.
2173
2174         Shared the code to fetch the list of triggerables from the database between ManifestGenerator
2175         and /api/triggerables.
2176
2177         * public/api/triggerables.php:
2178         (main):
2179         * public/include/manifest-generator.php:
2180         (ManifestGenerator::fetch_triggerables): Extracted as a static function. Also include the ID
2181         in the triggerable data.
2182
2183 2017-03-23  Ryosuke Niwa  <rniwa@webkit.org>
2184
2185         create-test-group should allow a different set of repositories to be used in each configuration
2186         https://bugs.webkit.org/show_bug.cgi?id=169992
2187
2188         Rubber-stamped by Antti Koivisto.
2189
2190         Added the support for new POST parameter, revisionSets, to /privileged-api/create-test-group.
2191         This new parameter now specifies an array of repository id to revision dictionaries, and allows
2192         different set of repositories' revisions to be specified in each dictionary.
2193
2194         We keep the old API for v2 UI and detect-changes.js compatibility for now.
2195
2196         * public/privileged-api/create-test-group.php:
2197         (main):
2198         (commit_sets_from_revision_sets): Added.
2199         (ensure_commit_sets): Only fetch the top-level repository per r213788 and r213976.
2200
2201         * public/v3/models/test-group.js:
2202         (TestGroup.createAndRefetchTestGroups): Use the newly added revisionSets parameter instead of
2203         the now depreacted commitSets parameter.
2204
2205         * public/v3/pages/analysis-task-page.js:
2206         (AnalysisTaskPage.prototype._createTestGroupAfterVerifyingCommitSetList): Simplified this code
2207         by simply verifying the consistency of commit sets now that createAndRefetchTestGroups takes
2208         an array of commit sets instead of a dictionary of repository name to a list of revisions.
2209
2210         * server-tests/privileged-api-create-test-group-tests.js: Added test cases for new parameter.
2211
2212 2017-03-22  Ryosuke Niwa  <rniwa@webkit.org>
2213
2214         /api/uploaded-file should return createdAt as a POSIX timestamp
2215         https://bugs.webkit.org/show_bug.cgi?id=169980
2216
2217         Rubber-stamped by Antti Koivisto.
2218
2219         Call Database::to_js_time on createdAt to return it as a POSIX timestamp.
2220
2221         * public/include/uploaded-file-helpers.php:
2222         (format_uploaded_file): Fixed the bug.
2223         * server-tests/api-manifest-tests.js: Renamed from api-manifest.js.
2224         * server-tests/api-uploaded-file-tests.js: Renamed from api-uploaded-file.js. Added a test case.
2225
2226 2017-03-22  Ryosuke Niwa  <rniwa@webkit.org>
2227
2228         UploadedFile should support a callback for upload progress
2229         https://bugs.webkit.org/show_bug.cgi?id=169977
2230
2231         Reviewed by Andreas Kling.
2232
2233         Added a new option dictionary to CommonRemoteAPI.sendHttpRequest with uploadProgressCallback
2234
2235         Moved request headers and responseHandler callback in NodeRemoteAPI to this dictionary,
2236         and updated the tests which relied on this code.
2237
2238         * public/shared/common-remote.js:
2239         (CommonRemoteAPI.prototype.postJSON):
2240         (CommonRemoteAPI.prototype.postJSONWithStatus):
2241         (CommonRemoteAPI.prototype.postFormData):
2242         (CommonRemoteAPI.prototype.postFormDataWithStatus):
2243         * public/v3/privileged-api.js:
2244         (PrivilegedAPI.prototype.sendRequest):
2245         * public/v3/remote.js:
2246         (BrowserRemoteAPI.prototype.sendHttpRequest):
2247         (BrowserRemoteAPI.prototype.sendHttpRequestWithFormData):
2248         (BrowserRemoteAPI):
2249         * server-tests/api-uploaded-file.js:
2250         * tools/js/remote.js:
2251         (NodeRemoteAPI.prototype.sendHttpRequest):
2252         (NodeRemoteAPI.prototype.sendHttpRequestWithFormData):
2253         (NodeRemoteAPI):
2254
2255 2017-03-22  Ryosuke Niwa  <rniwa@webkit.org>
2256
2257         ComponentBase should enqueue itself to render when it becomes connected
2258         https://bugs.webkit.org/show_bug.cgi?id=169905
2259
2260         Reviewed by Antti Koivisto.
2261
2262         When a component becomes connected to a document, enqueue itself to render automatically.
2263         Also added the support for boolean attribute to ComponentBase.createElement.
2264
2265         * ReadMe.md: Added an instruction to raise the upload limit per r214065.
2266         * browser-tests/component-base-tests.js: Added tests for the new behavior and createElement. Also moved
2267         the tests related to enqueueToRenderOnResize out of defineElement tests.
2268
2269         * browser-tests/index.html:
2270         (BrowsingContext.prototype.constructor): Override requestAnimationFrame so that the callback would be
2271         involved immediately durign testing.
2272
2273         * public/v3/components/base.js:
2274         (ComponentBase): Enqueue itself to render during construction if custom elements is not available.
2275         (ComponentBase.defineElement):
2276         (ComponentBase.defineElement.elementClass.prototype.connectedCallback): Enqueue itself to render when
2277         the component's element became connected.
2278         (ComponentBase.createElement): Use Array.isArray instead of instanceof to make it work with arrays made
2279         in other realms (global objects) during testing. Added the support for boolean attributes. Setting an
2280         attribute value to true would set the attribute, and setting it to false would not set the attribute.
2281         (ComponentBase.useNativeCustomElements): Added. True iff window.customElements is defined.
2282
2283         * public/v3/components/chart-pane-base.js:
2284         (ChartPaneBase.prototype.render): No longer need to call enqueueToRender on the commit log viewer.
2285
2286         * public/v3/components/commit-log-viewer.js:
2287         (CommitLogViewer.prototype.render): No longer need to call enqueueToRender on the spinner icon.
2288
2289         * public/v3/models/time-series.js:
2290         (TimeSeries): Made this a proper class declaration now that we don't include data.js after r213300.
2291
2292         * public/v3/pages/chart-pane.js:
2293         (ChartPane.prototype._renderActionToolbar): No longer need to call enqueueToRender on the close icon.
2294
2295         * public/v3/pages/summary-page.js:
2296         (SummaryPage.prototype._renderCell): No longer need to call enqueueToRender on the spinner icon.
2297
2298 2017-03-20  Ryosuke Niwa  <rniwa@webkit.org>
2299
2300         Delete another function that was supposed to be removed in the previous commit.
2301
2302         * public/v3/models/build-request.js:
2303         (BuildRequest.cachedRequestsForTriggerableID): Deleted.
2304
2305 2017-03-20  Ryosuke Niwa  <rniwa@webkit.org>
2306
2307         Modernize BuildRequestQueuePage
2308         https://bugs.webkit.org/show_bug.cgi?id=169903
2309
2310         Reviewed by Antti Koivisto.
2311
2312         Modernized the code for /v3/#/analysis/queue.
2313
2314         * public/v3/models/build-request.js:
2315         (BuildRequest.fetchTriggerables): Deleted since the manifest JSON now contains all the triggerables.
2316
2317         * public/v3/pages/build-request-queue-page.js:
2318         (BuildRequestQueuePage): Deleted this._triggerables. Added this._buildRequestsByTriggerable.
2319         (BuildRequestQueuePage.prototype.open): Modernized the code.
2320         (BuildRequestQueuePage.prototype.render): Ditto.
2321         (BuildRequestQueuePage.prototype._constructBuildRequestTable): Ditto.
2322
2323 2017-03-19  Ryosuke Niwa  <rniwa@webkit.org>
2324
2325         Charts page show an inconsistent list of revisions for Git and Subversion
2326         https://bugs.webkit.org/show_bug.cgi?id=169888
2327
2328         Reviewed by Andreas Kling.
2329
2330         With Git, CommitLogViewer was showing the list of revisions including the starting hash,
2331         which was the last data point's revision instead of all revisions after the last data point.
2332
2333         Fixed the bug by always specifying the revision at the last data point in both Subversion
2334         and Git and then making /api/commits/<repository>/?from=X&to=Y exclude the first revision.
2335         For clarity, "from" and "to" query parameters have been renamed to "precedingRevision" and
2336         "lastRevision" respectively.
2337
2338         We also no longer adds 1 to the starting revision of Subversion-like starting revisions. e.g.
2339         when the last data point was at r1234, new data point is at r1250, the label is now "r1234-r1250"
2340         instead of "r1235-r1250".
2341
2342         * browser-tests/chart-revision-range-tests.js: Fixed the tests since revisionList no longer
2343         specifies from/to revisions.
2344         * browser-tests/commit-log-viewer-tests.js: Added. Added tests for CommitLogViewer.
2345         * browser-tests/index.html: Include the new test. Also use a local copy of mocha.js/css.
2346
2347         * public/api/commits.php:
2348         (main): Renamed "from" and "to" query parameters.
2349
2350         * public/include/commit-log-fetcher.php:
2351         (CommitLogFetcher::fetch_between): Added a check that commit time should either be specified
2352         in both rows or not specified in either. Also reject when before_first_revision is identical
2353         or after last_revision instead of re-ordering them since it no longer makes sense to do so with
2354         new query parameter names.
2355
2356         * public/v3/components/base.js:
2357         (ComponentBase._addContentToElement): Use Array.isArray instead of instanceof. It's resilient
2358         againt realm (global object) differences.
2359
2360         * public/v3/components/chart-pane-base.js:
2361         (ChartPaneBase.prototype._updateCommitLogViewer): No longer calls enqueueToRender on this since
2362         CommitLogViewer does that on its own now.
2363         (ChartPaneBase.prototype.render): Juse use this._openRepository instead of relying on CommitLogViewer
2364         to remember which repository is current. This was the only use of currentRepository.
2365
2366         * public/v3/components/commit-log-viewer.js:
2367         (CommitLogViewer):
2368         (CommitLogViewer.prototype.currentRepository): Deleted.
2369         (CommitLogViewer.prototype.view):
2370         (CommitLogViewer.prototype._fetchCommitLogs): Modernized and extracted from view to make it lazy.
2371         Call fetchForSingleRevision when precedingRevision is not specified or it's identical to lastRevision
2372         since the generic JSON API no longer supports being called with the identical revisions.
2373         (CommitLogViewer.prototype.render): Modernized & simplified the code.
2374         (CommitLogViewer.prototype._renderCommitList): Extracted from render to make it lazy.
2375         (CommitLogViewer.htmlTemplate): Add ID on caption & tbody so that they're more easily addressable.
2376         (CommitLogViewer.cssTemplate):
2377
2378         * public/v3/models/commit-log.js:
2379         (CommitLog.prototype.diff): No longer includes from/to revisions in the result. Also avoid adding
2380         1 to a Subversion-like starting revision for creating the label. See above. But we still do this
2381         for forming URLs due to the way tools like Trac work with Subversion revisions.
2382         (CommitLog.fetchBetweenRevisions): Rewritten using DataModel.prototype.cachedFetch with FIXME for
2383         what this function is supposed to be doing.
2384         (CommitLog._cachedCommitLogs): Deleted.
2385         (CommitLog.fetchForSingleRevision): Added.
2386         (CommitLog._constructFromRawData): Added.
2387
2388         * public/v3/models/data-model.js:
2389         (DataModelObject.cachedFetch): Don't parse query values as an integer. Just URL-escape them.
2390
2391         * public/v3/remote.js:
2392         (BrowserRemoteAPI.prototype.sendHttpRequest): Fixed a typo.
2393
2394         * server-tests/api-commits-tests.js: Renamed from api-commits.js. Updated the existing tests to
2395         use new query parameters and added more test cases.
2396
2397         * unit-tests/commit-log-tests.js: Updated the test cases now that CommitLog.prototype.diff no longer
2398         includes from/to values. They're computed in ChartRevisionRange instead.
2399
2400 2017-03-20  Ryosuke Niwa  <rniwa@webkit.org>
2401
2402         Fix os-build-fetcher.js and subprocess.js to make them work
2403         https://bugs.webkit.org/show_bug.cgi?id=169844
2404
2405         Reviewed by Antti Koivisto.
2406
2407         The script added in r213976 has a bug that it can execute commands to fetch subcommits in parallel.
2408         Some commands to poll the lsit of system components is not desirable to be ran in parallel.
2409
2410         * server-tests/resources/mock-subprocess.js:
2411         (MockSubprocess): Use const declaration.
2412         (MockSubprocess.resetAndWaitForInvocation): Added.
2413         (MockSubprocess.waitForInvocation): Renamed from waitingForInvocation. A function name must be a verb.
2414         See https://webkit.org/code-style-guidelines/#names-verb
2415         (MockSubprocess.reset): Set invocations.length to 0 so that tests can store a reference to the array
2416         regardless of whether reset is called or when it's called.
2417
2418         * server-tests/tools-os-build-fetcher-tests.js: Updated tests per the code change. Most of codes now
2419         expect each command to be ran seprately. e.g. if there were two commands to run, instead of expecting
2420         them to be both ran, and resolving invocation promises, we'd wait for one command to run, resolve,
2421         its subcommand to run, and then move onto the second top-level command. Also use a local reference
2422         to MockSubprocess.invocations instead of using the fully qualified name.
2423
2424         * tools/js/os-build-fetcher.js:
2425         (mapInSerialPromiseChain): Added. Calling a closure that returns a promise on each item in an array
2426         in serial (not asynchronous) is a very common pattern in this class.
2427         (OSBuildFetcher.fetchAndReportAllInOrder): Added.
2428         (OSBuildFetcher.prototype.fetchAndReportNewBuilds): Log what the number of builds being submitted.
2429         (OSBuildFetcher.prototype._fetchAvailableBuilds): Fixed the main bug. Using Promise.all would result
2430         in each top-level command to be execued in parallel. Since each subcommand is executed as soon as
2431         its parent command is executed, this results in commands to be executed in parallel.
2432         Added a whole bunch of logging so that we can at least detect a bug like this in the future.
2433         (OSBuildFetcher.prototype._commitsForAvailableBuilds): Cleanup the coding style.
2434         (OSBuildFetcher.prototype._addSubCommitsForBuild): Use mapInSerialPromiseChain. Tightened the assertion
2435         about the content returned by a subcommand.
2436
2437         * tools/js/subprocess.js: Fixed the bug that we were importing require('child_process').ChildProcess.
2438         execFile is defined on require('child_process') itself.
2439         (Subprocess.prototype.execute): Fixed a typo. this._childProcess doesn't exist.
2440         (Subprocess):
2441
2442         * tools/sync-os-versions.js: Renamed from tools/pull-os-versions.js.
2443         (syncLoop): Cleaned up the coding style a little. Also added logging about how long we're about to sleep.
2444
2445 2017-03-16  Ryosuke Niwa  <rniwa@webkit.org>
2446
2447         Add the file uploading capability to the perf dashboard.
2448         https://bugs.webkit.org/show_bug.cgi?id=169737
2449
2450         Reviewed by Chris Dumez.
2451
2452         Added /privileged-api/upload-file to upload a file, and /api/uploaded-file/ to download the file
2453         and retrieve its meta data based on its SHA256. We treat two files with the identical SHA256 as
2454         identical since anyone who can upload a file using this mechanism can execute arbitrary code in
2455         our bots anyway. This is important for avoiding uploading a large darwinup roots multiple times
2456         to the server, saving both user's time/bandwidth and server's disk space.
2457
2458         * config.json: Added uploadDirectory, uploadFileLimitInMB, and uploadUserQuotaInMB as options.
2459         * init-database.sql: Added uploaded_files table.
2460
2461         * public/api/uploaded-file.php: Added.
2462         (main): /api/uploaded-file/N would download uploaded_file with id=N. /api/uploaded-file/?sha256=X
2463         would return the meta data for uploaded_file with sha256=X.
2464         (stream_file_content): Streams the file content in 64KB chunks. We support Range & If-Range HTTP
2465         request headers so that browsers can pause and resume downloading of a large root file.
2466         (parse_range_header): Parses Range HTTP request header.
2467
2468         * public/include/json-header.php:
2469         (remote_user_name): Use the default argument of NULL.
2470
2471         * public/include/manifest-generator.php:
2472         (ManifestGenerator::generate): Include the maximum upload size in the manifest file to let the
2473         frontend code preemptively check the file size before attempting to submit a file.
2474
2475         * public/include/uploaded-file-helpers.php: Added.
2476         (format_uploaded_file):
2477         (uploaded_file_path_for_row):
2478
2479         * public/privileged-api/upload-file-form.html: Added. For debugging purposes.
2480         (fetchCSRFfToken):
2481         (upload):
2482
2483         * public/privileged-api/upload-file.php: Added.
2484         (main):
2485         (query_total_file_size):
2486         (create_uploaded_file_from_form_data):
2487
2488         * public/shared/common-remote.js:
2489         (CommonRemoteAPI.prototype.postFormData): Added.
2490         (CommonRemoteAPI.prototype.postFormDataWithStatus): Added.
2491         (CommonRemoteAPI.prototype.sendHttpRequestWithFormData): Added.
2492         (CommonRemoteAPI.prototype._asJSON): Throw an exception instead of calling a non-existent reject.
2493
2494         * public/v3/models/uploaded-file.js: Added.
2495         (UploadedFile): Added.
2496         (UploadedFile.uploadFile): Added.
2497         (UploadedFile.fetchUnloadedFileWithIdenticalHash): Added. Finds the file with the same SHA256 in
2498         the server to avoid uploading a large custom root multiple times.
2499         (UploadedFile._computeSHA256Hash): Added.
2500
2501         * public/v3/privileged-api.js:
2502         (PrivilegedAPI.prototype.sendRequest): Added the options dictionary as a third argument. For now,
2503         only support useFormData boolean.
2504
2505         * public/v3/remote.js:
2506         (BrowserRemoteAPI.prototype.sendHttpRequestWithFormData): Added.
2507
2508         * server-tests/api-manifest.js: Updated per the inclusion of fileUploadSizeLimit in the manifest.
2509         * server-tests/api-uploaded-file.js: Added.
2510         * server-tests/privileged-api-upload-file-tests.js: Added.
2511
2512         * server-tests/resources/temporary-file.js: Added.
2513         (TemporaryFile): Added. A helper class for creating a temporary file to upload.
2514         (TemporaryFile.makeTemporaryFileOfSizeInMB):
2515         (TemporaryFile.makeTemporaryFile):
2516         (TemporaryFile.inject):
2517
2518         * server-tests/resources/test-server.conf: Set upload_max_filesize and post_max_size for testing.
2519         * server-tests/resources/test-server.js:
2520         (TestServer.prototype.testConfig): Use uploadFileLimitInMB and uploadUserQuotaInMB of 2MB and 5MB.
2521         (TestServer.prototype._ensureDataDirectory): Create a directory to store uploaded files inside
2522         the data directory. In a production server, we can place it outside ServerRoot / DocumentRoot.
2523         (TestServer.prototype.cleanDataDirectory): Delete the aforementioned directory as needed.
2524
2525         * tools/js/database.js:
2526         (tableToPrefixMap): Added uploaded_files.
2527
2528         * tools/js/remote.js:
2529         (NodeRemoteAPI.prototype.sendHttpRequest): Added a dictionary to specify request headers and
2530         a callback to process the response as arguments. Fixed the bug that any 2xx code other than 200
2531         was resulting in a rejected promise. Also include the response headers in the result for tests.
2532         Finally, when content is a function, call that instead of writing the content since FormData
2533         requires a custom logic.
2534         (NodeRemoteAPI.prototype.sendHttpRequestWithFormData): Added.
2535
2536         * tools/js/v3-models.js: Include uploaded-file.js.
2537
2538         * tools/run-tests.py:
2539         (main): Add form-data as a new dependency.
2540
2541 2017-03-15  Dewei Zhu  <dewei_zhu@apple.com>
2542
2543         Fix unit test and bug fix for 'pull-os-versions.js' script.
2544         https://bugs.webkit.org/show_bug.cgi?id=169701
2545
2546         Reviewed by Ryosuke Niwa.
2547
2548         Fix unit tests warnings on node-6.10.0.
2549         Fix 'pull-os-versions.js' does not fetch new builds and report.
2550
2551         * server-tests/tools-os-build-fetcher-tests.js:
2552         (then):
2553         (beforeEach):
2554         (afterEach):
2555         * tools/pull-os-versions.js:
2556         (syncLoop):
2557
2558 2017-03-15  Ryosuke Niwa  <rniwa@webkit.org>
2559
2560         In-browser and node.js implementations of RemoteAPI should share some code
2561         https://bugs.webkit.org/show_bug.cgi?id=169695
2562
2563         Rubber-stamped by Antti Koivisto.
2564
2565         Extracted CommonRemoteAPI out of RemoteAPI implementations for node.js and browser. 
2566
2567         * public/shared/common-remote.js: Added.
2568         (CommonRemoteAPI): Added.
2569         (CommonRemoteAPI.prototype.postJSON): Extracted from RemoteAPI.
2570         (CommonRemoteAPI.prototype.postJSONWithStatus): Ditto.
2571         (CommonRemoteAPI.prototype.getJSON): Ditto.
2572         (CommonRemoteAPI.prototype.getJSONWithStatus): Ditto.
2573         (CommonRemoteAPI.prototype.sendHttpRequest): Added. Needs to implemented by a subclass.
2574         (CommonRemoteAPI.prototype._asJSON): Added.
2575         (CommonRemoteAPI.prototype._checkStatus): Added.
2576
2577         * public/v3/index.html: Include common-remote.js.
2578
2579         * public/v3/privileged-api.js:
2580         (PrivilegedAPI): Use class now that we don't include data.js.
2581         (PrivilegedAPI.sendRequest): Modernized the code.
2582         (PrivilegedAPI.requestCSRFToken): Ditto.
2583
2584         * public/v3/remote.js:
2585         (BrowserRemoteAPI): Renamed from RemoteAPI. window.RemoteAPI is now an instance of this class.
2586         (BrowserRemoteAPI.prototype.sendHttpRequest): Moved from RemoteAPI.sendHttpRequest.
2587         (BrowserRemoteAPI.prototype.sendHttpRequest):
2588
2589         * server-tests/privileged-api-create-analysis-task-tests.js: Updated tests since NodeJSRemoteAPI
2590         now throws the JSON status as an error to be consistent with BrowserRemoteAPI.
2591         * server-tests/privileged-api-create-test-group-tests.js: Ditto.
2592         * server-tests/privileged-api-upate-run-status.js: Ditto.
2593
2594         * tools/js/buildbot-triggerable.js:
2595         (BuildbotTriggerable.prototype.syncOnce): Just use postJSONWithStatus instead of manually
2596         checking the status.
2597
2598         * tools/js/remote.js:
2599         (NodeRemoteAPI): Renamed from RemoteAPI. Still exported as RemoteAPI.
2600         (NodeRemoteAPI.prototype.constructor):
2601         (NodeRemoteAPI.prototype.sendHttpRequest): Modernized the code.
2602
2603 2017-03-15  Ryosuke Niwa  <rniwa@webkit.org>
2604
2605         Fix server tests after r213998 and r213969
2606         https://bugs.webkit.org/show_bug.cgi?id=169690
2607
2608         Reviewed by Antti Koivisto.
2609
2610         Fixed the existing server tests.
2611
2612         * public/v3/models/analysis-task.js:
2613         (AnalysisTask.prototype._updateRemoteState): Use the relative path from the root so that it works inside tests.
2614         (AnalysisTask.prototype.associateBug): Ditto.
2615         (AnalysisTask.prototype.dissociateBug): Ditto.
2616         (AnalysisTask.prototype.associateCommit): Ditto.
2617         (AnalysisTask.prototype.dissociateCommit): Ditto.
2618         (AnalysisTask._fetchSubset): Ditto.
2619         (AnalysisTask.fetchAll): Ditto.
2620         * public/v3/models/test-group.js:
2621         (TestGroup.prototype.updateName): Ditto.
2622         (TestGroup.prototype.updateHiddenFlag): Ditto.
2623         (TestGroup.createAndRefetchTestGroups): Ditto.
2624         (TestGroup.cachedFetch): Ditto.
2625         * server-tests/api-manifest.js: Reverted an inadvertant change in r213969.
2626         * tools/js/database.js:
2627         (tableToPrefixMap): Added analysis_strategies.
2628         * unit-tests/analysis-task-tests.js: Updated expectations per changes to AnalysisTask.
2629
2630 2017-03-15  Ryosuke Niwa  <rniwa@webkit.org>
2631
2632         Add tests for privileged-api/create-analysis-task and privileged-api/create-test-group
2633         https://bugs.webkit.org/show_bug.cgi?id=169688
2634
2635         Rubber-stamped by Antti Koivisto.
2636
2637         Added tests for privileged-api/create-analysis-task and privileged-api/create-test-group, and fixed newly found bugs.
2638
2639         * public/privileged-api/create-analysis-task.php:
2640         (main): Fixed the bug that we were not explicitly checking whether start_run and end_run were integers or not.
2641         Also return InvalidTimeRange when start and end times are identical as that makes no sense for an analysis task.
2642
2643         * public/privileged-api/create-test-group.php:
2644         (main): Fixed a bug that we were not explicitly checking task and repetitionCount to be an integer.
2645         (ensure_commit_sets): Fixed the bug that the number of commit sets weren't checked. 
2646
2647         * server-tests/privileged-api-create-analysis-task-tests.js: Added.
2648         * server-tests/privileged-api-create-test-group-tests.js: Added.
2649
2650         * server-tests/resources/common-operations.js:
2651         (prepareServerTest): Increase the timeout from 1s to 5s.
2652
2653         * server-tests/resources/mock-data.js:
2654         (MockData.addMockData): Use a higher database ID of 20 for a mock build_slave to avoid a conflict with auto-generated IDs.
2655
2656 2017-03-15  Ryosuke Niwa  <rniwa@webkit.org>
2657
2658         Make unit tests return a promise instead of manually calling done
2659         https://bugs.webkit.org/show_bug.cgi?id=169663
2660
2661         Reviewed by Antti Koivisto.
2662
2663         Make the existing unit tests always reutrn a promise instead of manually calling "done" callback as done
2664         in r213969. The promise tests are a lot more stable and less error prone.
2665
2666         Also use MockRemoteAPI.waitForRequest() instead of chaining two resolved promises where appropriate.
2667
2668         * unit-tests/analysis-task-tests.js:
2669         * unit-tests/buildbot-syncer-tests.js:
2670         * unit-tests/checkconfig.js:
2671         * unit-tests/privileged-api-tests.js:
2672
2673 2017-03-15  Dewei Zhu  <dewei_zhu@apple.com>
2674
2675         Rewrite 'pull-os-versions' script in Javascript to add support for reporting os revisions with sub commits.
2676         https://bugs.webkit.org/show_bug.cgi?id=169542
2677
2678         Reviewed by Ryosuke Niwa.
2679
2680         Extend '/api/commits/<repository>/last-reported' to accept a range and return last reported commits in given range.
2681         Rewrite 'pull-os-versions' in JavaScript and add unit tests for it.
2682         Instead of writing query manually while searching criteria contains null columns, use the methods provided in 'db.php'.
2683         Add '.gitignore' file to ommit files generated by while running tests/instances locally.
2684
2685         * .gitignore: Added.
2686         * public/api/commits.php:
2687         * public/api/report-commits.php:
2688         * public/include/commit-log-fetcher.php:
2689         * public/include/db.php: 'null_columns' of prepare_params should be a reference.
2690         * public/include/report-processor.php:
2691         * server-tests/api-commits.js:
2692         (then):
2693         * server-tests/api-report-commits-tests.js:
2694         * server-tests/resources/mock-logger.js: Added.
2695         (MockLogger):
2696         (MockLogger.prototype.log):
2697         (MockLogger.prototype.error):
2698         * server-tests/resources/mock-subprocess.js: Added.
2699         (MockSubprocess.call):
2700         (MockSubprocess.waitingForInvocation):
2701         (MockSubprocess.inject):
2702         (MockSubprocess.reset):
2703         * server-tests/tools-buildbot-triggerable-tests.js:
2704         (MockLogger): Deleted.
2705         (MockLogger.prototype.log): Deleted.
2706         (MockLogger.prototype.error): Deleted.
2707         * server-tests/tools-os-build-fetcher-tests.js: Added.
2708         (beforeEach):
2709         (return.waitingForInvocationPromise.then):
2710         (then):
2711         (string_appeared_here.return.waitingForInvocationPromise.then):
2712         (return.addSlaveForReport.emptyReport.then):
2713         * tools/js/os-build-fetcher.js: Added.
2714         (OSBuildFetcher):
2715         (OSBuildFetcher.prototype._fetchAvailableBuilds):
2716         (OSBuildFetcher.prototype._computeOrder):
2717         (OSBuildFetcher.prototype._commitsForAvailableBuilds.return.this._subprocess.call.then.):
2718         (OSBuildFetcher.prototype._commitsForAvailableBuilds):
2719         (OSBuildFetcher.prototype._addSubCommitsForBuild):
2720         (OSBuildFetcher.prototype._submitCommits):
2721         (OSBuildFetcher.prototype.fetchAndReportNewBuilds):
2722         * tools/js/subprocess.js: Added.
2723         (const.childProcess.require.string_appeared_here.Subprocess.prototype.call):
2724         (const.childProcess.require.string_appeared_here.Subprocess):
2725         * tools/pull-os-versions.js: Added.
2726         (main):
2727         (syncLoop):
2728         * tools/sync-commits.py:
2729         (Repository.fetch_commits_and_submit):
2730
2731 2017-03-14  Ryosuke Niwa  <rniwa@webkit.org>
2732
2733         Make server tests return a promise instead of manually calling done
2734         https://bugs.webkit.org/show_bug.cgi?id=169648
2735
2736         Rubber-stamped by Chris Dumez.
2737
2738         Make the existing server tests always reutrn a promise instead of manually calling "done" callback.
2739         The promise tests are a lot more stable and less error prone.
2740
2741         Also use arrow functions everywhere and use prepareServerTest, renamed from connectToDatabaseInEveryTest,
2742         in more tests instead of manually connecting to database in every test, and reset v3 models.
2743
2744         * server-tests/admin-platforms-tests.js:
2745         * server-tests/admin-reprocess-report-tests.js:
2746         * server-tests/api-build-requests-tests.js:
2747         * server-tests/api-manifest.js:
2748         * server-tests/api-measurement-set-tests.js:
2749         (.postReports): Deleted. Not used in any test.
2750         * server-tests/api-report-commits-tests.js:
2751         * server-tests/api-report-tests.js:
2752         * server-tests/api-update-triggerable.js:
2753         * server-tests/privileged-api-upate-run-status.js:
2754         * server-tests/resources/common-operations.js:
2755         (prepareServerTest): Renamed from connectToDatabaseInEveryTest. Increase the timeout and reset v3 models.
2756         * server-tests/tools-buildbot-triggerable-tests.js:
2757
2758 2017-03-12  Ryosuke Niwa  <rniwa@webkit.org>
2759
2760         Rename RootSet to CommitSet
2761         https://bugs.webkit.org/show_bug.cgi?id=169580
2762
2763         Rubber-stamped by Chris Dumez.
2764
2765         Renamed root_sets to commit_sets and roots to commit_set_relationships in the database schema, and renamed
2766         related classes in public/v3/ and tools accordingly.
2767
2768         RootSet, MeasurementRootSet, and CustomRootSet are respectively renamed to CommitSet, MeasurementCommitSet,
2769         and CustomCommitSet.
2770
2771         In order to migrate the database, run:
2772         ```
2773         BEGIN;
2774         ALTER TABLE root_sets RENAME TO commit_sets;
2775         ALTER TABLE commit_sets RENAME COLUMN rootset_id TO commitset_id;
2776         ALTER TABLE roots RENAME TO commit_set_relationships;
2777         ALTER TABLE commit_set_relationships RENAME COLUMN root_set TO commitset_set;
2778         ALTER TABLE commit_set_relationships RENAME COLUMN root_commit TO commitset_commit;
2779         ALTER TABLE build_requests RENAME COLUMN request_root_set TO request_commit_set;
2780         END;
2781         ```
2782
2783         * browser-tests/index.html:
2784         * init-database.sql:
2785         * public/api/build-requests.php:
2786         (main):
2787         * public/api/test-groups.php:
2788         (main):
2789         (format_test_group):
2790         * public/include/build-requests-fetcher.php:
2791         (BuildRequestsFetcher::__construct):
2792         (BuildRequestsFetcher::results_internal):
2793         (BuildRequestsFetcher::commit_sets): Renamed from root_sets.
2794         (BuildRequestsFetcher::commits): Renamed from roots.
2795         (BuildRequestsFetcher::fetch_commits_for_set_if_needed): Renamed from fetch_roots_for_set_if_needed.
2796         * public/privileged-api/create-test-group.php:
2797         (main):
2798         (ensure_commit_sets): Renamed from commit_sets_from_root_sets.
2799         * public/v3/components/analysis-results-viewer.js:
2800         (AnalysisResultsViewer.prototype.buildRowGroups):
2801         (AnalysisResultsViewer.prototype._collectCommitSetsInTestGroups): Renamed from _collectRootSetsInTestGroups.
2802         (AnalysisResultsViewer.prototype._buildRowsForPointsAndTestGroups):
2803         (AnalysisResultsViewer.prototype._buildRowsForPointsAndTestGroups):
2804         (AnalysisResultsViewer.CommitSetInTestGroup): Renamed from RootSetInTestGroup.
2805         (AnalysisResultsViewer.CommitSetInTestGroup.prototype.constructor):
2806         (AnalysisResultsViewer.CommitSetInTestGroup.prototype.commitSet): Renamed from rootSet.
2807         (AnalysisResultsViewer.CommitSetInTestGroup.prototype.succeedingCommitSet): Renamed from succeedingRootSet.
2808         (AnalysisResultsViewer.TestGroupStackingBlock.prototype.constructor):
2809         (AnalysisResultsViewer.TestGroupStackingBlock.prototype.addRowIndex):
2810         (AnalysisResultsViewer.TestGroupStackingBlock.prototype.isComplete):
2811         (AnalysisResultsViewer.TestGroupStackingBlock.prototype.startRowIndex):
2812         (AnalysisResultsViewer.TestGroupStackingBlock.prototype.endRowIndex):
2813         (AnalysisResultsViewer.TestGroupStackingBlock.prototype._computeTestGroupStatus):
2814         * public/v3/components/chart-revision-range.js:
2815         (ChartRevisionRange.prototype._revisionForPoint):
2816         (ChartRevisionRange.prototype._computeRevisionList):
2817         * public/v3/components/customizable-test-group-form.js:
2818         (CustomizableTestGroupForm.prototype.constructor):
2819         (CustomizableTestGroupForm.prototype.setCommitSetMap): Renamed from setRootSetMap.
2820         (CustomizableTestGroupForm.prototype._submitted):
2821         (CustomizableTestGroupForm.prototype._computeCommitSetMap): Renamed from _computeRootSetMap.
2822         (CustomizableTestGroupForm.prototype.render): Renamed from render.
2823         (CustomizableTestGroupForm.prototype._constructRevisionRadioButtons):
2824         * public/v3/components/results-table.js:
2825         (ResultsTable.prototype.render):
2826         (ResultsTable.prototype._createRevisionListCells):
2827         (ResultsTable.prototype._computeRepositoryList):
2828         (ResultsTableRow.prototype.constructor):
2829         (ResultsTableRow.prototype.commitSet): Renamed from rootSet.
2830         * public/v3/components/test-group-results-table.js:
2831         (TestGroupResultsTable.prototype.buildRowGroups):
2832         * public/v3/index.html:
2833         * public/v3/models/build-request.js:
2834         (BuildRequest.prototype.constructor):
2835         (BuildRequest.prototype.updateSingleton):
2836         (BuildRequest.prototype.commitSet): Renamed from rootSet.
2837         (BuildRequest.constructBuildRequestsFromData):
2838         * public/v3/models/commit-set.js: Renamed from public/v3/models/root-set.js.
2839         (CommitSet): Renamed from RootSet.
2840         (CommitSet.containsMultipleCommitsForRepository):
2841         (MeasurementCommitSet): Renamed from MeasurementRootSet.
2842         (MeasurementCommitSet.prototype.namedStaticMap):
2843         (MeasurementCommitSet.prototype.ensureNamedStaticMap):
2844         (MeasurementCommitSet.namedStaticMap):
2845         (MeasurementCommitSet.ensureNamedStaticMap):
2846         (MeasurementCommitSet.ensureSingleton):
2847         (CustomCommitSet): Renamed from CustomRootSet.
2848         * public/v3/models/measurement-adaptor.js:
2849         (MeasurementAdaptor.prototype.applyTo):
2850         * public/v3/models/test-group.js:
2851         (TestGroup.prototype.constructor):
2852         (TestGroup.prototype.addBuildRequest):
2853         (TestGroup.prototype.repetitionCount):
2854         (TestGroup.prototype.requestedCommitSets): Renamed from requestedRootSets.
2855         (TestGroup.prototype.requestsForCommitSet): Renamed from requestsForRootSet.
2856         (TestGroup.prototype.labelForCommitSet): Renamed from labelForRootSet.
2857         (TestGroup.prototype.didSetResult):
2858         (TestGroup.prototype.compareTestResults):
2859         (TestGroup.prototype._valuesForCommitSet): Renamed from _valuesForRootSet.
2860         (TestGroup.prototype.createAndRefetchTestGroups):
2861         * public/v3/pages/analysis-task-page.js:
2862         (AnalysisTaskPage.prototype.render):
2863         (AnalysisTaskPage.prototype._retryCurrentTestGroup):
2864         (AnalysisTaskPage.prototype._createNewTestGroupFromChart):
2865         (AnalysisTaskPage.prototype._createNewTestGroupFromViewer):
2866         (AnalysisTaskPage.prototype._createTestGroupAfterVerifyingCommitSetList):
2867         * server-tests/api-build-requests-tests.js:
2868         * server-tests/resources/mock-data.js:
2869         (MockData.resetV3Models):
2870         (MockData.addMockData):
2871         (MockData.addAnotherMockTestGroup):
2872         * tools/detect-changes.js:
2873         (createAnalysisTaskAndNotify):
2874         * tools/js/buildbot-syncer.js:
2875         (BuildbotSyncer.prototype._propertiesForBuildRequest):
2876         (BuildbotSyncer.prototype._revisionSetFromCommitSetWithExclusionList):
2877         * tools/js/database.js:
2878         (tableToPrefixMap):
2879         * tools/js/v3-models.js:
2880         * tools/sync-buildbot.js:
2881         (syncLoop):
2882         * tools/sync-with-buildbot.py: Deleted. No longer used.
2883         * unit-tests/analysis-task-tests.js:
2884         * unit-tests/build-request-tests.js:
2885         (sampleBuildRequestData):
2886         * unit-tests/buildbot-syncer-tests.js:
2887         (sampleCommitSetData):
2888         * unit-tests/measurement-adaptor-tests.js:
2889         * unit-tests/measurement-set-tests.js:
2890         * unit-tests/resources/mock-v3-models.js:
2891         (MockModels.inject):
2892         * unit-tests/test-groups-tests.js:
2893         (sampleTestGroup):
2894
2895 2017-03-13  Ryosuke Niwa  <rniwa@webkit.org>
2896
2897         Database's query functions should support querying for a row with NULL value
2898         https://bugs.webkit.org/show_bug.cgi?id=169504
2899
2900         Reviewed by Antti Koivisto.
2901
2902         Add the support for calling select_* with one of column values set to NULL.
2903         This feature is useful in webkit.org/b/146374 and webkit.org/b/168962.
2904
2905         * public/include/db.php:
2906         (Database::prepare_params): Added $null_columns as an optional argument.
2907         (Database::select_conditions_with_null_columns): Added. Builds up a query string by appending AND x is NULL
2908         to match columns whose value must be NULL.
2909         (Database::_select_update_or_insert_row):
2910         (Database::select_rows):
2911
2912 2017-03-13  Dewei Zhu  <dewei_zhu@apple.com>
2913
2914         Add the ability to report a commit with sub-commits.
2915         https://bugs.webkit.org/show_bug.cgi?id=168962
2916
2917         Reviewed by Ryosuke Niwa.
2918
2919         Introduce 'commit_ownerships' which records ownership between commits.
2920         On existing production server, run ```
2921             CREATE TABLE commit_ownerships (
2922                 commit_owner integer NOT NULL REFERENCES commits ON DELETE CASCADE,
2923                 commit_ownee integer NOT NULL REFERENCES commits ON DELETE CASCADE,
2924                 PRIMARY KEY (commit_owner, commit_ownee)
2925             );
2926             ALTER TABLE repositories RENAME repository_parent TO repository_owner;
2927             ALTER TABLE repositories DROP repository_name_must_be_unique;
2928             CREATE UNIQUE INDEX repository_name_owner_unique_index ON repositories (repository_owner, repository_name) WHERE repository_owner IS NOT NULL;
2929             CREATE UNIQUE INDEX repository_name_unique_index ON repositories (repository_name) WHERE repository_owner IS NULL;
2930         ``` to update database.
2931         Add unit-tests to cover this change.
2932
2933         * init-database.sql:
2934         * public/api/report-commits.php:
2935         * public/include/commit-log-fetcher.php:
2936         * public/include/db.php:
2937         * public/include/manifest-generator.php:
2938         * public/include/report-processor.php:
2939         * public/v3/models/repository.js:
2940         (Repository):
2941         (Repository.prototype.owner):
2942         * server-tests/admin-reprocess-report-tests.js:
2943         (addBuilderForReport.simpleReportWithRevisions.0.then):
2944         (then):
2945         * server-tests/api-manifest.js:
2946         (then):
2947         * server-tests/api-report-commits-tests.js:
2948         (addSlaveForReport.sameRepositoryNameInSubCommitAndMajorCommit.then):
2949         (then):
2950         (addSlaveForReport.systemVersionCommitWithSubcommits.then):
2951         (addSlaveForReport.multipleSystemVersionCommitsWithSubcommits.then):
2952         (addSlaveForReport.systemVersionCommitWithEmptySubcommits.then):
2953         (addSlaveForReport.systemVersionCommitAndSubcommitWithTimestamp.then):
2954         * tools/js/database.js:
2955
2956 2017-03-07  Ryosuke Niwa  <rniwa@webkit.org>
2957
2958         Update ReadMe.md to use directory format for backing up & restoring the database
2959         https://bugs.webkit.org/show_bug.cgi?id=169263
2960
2961         Reviewed by Joseph Pecoraro.
2962
2963         Update ReadMe.md's instruction to backup and restore the database to use directory format instead of
2964         piping it to gzip. The new command will backup and restore the database with multiple concurrent processes
2965         with a custom compression level.
2966
2967         * ReadMe.md:
2968
2969 2017-03-02  Ryosuke Niwa  <rniwa@webkit.org>
2970
2971         Make baseline data points selectable
2972         https://bugs.webkit.org/show_bug.cgi?id=169069
2973         <rdar://problem/29209427>
2974
2975         Reviewed by Antti Koivisto.
2976
2977         Add the capability to select data points other than "current" configuration type.
2978
2979         This patch refactors the way the "chart status" is computed. Before this patch, ChartStatusView was
2980         responsible for determining two data points for which to compute the status, and computing the status
2981         between two data points. ChartPaneStatusView which inherits from ChartStatusView and used in the charts
2982         page relied upon ChartStatusView to compute these values, and computed the list of revision ranges for
2983         each relevant repository between the data points. ChartPane then had callbacks on ChartPaneStatusView
2984         to know whenever these values changed. Because of this entangled mess, ChartStatusView had to be aware
2985         of InteractiveTimeSeriesChart even though only ChartPaneStatusView could be used with it.
2986
2987         This patch dramatically simplifies the situation by adding referencePoints() on TimeSeriesChart and
2988         InteractiveTimeSeriesChart which returns the current point, the previous point if there is any, and
2989         their time series view. It also extracts ChartStatusEvaluator which computes the current status values
2990         and ChartRevisionRange which computes a list of revision differences both based on the referencePoints.
2991         As a result, ChartPaneStatusView no longer inherits from ChartStatusView, and ChartStatusView has been
2992         renamed to DashboardChartStatusView to reflect its purpose. Furthermore, ChartPane which used to rely on
2993         ChartPaneStatusView's revisionCallback to update the commit log viewer simply uses another instance of
2994         ChartRevisionRange, eliminating the need for the callback.
2995
2996         To implement these classes easily, this patch also introduces a new class, LazilyEvaluatedFunction to
2997         memoize the return value of a function when called with the same arguments. Delaying the computation of
2998         a value and avoiding the work when the values are the same is a very common pattern in the perf dashboard
2999         so I expect this class would be used in a lot more places in the future.
3000
3001         * browser-tests/chart-revision-range-tests.js: Added. Tests for ChartRevisionRange.
3002         * browser-tests/chart-status-evaluator-tests.js: Added. Tests for ChartStatusEvaluator.
3003
3004         * browser-tests/index.html:
3005         (BrowsingContext):
3006         (BrowsingContext.importScripts): Fixed the bug that calling importScripts twice results in MockRemoteAPI
3007         being loaded twice.
3008         (ChartTest.importChartScripts): Import more model objects.
3009         (ChartTest.sampleCluster): Made this a getter.
3010         (ChartTest.makeModelObjectsForSampleCluster):
3011         (ChartTest.makeSampleCluster): Added. Cutomizes the valus of baseline / target based on options.
3012         (ChartTest.respondWithSampleCluster): Now takes an options argument for makeSampleCluster.
3013
3014         * public/v3/components/chart-pane-base.js:
3015         (ChartPaneBase): Added _openRepository to keep track of the currently open repository instead of relying
3016         on _mainChartStatus or _commitLogViewer to keep track of it.
3017         (ChartPaneBase.prototype.configure):  The callback for when the user clicked on a repository name in
3018         ChartPaneStatusView has been replaced by "openRepository" action.
3019         (ChartPaneBase.prototype.setOpenRepository): Moved from ChartPane.
3020         (ChartPaneBase.prototype._mainSelectionDidChange):
3021         (ChartPaneBase.prototype._indicatorDidChange):
3022         (ChartPaneBase.prototype._didFetchData):
3023         (ChartPaneBase.prototype._updateCommitLogViewer): Renamed from _updateStatus.
3024         (ChartPaneBase.prototype.openNewRepository): Renamed from _requestOpeningCommitViewer. Fixed a bug that
3025         clicking on the repository name inside ChartPaneStatusView would not focus the pane, which resulted in
3026         arrow keys to be ignored instead of moving the main chart's indicator or the currently open repository.
3027         (ChartPaneBase.prototype._keyup):
3028         (ChartPaneBase.prototype._moveOpenRepository): Moved from ChartPaneStatusView's
3029         moveRepositoryWithNotification. Used when changing the open repository by up/down arrow keys.
3030
3031         * public/v3/components/chart-revision-range.js: Added. Extracted from ChartPaneStatusView.
3032         (ChartRevisionRange): Added.
3033         (ChartRevisionRange.prototype.revisionList): Added.
3034         (ChartRevisionRange.prototype.rangeForRepository): Added.
3035         (ChartRevisionRange._revisionForPoint): Added. Extracted from ChartPaneStatusView's
3036         _updateRevisionListForNewCurrentRepository.
3037         (ChartRevisionRange._computeRevisionList): Ditto from computeChartStatusLabels.
3038
3039         * public/v3/components/chart-status-evaluator.js: Added.
3040         (ChartStatusEvaluator): Added.
3041         (ChartStatusEvaluator.prototype.status): Added.
3042         (ChartStatusEvaluator.computeChartStatus): Added. Extracted from ChartStatusView's updateStatusIfNeeded.
3043
3044         * public/v3/components/chart-status-view.js: Removed.
3045         (ChartStatusView): Deleted. Split into ChartStatusEvaluator and DashboardChartStatusView.
3046
3047         * public/v3/components/chart-styles.js:
3048         (ChartStyles.baselineStyle): Make baseline data points interactive. This single line change is what
3049         enables the user to interact with the data points. The rest of changes in this patch mostly deals with
3050         the status text such as "5% worse than baseline" and the list of revisions shown in the commit log viewer
3051         which would have shown the wrong range without these changes.
3052
3053         * public/v3/components/dashboard-chart-status-view.js: Added. Extracted from ChartStatusView.
3054         (DashboardChartStatusView): Added.
3055         (DashboardChartStatusView.prototype.render): Added.
3056         (DashboardChartStatusView.htmlTemplate): Added.
3057         (DashboardChartStatusView.cssTemplate): Added.
3058
3059         * public/v3/components/interactive-time-series-chart.js:
3060         (InteractiveTimeSeriesChart.prototype.referencePoints): Added. Return the first point and the last point
3061         as the reference points when there is a selection. Only report the previous point if they are distinct as
3062         showing a range of revisions from a data point to itself makes no sense. When there is a indicator simply
3063         return it and its previous point as reference points. Otherwise return null unlike TimeSeriesChart's
3064         referencePoints which always returns the latest point as the reference point.
3065
3066         * public/v3/components/time-series-chart.js:
3067         (TimeSeriesChart.prototype.referencePoints): Added. Return the latest point as the reference point. It
3068         never returns the previous point even if there were more data points as there is no way for the user to
3069         specify which data points to compare.
3070
3071         * public/v3/index.html: Include newly added files.
3072
3073         * public/v3/lazily-evaluated-function.js: Added.
3074         (LazilyEvaluatedFunction): Added.
3075         (LazilyEvaluatedFunction.prototype.evaluate): Added.
3076
3077         * public/v3/models/commit-log.js:
3078         (CommitLog.prototype.diff): Fixed a bug that computing the diff of two Subversion-like revisions results
3079         in "from" field to be unexpectedly an integer instead of a string.
3080
3081         * public/v3/models/metric.js:
3082         (Metric): Moved the code to compute the unit from the metric name from v2's RunsData class. This makes
3083         writing tests easier since it eliminates the need to load v2's data.js.
3084         (Metric.prototype.unit):
3085         (Metric.prototype.isSmallerBetter): Ditto for determining whether the unit is smaller-is-better.
3086
3087         * public/v3/pages/analysis-task-page.js:
3088         (AnalysisTaskChartPane.prototype._updateStatus): Deleted the unused code.
3089
3090         * public/v3/pages/chart-pane-status-view.js:
3091         (ChartPaneStatusView): No longer inherits from ChartStatusView. Uses ChartStatusEvaluator and
3092         ChartRevisionRange to to compute the chart status and the list of revision changes.
3093         (ChartPaneStatusView.prototype.pointsRangeForAnalysis): Deleted.
3094         (ChartPaneStatusView.prototype.render): Split it into _renderStatus and _renderBuildRevisionTable using
3095         LazilyEvaluatedFunction.
3096         (ChartPaneStatusView.prototype._renderStatus): Added.
3097         (ChartPaneStatusView.prototype._renderBuildRevisionTable): Added.
3098         (ChartPaneStatusView.prototype.setCurrentRepository): _updateRevisionListForNewCurrentRepository has been
3099         moved into ChartRevisionRange. Just enqueue itself to re-render.
3100         (ChartPaneStatusView.prototype._setRevisionRange): Deleted.
3101         (ChartPaneStatusView.prototype.moveRepositoryWithNotification): Deleted.
3102         (ChartPaneStatusView.prototype.updateRevisionList): Deleted.
3103         (ChartPaneStatusView.prototype._updateRevisionListForNewCurrentRepository): Deleted.
3104         (ChartPaneStatusView.prototype.computeChartStatusLabels): Deleted.
3105         (ChartPaneStatusView.htmlTemplate):
3106         (ChartPaneStatusView.cssTemplate):
3107
3108         * public/v3/pages/chart-pane.js:
3109         (ChartPane.prototype.openNewRepository): Overrides the one in ChartPaneBase, which has been renamed from
3110         _requestOpeningCommitViewer.
3111         (ChartPane.prototype._analyzeRange):
3112         (ChartPane.prototype._renderActionToolbar): Use the main chart's selection directly to determine whether
3113         an analysis task can be created for the currenty selected range.
3114
3115         * public/v3/pages/dashboard-page.js:
3116         (DashboardPage.prototype._createChartForCell):
3117
3118         * unit-tests/lazily-evaluated-function-tests.js: Added. Tests for LazilyEvaluatedFunction.
3119
3120 2017-03-01  Ryosuke Niwa  <rniwa@webkit.org>
3121
3122         Build fix after r212853. Make creating an analysis task work again.
3123
3124         * public/v3/pages/analysis-task-page.js:
3125         (AnalysisTaskPage.prototype.render):
3126
3127 2017-02-27  Ryosuke Niwa  <rniwa@webkit.org>
3128
3129         Fix tests after r213119 and r213120.
3130
3131         * browser-tests/time-series-chart-tests.js:
3132         (return.ChartTest.importChartScripts.context.then):
3133         (string_appeared_here.then): Deleted.
3134
3135 2017-02-27  Ryosuke Niwa  <rniwa@webkit.org>
3136
3137         Removed the unused code that was supposed to be removed in the previous commit.
3138
3139         * browser-tests/time-series-chart-tests.js:
3140
3141 2017-02-27  Ryosuke Niwa  <rniwa@webkit.org>
3142
3143         Split tests for InteractiveTimeSeriesChart into a separate test file.
3144         https://bugs.webkit.org/show_bug.cgi?id=168960
3145
3146         Reviewed by Joseph Pecoraro.
3147
3148         Extracted the test cases for InteractiveTimeSeriesChart charts from time-series-chart-tests.js
3149         into interactive-time-series-chart-tests.js now that the former file has gotten really big over time.
3150
3151         Also extracted a bunch of helper functions time-series-chart-tests.js as ChartTest in index.html.
3152         Any test which instantiates a time series chart can use this helper class.
3153
3154         * browser-tests/index.html:
3155         (ChartTest.importChartScripts): Ditto.
3156         (ChartTest.posixTime): Moved from time-series-chart-tests.js.
3157         (ChartTest.sampleCluster): Ditto.
3158         (ChartTest.createChartWithSampleCluster): Ditto.
3159         (ChartTest.createInteractiveChartWithSampleCluster): Ditto.
3160         (ChartTest.respondWithSampleCluster):
3161         * browser-tests/interactive-time-series-chart-tests.js: Extracted from time-series-chart-tests.js.
3162         * browser-tests/time-series-chart-tests.js:
3163         (posixTime): Moved.
3164         (dayInMilliseconds): Moved.
3165         (sampleCluster): Moved.
3166         (createChartWithSampleCluster): Moved.
3167         (createInteractiveChartWithSampleCluster): Moved.
3168         (respondWithSampleCluster): Moved.
3169         * unit-tests/analysis-task-tests.js: Fixed a typo. s/adopter/adapter/.
3170
3171 2017-02-27  Ryosuke Niwa  <rniwa@webkit.org>
3172
3173         Calling build() on a baseline point results in an exception
3174         https://bugs.webkit.org/show_bug.cgi?id=168959
3175
3176         Reviewed by Joseph Pecoraro.
3177
3178         Some baseline points may lack the build information. e.g. A custom data point made by an user.
3179         Only instantiate Build object in a point object returned by MeasurementAdaptor when the builder id
3180         is available so that we don't hit an assertion inside Build's constructor.
3181
3182         * public/v3/models/measurement-adaptor.js:
3183         (MeasurementAdaptor.prototype.applyTo..build): Only instantiate Build when builderId is set.
3184         * unit-tests/measurement-adaptor-tests.js: Added a test case.
3185
3186 2017-02-27  Ryosuke Niwa  <rniwa@webkit.org>
3187
3188         Arrow key shouldn't move the indicator beyond the visible points
3189         https://bugs.webkit.org/show_bug.cgi?id=168956
3190
3191         Reviewed by Joseph Pecoraro.
3192
3193         The bug was caused by moveLockedIndicatorWithNotification using the full sampled time series view
3194         instead of the one constrained by the domain. Since the time series chart expands the visible domain
3195         to include at least one point before the start time and one point after the end tiem to draw lines
3196         extending beyond the visible region (otherwise it looks as though the graph ends there), we need to
3197         use a view constrained by the start time and the end time before looking for a next/previous point.
3198
3199         * browser-tests/time-series-chart-tests.js: Added test cases for moveLockedIndicatorWithNotification.
3200         * public/v3/components/interactive-time-series-chart.js:
3201         (InteractiveTimeSeriesChart.prototype.moveLockedIndicatorWithNotification): Fixed the bug. Also
3202         enqueue itself to render instead of relying on a parent component to do it.
3203
3204 2017-02-27  Ryosuke Niwa  <rniwa@webkit.org>
3205
3206         A Locked indicator should be visually distinct from an unlocked indicator
3207         https://bugs.webkit.org/show_bug.cgi?id=168868
3208         <rdar://problem/29666054>
3209
3210         Reviewed by Antti Koivisto.
3211
3212         Added the support for specifying options.lockedIndicator in addition to options.indicator to style
3213         an locked indicator differently from an unlocked one.
3214
3215         * browser-tests/time-series-chart-tests.js: Added new test cases for indicators.
3216         (createChartWithSampleCluster): Renamed and swapped the order of arguments to better match
3217         TimeSeriesChart's constructor. Now the second argument is an array of source as is in the constructor.
3218         (createInteractiveChartWithSampleCluster): Added.
3219
3220         * public/v3/components/chart-styles.js:
3221         (ChartStyles.overviewChartOptions): Changed the color of a selection to blue.
3222         (ChartStyles.mainChartOptions): Ditto. Also use a different style for a locked indicator.
3223
3224         * public/v3/components/interactive-time-series-chart.js:
3225         (InteractiveTimeSeriesChart.prototype._layout): Removed the unused variable.
3226         (InteractiveTimeSeriesChart.prototype._renderChartContent): Use options.lockedIndicator when rendering
3227         a locked indicator. Also stroke the circle in addition to filling it so that we can use a blue circle
3228         with a white hole for a locked indicator to make it even more visually distinctive from an unlocked one.
3229
3230 2017-02-25  Dewei Zhu  <dewei_zhu@apple.com>
3231
3232         Commit should order by 'commit_order' as secondary key.
3233         https://bugs.webkit.org/show_bug.cgi?id=168866
3234
3235         Reviewed by Ryosuke Niwa.
3236
3237         Currently, commits are sorted by 'commit_time' only.
3238         We should use 'commit_order' as secondary key when 'commit_time' is equal or null.
3239
3240         * public/include/commit-log-fetcher.php:
3241         * public/include/db.php:
3242         * server-tests/api-commits.js:
3243         (return.addSlaveForReport.subversionCommits.then):
3244         (then):
3245
3246 2017-02-24  Ryosuke Niwa  <rniwa@webkit.org>
3247
3248         REGRESSION(r212853): Comparisons to baseline no longer shows up
3249         https://bugs.webkit.org/show_bug.cgi?id=168863
3250
3251         Reviewed by Joseph Pecoraro.
3252
3253         The bug was caused by ChartStatusView's code not being updated to use TimeSeriesView's.
3254         Updated the code to use TimeSeriesView's methods to fix the bug.
3255
3256         Also made InteractiveTimeSeriesChart's currentPoint to return a (TimeSeriesView, point, isLocked) tuple
3257         to consolidate it with lockedIndicator() to work towards making the baseline data points selectable.
3258
3259         * browser-tests/time-series-chart-tests.js: Updated the test cases to use currentIndicator, and added
3260         test cases for newly added lastPointInTimeRange.
3261
3262         * public/v3/components/chart-pane.js:
3263         (ChartPane.prototype.serializeState): Updated to use currentIndicator.
3264         (ChartPane.prototype._renderFilteringPopover): Ditto.
3265
3266         * public/v3/components/chart-status-view.js:
3267         (ChartStatusView.prototype.updateStatusIfNeeded): Use currentIndicator for an interative time series.
3268         Fixed the non-interactive chart's code path for TimeSeriesView.
3269         (ChartStatusView.prototype._computeChartStatus): Modernized the code.
3270         (ChartStatusView.prototype._findLastPointPriorToTime): Deleted. Replaced by TimeSeriesView's
3271         lastPointInTimeRange.
3272
3273         * public/v3/components/interactive-time-series-chart.js:
3274         (InteractiveTimeSeriesChart.prototype.currentIndicator):
3275         (InteractiveTimeSeriesChart.prototype.moveLockedIndicatorWithNotification):
3276         (InteractiveTimeSeriesChart.prototype._renderChartContent):
3277         (InteractiveTimeSeriesChart):
3278
3279         * public/v3/models/time-series.js:
3280         (TimeSeriesView.prototype.lastPointInTimeRange): Added.
3281         (TimeSeriesView.prototype._reverse): Added. Traverses the view in the reverse order.
3282         * unit-tests/time-series-tests.js:
3283
3284 2017-02-23  Dewei Zhu  <dewei_zhu@apple.com>
3285
3286         Rename 'commit_parent' in 'commits' table to 'commit_previous_commit'.
3287         https://bugs.webkit.org/show_bug.cgi?id=168816
3288
3289         Reviewed by Ryosuke Niwa.
3290
3291         Rename 'commit_parent' to avoid ambiguity in the coming feature.
3292         For exisiting database, run
3293             "ALTER TABLE commits RENAME commit_parent TO commit_previous_commit;"
3294         to update the database.
3295
3296         * init-database.sql:
3297         * public/api/report-commits.php:
3298         * public/include/commit-log-fetcher.php:
3299         * server-tests/api-commits.js:
3300         (then):
3301         * server-tests/api-report-commits-tests.js:
3302         (then):
3303         * tools/sync-commits.py:
3304         (main):
3305         (Repository.fetch_commits_and_submit):
3306         (GitRepository._revision_from_tokens):
3307         * unit-tests/analysis-task-tests.js:
3308         (sampleAnalysisTask):
3309
3310 2017-02-23  Ryosuke Niwa  <rniwa@webkit.org>
3311
3312         New sampling algorithm shows very few points when zoomed out
3313         https://bugs.webkit.org/show_bug.cgi?id=168813
3314
3315         Reviewed by Saam Barati.
3316
3317         When a chart is zoomed out to a large time interval, the new sampling algorithm introduced in r212853 can
3318         hide most of the data points because the difference between the preceding point's time and the succeeding
3319         point's time of most points will be below the threshold we computed.
3320
3321         Instead, rank each data point based on the aforementioned time interval difference, and pick the first M data
3322         points when M data points are to be shown.
3323
3324         This makes the new algorithm behave like our old algorithm while keeping it stable still. Note that this
3325         algorithm still biases data points without a close neighboring point but this seems to work out in practice
3326         because such a point tends to be an important sample anyway, and we don't have a lot of space between
3327         data points since we aim to show about one point per pixel.
3328
3329         * browser-tests/index.html:
3330         (CanvasTest.canvasContainsColor): Extracted from one of the test cases and generalized. Returns true when
3331         the specified region of the canvas contains a specified color (alpha is optional).
3332         * browser-tests/time-series-chart-tests.js: Added a test case for sampling. It checks that sampling happens
3333         and that we always show some data point even when zoomed out to a large time interval.
3334         (createChartWithSampleCluster):
3335
3336         * public/v3/components/interactive-time-series-chart.js:
3337         (InteractiveTimeSeriesChart.prototype._sampleTimeSeries):
3338         * public/v3/components/time-series-chart.js:
3339         (TimeSeriesChart.prototype._ensureSampledTimeSeries): M, the number of data points we pick must be computed
3340         based on the width of data points we're about to draw constrained by the canvas size. e.g. when the canvas
3341         is only half filled, we shouldn't be showing two points per pixel in the filled region.
3342         (TimeSeriesChart.prototype._sampleTimeSeries): Refined the algorithm. First, compute the time difference or
3343         the rank for each N data points. Sort those ranks in descending order (in the order we prefer), and include
3344         all data points above the M-th rank in the sample.
3345         (TimeSeriesChart.prototype.computeTimeGrid): Revert the inadvertent change in r212935.
3346
3347         * public/v3/models/time-series.js:
3348         (TimeSeriesView.prototype.filter): Fixed a bug that the indices passed onto the callback were shifted by the
3349         starting index.
3350         * unit-tests/time-series-tests.js: Added a test case to ensure callbacks are called with correct data points
3351         and indices.
3352
3353 2017-02-23  Ryosuke Niwa  <rniwa@webkit.org>
3354
3355         REGRESSION(r212542): Make TimeSeriesChart.computeTimeGrid stops x-axis grid prematurely
3356         https://bugs.webkit.org/show_bug.cgi?id=168812
3357
3358         Reviewed by Joseph Pecoraro.
3359
3360         Add time iterator of two months, three months, and four months with some tests.
3361
3362         Also for one-month time iterator, round the day of month to 1 or 15 whichever is closer.
3363
3364         * browser-tests/time-series-chart-tests.js: Added more tests.
3365         * public/v3/components/time-series-chart.js:
3366         (TimeSeriesChart._timeIterators.next):
3367         (TimeSeriesChart._timeIterators):
3368
3369 2017-02-22  Ryosuke Niwa  <rniwa@webkit.org>
3370
3371         Add tests for InteractiveTimeSeriesChart and adopt actions
3372         https://bugs.webkit.org/show_bug.cgi?id=168750
3373
3374         Reviewed by Chris Dumez.
3375
3376         Added tests for InteractiveTimeSeriesChart.
3377
3378         Also replaced selection.onchange, selection.onzoom, indicator.onchange, annotations.onclick callbacks
3379         by "selectionChange", "zoom", "indicatorChange", and "annotationClick" actions respectively.
3380
3381         Also fixed various bugs and bad code I encountered while writing these tests.
3382
3383         * browser-tests/index.html:
3384         (waitForComponentsToRender): Delay the call to enqueueToRender until the next run loop because there
3385         might be outstanding promises that just got resolved. e.g. for fetching measurement sets JSONs. Let
3386         all those promises get resolved first. Otherwise, some tests become racy.
3387         (canvasImageData): Extracted from time-series-chart-tests.js.
3388         (canvasRefTest): Ditto.
3389         (CanvasTest): Ditto.
3390         (CanvasTest.fillCanvasBeforeRedrawCheck): Ditto.
3391         (CanvasTest.hasCanvasBeenRedrawn): Ditto.
3392         (CanvasTest.canvasImageData): Ditto.
3393         (CanvasTest.expectCanvasesMatch): Ditto.
3394         (CanvasTest.expectCanvasesMismatch): Ditto.
3395
3396         * browser-tests/time-series-chart-tests.js: Fixed some test cases where dpr multipler was not doing
3397         the right thing anymore in Safari under a high DPI screen. Also added a lot of test cases for interactive
3398         time series chart and one for rendering annotations.
3399         (scripts): Moved.
3400         (posixTime): Added. A helper function for sampleCluster.
3401         (dayInMilliseconds): Ditto.
3402         (sampleCluster): Moved here. Made the same cluster more artifical for an easier testing.
3403         (createChartWithSampleCluster): Moved out of one of the tests.
3404         (respondWithSampleCluster): Ditto.
3405
3406         * public/v3/components/chart-pane-base.js:
3407         (ChartPaneBase.prototype.configure): Adopted new actions in InteractiveTimeSeriesChart.
3408
3409         * public/v3/components/chart-status-view.js:
3410         (ChartStatusView.prototype.updateStatusIfNeeded): Removed a superflous console.log.
3411
3412         * public/v3/components/chart-styles.js:
3413         (ChartStyles.mainChartOptions): Set zoomButton to true. InteractiveTimeSeriesChart used to determine
3414         whether to show the zoom button or not based on the precense of the zoom callback. We made it explicit.
3415
3416         * public/v3/components/interactive-time-series-chart.js:
3417         (InteractiveTimeSeriesChart.prototype.setIndicator): Explicitly call _notifySelectionChanged with false
3418         instead of relying on undefined to be treated as falsey.
3419         (InteractiveTimeSeriesChart.prototype._createCanvas): Use id instead of selector to find elements.
3420         (InteractiveTimeSeriesChart.htmlTemplate):
3421         (InteractiveTimeSeriesChart.cssTemplate):
3422         (InteractiveTimeSeriesChart.prototype._mouseMove): Explicitly call _startOrContinueDragging with false
3423         instead of relying on undefined treated as falsey. Also added the missing call to enqueueToRender found
3424         by new tests. This was working fine on the dashboard due to other components invoking enqueueToRender
3425         but won't work in a standalone instance of InteractiveTimeSeriesChart.
3426         (InteractiveTimeSeriesChart.prototype._mouseLeave): Ditto, adding the missing call to enqueueToRender.
3427         (InteractiveTimeSeriesChart.prototype._click): Removed the assignment to _forceRender when calling
3428         _mouseMove in an early exist, which does set this flag and invokes enqueueToRender, and added the missing
3429         call to enqueueToRender in the other code path.
3430         (InteractiveTimeSeriesChart.prototype._startOrContinueDragging): Replaced annotations.onclick callback
3431         by the newly added "annotationClick" action, and added the missing call to enqueueToRender.
3432         (InteractiveTimeSeriesChart.prototype._endDragging): Use arrow function.
3433         (InteractiveTimeSeriesChart.prototype._notifyIndicatorChanged): Replaced indicator.onchange callback by
3434         the newly added "indicatorChange" action.
3435         (InteractiveTimeSeriesChart.prototype._notifySelectionChanged): Replaced selection.onchange callback by
3436         the newly added "selectionChange" action.
3437         (InteractiveTimeSeriesChart.prototype._renderChartContent): Show the zoom button when options.zoomButton
3438         is set instead of relying on the presence of selection.onzoom especially now that the callback has been
3439         replaced by the "zoom" action.
3440
3441         * public/v3/components/time-series-chart.js:
3442         (TimeSeriesChart.prototype.setAnnotations): Added the missing call to enqueueToRender.
3443
3444         * public/v3/main.js:
3445
3446 2017-02-21  Ryosuke Niwa  <rniwa@webkit.org>
3447
3448         Make sampling algorithm more stable and introduce an abstraction for sampled data
3449         https://bugs.webkit.org/show_bug.cgi?id=168693
3450
3451         Reviewed by Chris Dumez.
3452
3453         Before this patch, TimeSeriesChart's resampling resulted in some points poping up and disappearing as
3454         the width of a chart is changed. e.g. when resizing the browser window. The bug was by caused by
3455         the sample for a given width not always including all points for a smaller width so as the width is
3456         expanded, some point may be dropped.
3457
3458         Fixed this by using a much simpler algorithm of always picking a point when the time interval between
3459         the preceding point and the succeeding point is larger than the minimum space we allow for a given width.
3460
3461         Also introduced a new abstraction around the sample data: TimeSeriesView. A TimeSeriesView provides
3462         a similar API to TimeSeries for a subset of the time series filtered by a time range a custom function.
3463         This paves a way to adding the ability to select baseline, etc... on the chart status view.
3464
3465         TimeSeriesView can be in two modes:
3466         Mode 1. The view represents a contiguous subrange of TimeSeries - In this mode, this._data references
3467                 the underlying TimeSeries's _data directly, and we use _startingIndex to adjust index given to
3468                 find the relative index. Finding the next point or the previous point of a given point is done
3469                 via looking up the point's seriesIndex and doing a simple arithmetic. In general, an index is
3470                 converted to the absolute index in the underlying TimeSeries's _data array.
3471
3472         Mode 2. The view represents a filtered non-contiguous subset of TimeSeries -  In this mode, this._data is
3473                 its own array. Finding the next point or the previous point of a given point requires finding
3474                 a sibling point in the underlying TimeSeries which is in this view. Since this may result in O(n)
3475                 traversal and a hash lookup, we lazily build a map of each point to its position in _data instead.
3476
3477         * public/v3/components/chart-status-view.js:
3478         (ChartStatusView.prototype.updateStatusIfNeeded): Call selectedPoints instead of sampledDataBetween for
3479         clarity. This function now returns a TimeSeriesView instead of a raw array.
3480
3481         * public/v3/components/interactive-time-series-chart.js:
3482         (InteractiveTimeSeriesChart.prototype.currentPoint): Updated now that _sampledTimeSeriesData contains
3483         an array of TimeSeriesView's. Note that diff is either 0, -1, or 1.
3484         (InteractiveTimeSeriesChart.prototype.selectedPoints): Ditto. sampledDataBetween no longer exists since
3485         we can simply call viewTimeRange on TimeSeriesView returned by sampledDataBetween.
3486         (InteractiveTimeSeriesChart.prototype.firstSelectedPoint): Ditto.
3487         (InteractiveTimeSeriesChart.prototype._sampleTimeSeries): Use add since excludedPoints is now a Set.
3488
3489         * public/v3/components/time-series-chart.js:
3490         (TimeSeriesChart.prototype.sampledDataBetween): Deleted.
3491         (TimeSeriesChart.prototype.firstSampledPointBetweenTime): Deleted.
3492         (TimeSeriesChart.prototype._ensureSampledTimeSeries): Modernized the code. Use the the time interval of
3493         the chart divided by the number of allowed points as the time interval used in the new sampling algorithm.
3494         (TimeSeriesChart.prototype._sampleTimeSeries): Rewritten. We also create TimeSeriesView here.
3495         (TimeSeriesChart.prototype._sampleTimeSeries.findMedian): Deleted.
3496         (TimeSeriesChart.prototype._updateCanvasSizeIfClientSizeChanged): Fixed a bug that the canvas size wasn't
3497         set to the correct value on Chrome when a high DPI screen is used.
3498
3499         * public/v3/models/time-series.js:
3500         (TimeSeries.prototype.viewBetweenPoints): Renamed from dataBetweenPoints. Now returns a TimeSeriesView.
3501         (TimeSeriesView): Added. This constructor is to be called by viewBetweenPoints, viewTimeRange, and filter.
3502         (TimeSeriesView.prototype._buildPointIndexMap): Added. Used in mode (2).
3503         (TimeSeriesView.prototype.length): Added.
3504         (TimeSeriesView.prototype.firstPoint): Added.
3505         (TimeSeriesView.prototype.lastPoint): Added.
3506         (TimeSeriesView.prototype.nextPoint): Added. Note index is always a position in this._data. In mode (1),
3507         this is the position of the point in the underlying TimeSeries' _data. In mode (2), this is the position
3508         of the point in this._data which is dictinct from the underlying TimeSeries' _data.
3509         (TimeSeriesView.prototype.previousPoint): Ditto.
3510         (TimeSeriesView.prototype.findPointByIndex): Added. Finds the point using the positional index from the
3511         beginning of this view. findPointByIndex(0) on one view may not be same as findPointByIndex(0) of another.
3512         (TimeSeriesView.prototype.findById): Added. This is O(n).
3513         (TimeSeriesView.prototype.values): Added. Returns the value of each point in this view.
3514         (TimeSeriesView.prototype.filter): Added. Creates a new view with a subset of data points the predicate
3515         function returned true.
3516         (TimeSeriesView.prototype.viewTimeRange): Added. Creates a new view with a subset of data points for the
3517         given time ragne. When the resultant view would include all points of this view, it simply returns itself
3518         as an optimization.
3519         (TimeSeriesView.prototype.firstPointInTimeRange): Added. Returns the first point in the view which lies
3520         within the specified time range.
3521         (TimeSeriesView.prototype.Symbol.iterator): Added. Iterates over each point in the view.
3522
3523         * public/v3/pages/analysis-task-page.js:
3524         (AnalysisTaskChartPane.prototype.selectedPoints): Use selectedPoints in lieu of getting selection and then
3525         calling sampledDataBetween with that range.
3526
3527         * public/v3/pages/summary-page.js:
3528         (SummaryPageConfigurationGroup.set _medianForTimeRange): Modernized.
3529