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