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