<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[215203] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/215203">215203</a></dd>
<dt>Author</dt> <dd>rniwa@webkit.org</dd>
<dt>Date</dt> <dd>2017-04-10 14:43:11 -0700 (Mon, 10 Apr 2017)</dd>
</dl>

<h3>Log Message</h3>
<pre>.:
Elftoolchain ar doesn't support response files
https://bugs.webkit.org/show_bug.cgi?id=170105

Patch by Ting-Wei Lan &lt;lantw44@gmail.com&gt; on 2017-04-08
Reviewed by Michael Catanzaro.

WebKit enables the use of response files when cmake and ninja is used.
However, the default implementation of ar command used in FreeBSD, which
is part of elftoolchain project, doesn't support reading arguments from
response files. To avoid causing undefined reference error on FreeBSD,
we disable the use of response files when elftoolchain ar is detected.

* Source/cmake/OptionsCommon.cmake:

Websites/perf.webkit.org:
Unreviewed, rolling out <a href="http://trac.webkit.org/projects/webkit/changeset/215202">r215202</a>.
https://bugs.webkit.org/show_bug.cgi?id=170694

Committed incorrectly (Requested by rniwa on #webkit).

Reverted changeset:

&quot;Add the UI for scheduling a A/B testing with a custom root&quot;
https://bugs.webkit.org/show_bug.cgi?id=170622
http://trac.webkit.org/changeset/215202

Patch by Commit Queue &lt;commit-queue@webkit.org&gt; on 2017-04-10</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkChangeLog">trunk/ChangeLog</a></li>
<li><a href="#trunkWebsitesperfwebkitorgChangeLog">trunk/Websites/perf.webkit.org/ChangeLog</a></li>
<li><a href="#trunkWebsitesperfwebkitorgReadMemd">trunk/Websites/perf.webkit.org/ReadMe.md</a></li>
<li><a href="#trunkWebsitesperfwebkitorginitdatabasesql">trunk/Websites/perf.webkit.org/init-database.sql</a></li>
<li><a href="#trunkWebsitesperfwebkitorgpublicapibuildrequestsphp">trunk/Websites/perf.webkit.org/public/api/build-requests.php</a></li>
<li><a href="#trunkWebsitesperfwebkitorgpublicapicommitsphp">trunk/Websites/perf.webkit.org/public/api/commits.php</a></li>
<li><a href="#trunkWebsitesperfwebkitorgpublicapitestgroupsphp">trunk/Websites/perf.webkit.org/public/api/test-groups.php</a></li>
<li><a href="#trunkWebsitesperfwebkitorgpublicincludebuildrequestsfetcherphp">trunk/Websites/perf.webkit.org/public/include/build-requests-fetcher.php</a></li>
<li><a href="#trunkWebsitesperfwebkitorgpublicincludecommitlogfetcherphp">trunk/Websites/perf.webkit.org/public/include/commit-log-fetcher.php</a></li>
<li><a href="#trunkWebsitesperfwebkitorgpublicprivilegedapicreatetestgroupphp">trunk/Websites/perf.webkit.org/public/privileged-api/create-test-group.php</a></li>
<li><a href="#trunkWebsitesperfwebkitorgpublicprivilegedapiuploadfilephp">trunk/Websites/perf.webkit.org/public/privileged-api/upload-file.php</a></li>
<li><a href="#trunkWebsitesperfwebkitorgpublicv3indexhtml">trunk/Websites/perf.webkit.org/public/v3/index.html</a></li>
<li><a href="#trunkWebsitesperfwebkitorgpublicv3modelsanalysistaskjs">trunk/Websites/perf.webkit.org/public/v3/models/analysis-task.js</a></li>
<li><a href="#trunkWebsitesperfwebkitorgpublicv3modelsbuildrequestjs">trunk/Websites/perf.webkit.org/public/v3/models/build-request.js</a></li>
<li><a href="#trunkWebsitesperfwebkitorgpublicv3modelscommitlogjs">trunk/Websites/perf.webkit.org/public/v3/models/commit-log.js</a></li>
<li><a href="#trunkWebsitesperfwebkitorgpublicv3modelscommitsetjs">trunk/Websites/perf.webkit.org/public/v3/models/commit-set.js</a></li>
<li><a href="#trunkWebsitesperfwebkitorgpublicv3modelsmanifestjs">trunk/Websites/perf.webkit.org/public/v3/models/manifest.js</a></li>
<li><a href="#trunkWebsitesperfwebkitorgpublicv3modelsmetricjs">trunk/Websites/perf.webkit.org/public/v3/models/metric.js</a></li>
<li><a href="#trunkWebsitesperfwebkitorgpublicv3modelstestgroupjs">trunk/Websites/perf.webkit.org/public/v3/models/test-group.js</a></li>
<li><a href="#trunkWebsitesperfwebkitorgpublicv3modelstriggerablejs">trunk/Websites/perf.webkit.org/public/v3/models/triggerable.js</a></li>
<li><a href="#trunkWebsitesperfwebkitorgpublicv3modelsuploadedfilejs">trunk/Websites/perf.webkit.org/public/v3/models/uploaded-file.js</a></li>
<li><a href="#trunkWebsitesperfwebkitorgpublicv3pagesanalysiscategorypagejs">trunk/Websites/perf.webkit.org/public/v3/pages/analysis-category-page.js</a></li>
<li><a href="#trunkWebsitesperfwebkitorgpublicv3pagesanalysistaskpagejs">trunk/Websites/perf.webkit.org/public/v3/pages/analysis-task-page.js</a></li>
<li><a href="#trunkWebsitesperfwebkitorgpublicv3pageschartpanestatusviewjs">trunk/Websites/perf.webkit.org/public/v3/pages/chart-pane-status-view.js</a></li>
<li><a href="#trunkWebsitesperfwebkitorgpublicv3pageschartpanejs">trunk/Websites/perf.webkit.org/public/v3/pages/chart-pane.js</a></li>
<li><a href="#trunkWebsitesperfwebkitorgpublicv3pagescreateanalysistaskpagejs">trunk/Websites/perf.webkit.org/public/v3/pages/create-analysis-task-page.js</a></li>
<li><a href="#trunkWebsitesperfwebkitorgpublicv3pagespagerouterjs">trunk/Websites/perf.webkit.org/public/v3/pages/page-router.js</a></li>
<li><a href="#trunkWebsitesperfwebkitorgservertestsapibuildrequeststestsjs">trunk/Websites/perf.webkit.org/server-tests/api-build-requests-tests.js</a></li>
<li><a href="#trunkWebsitesperfwebkitorgservertestsapicommitstestsjs">trunk/Websites/perf.webkit.org/server-tests/api-commits-tests.js</a></li>
<li><a href="#trunkWebsitesperfwebkitorgservertestsprivilegedapicreatetestgrouptestsjs">trunk/Websites/perf.webkit.org/server-tests/privileged-api-create-test-group-tests.js</a></li>
<li><a href="#trunkWebsitesperfwebkitorgservertestsresourcesmockdatajs">trunk/Websites/perf.webkit.org/server-tests/resources/mock-data.js</a></li>
<li><a href="#trunkWebsitesperfwebkitorgtoolsjsremotejs">trunk/Websites/perf.webkit.org/tools/js/remote.js</a></li>
<li><a href="#trunkWebsitesperfwebkitorgunittestsanalysistasktestsjs">trunk/Websites/perf.webkit.org/unit-tests/analysis-task-tests.js</a></li>
<li><a href="#trunkWebsitesperfwebkitorgunittestsbuildrequesttestsjs">trunk/Websites/perf.webkit.org/unit-tests/build-request-tests.js</a></li>
<li><a href="#trunkWebsitesperfwebkitorgunittestsbuildbotsyncertestsjs">trunk/Websites/perf.webkit.org/unit-tests/buildbot-syncer-tests.js</a></li>
<li><a href="#trunkWebsitesperfwebkitorgunitteststestgroupstestsjs">trunk/Websites/perf.webkit.org/unit-tests/test-groups-tests.js</a></li>
</ul>

<h3>Removed Paths</h3>
<ul>
<li>trunk/public/</li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/ChangeLog (215202 => 215203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/ChangeLog        2017-04-10 21:38:04 UTC (rev 215202)
+++ trunk/ChangeLog        2017-04-10 21:43:11 UTC (rev 215203)
</span><span class="lines">@@ -1,237 +1,3 @@
</span><del>-2017-04-10  Ryosuke Niwa  &lt;rniwa@webkit.org&gt;
-
-        Add the UI for scheduling a A/B testing with a custom root
-        https://bugs.webkit.org/show_bug.cgi?id=170622
-
-        Reviewed by Anders Carlsson.
-
-        This patch adds the support for creating a new analysis task with a custom darwinup roots. A follow up patch
-        would update the syncing script to schedule such an A/B testing job to a buildbot instance.
-
-
-        * ReadMe.md: Updated instructions for backing up and restoring the database so that it's easier to replace
-        the file path for the backup.
-
-        * init-database.sql: Make task_platform and task_metric optional in each analysis task. Also added a column
-        to store the root file in commit_set_relationships.
-
-        * public/api/build-requests.php:
-        (main): Include the uploaded files.
-
-        * public/api/commits.php:
-        (main): Added the support for querying the latest commits for a given platform. This is used in a new page
-        to create a custom analysis task to autofill the latest revisions for a given platform.
-
-        * public/api/test-groups.php:
-        (main): Include the uploaded files.
-
-        * public/include/build-requests-fetcher.php:
-        (BuildRequestsFetcher::__construct): Added a list of uploaded_files and a map from its id.
-        (BuildRequestsFetcher::uploaded_files): Added.
-        (BuildRequestsFetcher::fetch_commits_for_set_if_needed): Added the support for including custom roots' id in
-        each commit set, and inserting its meta data in the list of uplaoded files.
-
-        * public/include/commit-log-fetcher.php:
-        (CommitLogFetcher::fetch_latest_for_platform): Added. Finds the latest commit for a given platform. Ideally,
-        we should be finding the latest commit for a given platform, but this is very slow so instead find the commit
-        of the latest build for a given platform.
-
-        * public/privileged-api/create-test-group.php:
-        (main): Added the support for creating an analysis task along with a group.
-        (commit_sets_from_revision_sets): Added the support for custom roots. Verify the specified uploaded file exists
-        and include it in commit_set_relationships. Because commits and upload files are stored in a different column
-        in commit_set_relationships, this function now stores the information for each row of commit_set_relationships
-        except the commit set ID, which is unknown until the set is created, instead of a commit ID.
-        (ensure_commit_sets): Made the each entry in a commit set a row instead of a commit ID as done. As this format
-        is only by v2 UI and detect-changes.js, we don't add the support for specifying custom roots here.
-
-        * public/privileged-api/upload-file.php:
-        (main): Fixed a typo. Also added one more error check.
-
-        * public/v3/components/custom-analysis-task-configurator.js: Added. The UI for selecting a test, a platform,
-        and a set of revisions, as well as custom roots for a custom A/B testing job. The first set of revision with
-        custom roots is referred as &quot;baseline&quot;, and the second configuration is referred as &quot;comparison&quot; in this class.
-        (CustomAnalysisTaskConfigurator):
-        (CustomAnalysisTaskConfigurator.prototype.tests): Added.
-        (CustomAnalysisTaskConfigurator.prototype.platform): Added.
-        (CustomAnalysisTaskConfigurator.prototype.commitSets): Added. Returns a pair of baseline and comparsion if both
-        have been configured by the user.
-        (CustomAnalysisTaskConfigurator.prototype.didConstructShadowTree): Added.
-        (CustomAnalysisTaskConfigurator.prototype._configureComparison): Added. Called when the user is to configu the
-        &quot;comparison&quot; configuration.
-        (CustomAnalysisTaskConfigurator.prototype.render): Added.
-        (CustomAnalysisTaskConfigurator.prototype._renderTriggerableTests): Added. Renders the list of top-level tests
-        that can be scheduled by a triggerable.
-        (CustomAnalysisTaskConfigurator.prototype._renderTriggerablePlatforms): Added. Renders the list of platforms
-        that can be schedule with the currently selected list of tests by a triggerable. Note that the current UI only
-        lets the user select a single test but the intent is to allow multiple tests to be selected in the near future.
-        (CustomAnalysisTaskConfigurator.prototype._buildCheckboxList): Added. Creates a list of radio boxes to select
-        an item with a callback for each. It automatically sets &quot;selected&quot; class on the selected item. It's used to
-        render both the list of tests and platforms.
-        (CustomAnalysisTaskConfigurator.prototype._updateTriggerable): Added. Finds the triggerable for a given list of
-        tests and platforms. Returns an error when some tests belong to another triggearalbe.
-        (CustomAnalysisTaskConfigurator.prototype._updateRepositoryGroups): Added. Finds a repository group to use when
-        the current triggerable has changed. We try to use the repository group of the same name if there is any, and
-        defaults to the first repository group if there is none. This allows the set of repositories to be specified to
-        more or less persist across different triggerables. For example, if iOS platforms and Mac platforms use two
-        distinct triggerables , and both triggerables have two repository groups: one that only specify the OS and the
-        other that specifies both teh OS and WebKit revision, then this code allows the choice the user had made to
-        specify either just the OS or the OS and WebKit will be preserved when the user switches from an iOS platform
-        to a Mac platform.
-        (CustomAnalysisTaskConfigurator.prototype._updateCommitSetMap): Added. Create a commit set map, the format that
-        TestGroup.createWithTask accepts given &quot;baseline&quot; and &quot;comparison&quot; commit sets. Pretend &quot;comparison&quot; is not set
-        if two sets are identical since it makes no sense to schedule an A/B testing job when A and B are identical.
-        (CustomAnalysisTaskConfigurator.prototype._computeCommitSet): Added. Creates a commit set using the revisions
-        and the csutom roots the user had specified.
-        (CustomAnalysisTaskConfigurator.prototype._renderRepositoryPanes): Added. Renders the pane to specify revisions
-        and custom roots for &quot;baseline&quot; and &quot;comparison&quot;.
-        (CustomAnalysisTaskConfigurator.prototype._renderBaselineRevisionTable): Added.
-        (CustomAnalysisTaskConfigurator.prototype._renderComparisonRevisionTable): Added.
-        (CustomAnalysisTaskConfigurator.prototype._optionalRepositoryList): Added.
-        (CustomAnalysisTaskConfigurator.prototype._buildRevisionTable): Added. Creates a table for specifying revisions
-        and custom roots along with a list of repository groups to pick. The set of repositories and custom roots are
-        shown at the all if all repository groups require them. Otherwise, they are grouped at the bottom as optional.
-        (CustomAnalysisTaskConfigurator.prototype._buildRepositoryGroupList): Added.
-        (CustomAnalysisTaskConfigurator.prototype._selectRepositoryGroup): Added.
-        (CustomAnalysisTaskConfigurator.prototype._buildRevisionInput): Added. Creates an input element to specify
-        a revision for a given repository. Autofills it with the latest commit for the currently selected platform if
-        the user had not modified the field by the time the revisions are fetched.
-        (CustomAnalysisTaskConfigurator.htmlTemplate): Added.
-        (CustomAnalysisTaskConfigurator.cssTemplate): Added.
-
-        * public/v3/components/instant-file-uploader.js: Added. A form to upload a custom darwinup root in &quot;baseline&quot;
-        or &quot;comparison&quot; configurations of CustomAnalysisTaskConfigurator. It's &quot;instant&quot; because it auto-detects when a
-        file to be uploaded had already been uploaded elsewhere by checking its SHA-256 hash.
-        (InstantFileUploader):
-        (InstantFileUploader.prototype.hasFileToUpload): Added.
-        (InstantFileUploader.prototype.uploadedFiles): Added.
-        (InstantFileUploader.prototype.addUploadedFile): Added. It's called on the uploader for &quot;comparison&quot;
-        configuration when the uploader for &quot;baseline&quot; configuration dipsatches &quot;uploadedFile&quot; action to automatically
-        mirror the newly uploaded custom root to &quot;comparision&quot; configuration.
-        (InstantFileUploader.prototype.didConstructShadowTree): Added.
-        (InstantFileUploader.prototype.render): Added.
-        (InstantFileUploader.prototype._renderUploadedFiles): Added. Renders the list of the uploaded files.
-        (InstantFileUploader.prototype._renderPreuploadFiles): Added. Renders the list of the files to be uploaded with
-        a progress bar.
-        (InstantFileUploader.prototype._updateUploadStatus): Added. Updates the progress bar for uploading the file.
-        (InstantFileUploader.prototype._formatUploadError): Added.
-        (InstantFileUploader.prototype._didFileInputChange): Added. Called when the user picks a file to uploaded on
-        the input element. Fetch the meta data for the uploaded file with the same SHA-256 hash if there is any, and
-        start uploading the file if there isn't one.
-        (InstantFileUploader.prototype._removeUploadedFile): Added.
-        (InstantFileUploader.prototype._didUploadFile): Added. Move a file from the list of files to be uploaded to
-        the list of uploaded files.
-        (InstantFileUploader.htmlTemplate): Added.
-        (InstantFileUploader.cssTemplate): Added.
-
-        * public/v3/index.html:
-
-        * public/v3/models/analysis-task.js:
-        (AnalysisTask): Made platform and metric optional as it is now.
-        (AnalysisTask.findByPlatformAndMetric): Skip analysis tasks without a platform or a metric.
-        (AnalysisTask.prototype.isCustom): Added. Returns true for a custom analysis task.
-        (AnalysisTask.fetchRelatedTasks): Skip custom analysis tasks.
-        (AnalysisTask._constructAnalysisTasksFromRawData): Construct analysis tasks even if they were missing a metric
-        or a platform instead of silently skipping them.
-
-        * public/v3/models/build-request.js:
-        (BuildRequest.constructBuildRequestsFromData): Construct uploaded file objects returned by /api/build-requests.
-
-        * public/v3/models/commit-log.js:
-        (CommitLog.fetchLatestCommitForPlatform): Added.
-
-        * public/v3/models/commit-set.js:
-        (CommitSet): Added this._customRoots.
-        (CommitSet.prototype.customRoots): Returns this._customRoots.
-        (CommitSet.prototype.equals): Returns false when the set of custom roots are not equal.
-        (CommitSet.areCustomRootsEqual): Added.
-        (CustomCommitSet):
-        (CustomCommitSet.prototype.equals): Added.
-        (CustomCommitSet.prototype.customRoots): Added.
-        (CustomCommitSet.prototype.addCustomRoot): Added.
-
-        * public/v3/models/manifest.js:
-        (Manifest._didFetchManifest): Store fileUploadSizeLimit in the manifest as UploadedFile.fileUploadSizeLimit.
-        This allows a file size check in the client size instead of uploading it to the server and receiving an error.
-
-        * public/v3/models/metric.js:
-        (Metric.formatTime): Moved from ChartPaneStatusView to be also used by InstantFileUploader._renderUploadedFiles.
-
-        * public/v3/models/test-group.js:
-        (TestGroup.prototype.createWithTask): Added.
-        (TestGroup.prototype.createAndRefetchTestGroups):
-        (TestGroup.prototype._revisionSetsFromCommitSets): Added. Extracted from createAndRefetchTestGroups.
-        (TestGroup.prototype._fetchTestGroupsForTask): Added. Extracted from createAndRefetchTestGroups.
-
-        * public/v3/models/triggerable.js:
-        (Triggerable.triggerablePlatformsForTests): Added.
-        (Triggerable.sortByNamePreferringSmallerRepositories): Added.
-
-        * public/v3/models/uploaded-file.js:
-        (UploadedFile.prototype.createdAt): Added.
-        (UploadedFile.prototype.filename): Added.
-        (UploadedFile.prototype.author): Added.
-        (UploadedFile.prototype.size): Added.
-        (UploadedFile.uploadFile): Added a client-side check for the file size using UploadedFile.fileUploadSizeLimit.
-        (UploadedFile.fetchUnloadedFileWithIdenticalHash): Ditto. Also fixed a bug that 404 was resulting in a rejected
-        promise instead of a resolved promise with null.
-
-        * public/v3/pages/analysis-category-page.js:
-        (AnalysisCategoryPage.prototype._reconstructTaskList): Modernized the code. Added the support for platform and
-        metric being null for some analysis tasks.
-
-        * public/v3/pages/analysis-task-page.js:
-        (AnalysisTaskPage.prototype._didFetchTask): Don't fetch the measurement set or create a chart for custom tasks.
-        (AnalysisTaskPage.prototype.render): Don't display the charts or the stacking table for custom tasks.
-        (AnalysisTaskPage.prototype._renderTaskNameAndStatus): Don't try to show the full test name for custom tasks
-        since it's not associated with exactly one pair.
-
-        * public/v3/pages/chart-pane-status-view.js:
-        (ChartPaneStatusView.prototype._renderBuildRevisionTable):
-        (ChartPaneStatusView.prototype._formatTime): Moved to Metric.formatTime.
-
-        * public/v3/pages/chart-pane.js:
-        (ChartPane.prototype._analyzeRange): Set inProgress to true to hide CustomAnalysisTaskConfigurator in
-        CreateAnalysisTaskPage when creating a non-custom analysis task for a specific range.
-
-        * public/v3/pages/create-analysis-task-page.js:
-        (CreateAnalysisTaskPage): This page now shows CustomAnalysisTaskConfigurator by default, and lets a user create
-        a custom analysis task by picking a test, a platform, and a set of revisions and custom darwinup roots.
-        (CreateAnalysisTaskPage.prototype.updateFromSerializedState): Show a message when inProgress is set. This is
-        the old behavior of this page.
-        (CreateAnalysisTaskPage.prototype.didConstructShadowTree): Added.
-        (CreateAnalysisTaskPage.prototype._createAnalysisTaskWithGroup): Added.
-        (CreateAnalysisTaskPage.prototype.render):
-        (CreateAnalysisTaskPage.prototype._renderMessage): Added. Hides CustomAnalysisTaskConfigurator and the select
-        element to specify the numebr of iterations when a message is set.
-        (CreateAnalysisTaskPage.htmlTemplate):
-        (CreateAnalysisTaskPage.cssTemplate):
-
-        * public/v3/pages/page-router.js:
-        (PageRouter.prototype.route): Always enqueue the page to re-render when the route has changed.
-
-        * server-tests/api-build-requests-tests.js: Updated test cases now that the response contains a list of
-        uploaded files associated with build requests.
-        *server-tests/api-commits-tests.js: Added a test case for /api/commits/&lt;repository-name&gt;/latest?platform=X.
-        * server-tests/privileged-api-create-test-group-tests.js: Added test cases for creating a custom analysis task
-        and a test group with custom roots. 
-        * server-tests/resources/mock-data.js:
-        (MockData.addMockData): Updated the mock data to satisfy new constraint on analysis-tasks table. Also inserted
-        more commits, builds, and build_commits rows for testing /api/commits/&lt;repository-name&gt;/latest?platform=X.
-
-        * tools/js/remote.js: Include global.FormData from form-data.js.
-
-        * unit-tests/analysis-task-tests.js: Added a test for calling findByPlatformAndMetric when there is a custom
-        analysis task.
-        (sampleAnalysisTask): Removed the category since /api/analysis-tasks/ no longer generate this property.
-        (sampleCustomAnalysisTask): Added.
-        * unit-tests/build-request-tests.js:
-        (sampleBuildRequestData): Updated the mock response. Added a test case for fetcing custom roots.
-        * unit-tests/buildbot-syncer-tests.js:
-        (createSampleBuildRequest): Ditto.
-        * unit-tests/test-groups-tests.js:
-        (sampleTestGroup): Ditto.
-
</del><span class="cx"> 2017-04-08  Ting-Wei Lan  &lt;lantw44@gmail.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Elftoolchain ar doesn't support response files
</span></span></pre></div>
<a id="trunkWebsitesperfwebkitorgChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Websites/perf.webkit.org/ChangeLog (215202 => 215203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/perf.webkit.org/ChangeLog        2017-04-10 21:38:04 UTC (rev 215202)
+++ trunk/Websites/perf.webkit.org/ChangeLog        2017-04-10 21:43:11 UTC (rev 215203)
</span><span class="lines">@@ -1,3 +1,16 @@
</span><ins>+2017-04-10  Commit Queue  &lt;commit-queue@webkit.org&gt;
+
+        Unreviewed, rolling out r215202.
+        https://bugs.webkit.org/show_bug.cgi?id=170694
+
+        Committed incorrectly (Requested by rniwa on #webkit).
+
+        Reverted changeset:
+
+        &quot;Add the UI for scheduling a A/B testing with a custom root&quot;
+        https://bugs.webkit.org/show_bug.cgi?id=170622
+        http://trac.webkit.org/changeset/215202
+
</ins><span class="cx"> 2017-04-10  Ryosuke Niwa  &lt;rniwa@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         Add the UI for scheduling a A/B testing with a custom root
</span></span></pre></div>
<a id="trunkWebsitesperfwebkitorgReadMemd"></a>
<div class="modfile"><h4>Modified: trunk/Websites/perf.webkit.org/ReadMe.md (215202 => 215203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/perf.webkit.org/ReadMe.md        2017-04-10 21:38:04 UTC (rev 215202)
+++ trunk/Websites/perf.webkit.org/ReadMe.md        2017-04-10 21:43:11 UTC (rev 215203)
</span><span class="lines">@@ -71,11 +71,11 @@
</span><span class="cx"> 
</span><span class="cx"> Use `pg_dump` and `pg_restore` to backup and restore the database. If you're replicating the production database for development purposes, you may consider excluding `run_iterations` table, which takes up 2/3 of the storage space, to reduce the size of the database for your local copy. Adjust the number of concurrent processes to use by `--jobs` and adjust the compression level by `--compress` (0 is no compression, 9 is most compressed).
</span><span class="cx"> 
</span><del>-- Making the fullbackup of the database: `/Applications/Server.app/Contents/ServerRoot/usr/bin/pg_dump -h localhost webkit-perf-db --format=directory --jobs=4 --no-owner --compress=7 --file=&lt;path to backup directory&gt;`
</del><ins>+- Making the fullbackup of the database: `/Applications/Server.app/Contents/ServerRoot/usr/bin/pg_dump -h localhost webkit-perf-db --format=directory --file=&lt;path to backup directory&gt; --jobs=4 --no-owner --compress=7`
</ins><span class="cx"> 
</span><del>-- Making an abridged backup without `run_iterations` table: `/Applications/Server.app/Contents/ServerRoot/usr/bin/pg_dump -h localhost webkit-perf-db --format=directory --jobs=4 --no-owner --compress=7 --exclude-table=run_iterations --file=&lt;path to backup directory&gt;`
</del><ins>+- Making an abridged backup without `run_iterations` table: `/Applications/Server.app/Contents/ServerRoot/usr/bin/pg_dump -h localhost webkit-perf-db --format=directory --file=&lt;path to backup directory&gt; --jobs=4 --no-owner --compress=7 --exclude-table=run_iterations`
</ins><span class="cx"> 
</span><del>-- Restoring the database: `/Applications/Server.app/Contents/ServerRoot/usr/bin/pg_restore --format=directory --jobs=4 --no-owner --host localhost --username=webkit-perf-db-user --dbname=webkit-perf-db &lt;path to backup directory&gt;`
</del><ins>+- Restoring the database: `/Applications/Server.app/Contents/ServerRoot/usr/bin/pg_restore --format=directory --jobs=4 --no-owner --host localhost --username=webkit-perf-db-user &lt;path to backup directory&gt; --dbname=webkit-perf-db`
</ins><span class="cx">     
</span><span class="cx"> ## Configuring Apache
</span><span class="cx"> 
</span><span class="lines">@@ -88,7 +88,7 @@
</span><span class="cx"> 
</span><span class="cx"> ### Instructions if you're not using Server.app
</span><span class="cx"> 
</span><del>- - Edit `/private/etc/apache2/httpd.conf`
</del><ins>+ - Edit /private/etc/apache2/httpd.conf
</ins><span class="cx"> 
</span><span class="cx">      1. Change DocumentRoot to `/Volumes/Data/perf.webkit.org/public/`
</span><span class="cx">      2. Uncomment `LoadModule php5_module libexec/apache2/libphp5.so`
</span></span></pre></div>
<a id="trunkWebsitesperfwebkitorginitdatabasesql"></a>
<div class="modfile"><h4>Modified: trunk/Websites/perf.webkit.org/init-database.sql (215202 => 215203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/perf.webkit.org/init-database.sql        2017-04-10 21:38:04 UTC (rev 215202)
+++ trunk/Websites/perf.webkit.org/init-database.sql        2017-04-10 21:43:11 UTC (rev 215203)
</span><span class="lines">@@ -204,8 +204,8 @@
</span><span class="cx">     task_segmentation integer REFERENCES analysis_strategies,
</span><span class="cx">     task_test_range integer REFERENCES analysis_strategies,
</span><span class="cx">     task_created_at timestamp NOT NULL DEFAULT (CURRENT_TIMESTAMP AT TIME ZONE 'UTC'),
</span><del>-    task_platform integer REFERENCES platforms,
-    task_metric integer REFERENCES test_metrics,
</del><ins>+    task_platform integer REFERENCES platforms NOT NULL,
+    task_metric integer REFERENCES test_metrics NOT NULL,
</ins><span class="cx">     task_start_run integer REFERENCES test_runs,
</span><span class="cx">     task_start_run_time timestamp,
</span><span class="cx">     task_end_run integer REFERENCES test_runs,
</span><span class="lines">@@ -213,13 +213,8 @@
</span><span class="cx">     task_result analysis_task_result_type,
</span><span class="cx">     task_needed boolean,
</span><span class="cx">     CONSTRAINT analysis_task_should_be_unique_for_range UNIQUE(task_start_run, task_end_run),
</span><del>-    CONSTRAINT analysis_task_must_be_associated_with_run_or_be_custom
-        CHECK ((task_start_run IS NULL AND task_start_run_time IS NULL
-                AND task_end_run IS NULL AND task_end_run_time IS NULL
-                AND task_platform IS NULL AND task_metric IS NULL)
-            OR (task_start_run IS NOT NULL AND task_start_run_time IS NOT NULL
-                AND task_end_run IS NOT NULL AND task_end_run_time IS NOT NULL
-                AND task_platform IS NOT NULL AND task_metric IS NOT NULL)));
</del><ins>+    CONSTRAINT analysis_task_should_not_be_associated_with_single_run
+        CHECK ((task_start_run IS NULL AND task_end_run IS NULL) OR (task_start_run IS NOT NULL AND task_end_run IS NOT NULL)));
</ins><span class="cx"> 
</span><span class="cx"> CREATE TABLE task_commits (
</span><span class="cx">     taskcommit_task integer NOT NULL REFERENCES analysis_tasks ON DELETE CASCADE,
</span><span class="lines">@@ -285,9 +280,7 @@
</span><span class="cx"> 
</span><span class="cx"> CREATE TABLE commit_set_relationships (
</span><span class="cx">     commitset_set integer REFERENCES commit_sets NOT NULL,
</span><del>-    commitset_commit integer REFERENCES commits,
-    commitset_root_file integer REFERENCES uploaded_files,
-    CONSTRAINT commitset_must_have_commit_or_root CHECK (commitset_commit IS NOT NULL OR commitset_root_file IS NOT NULL));
</del><ins>+    commitset_commit integer REFERENCES commits NOT NULL);
</ins><span class="cx"> 
</span><span class="cx"> CREATE TYPE build_request_status_type as ENUM ('pending', 'scheduled', 'running', 'failed', 'completed', 'canceled');
</span><span class="cx"> CREATE TABLE build_requests (
</span></span></pre></div>
<a id="trunkWebsitesperfwebkitorgpublicapibuildrequestsphp"></a>
<div class="modfile"><h4>Modified: trunk/Websites/perf.webkit.org/public/api/build-requests.php (215202 => 215203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/perf.webkit.org/public/api/build-requests.php        2017-04-10 21:38:04 UTC (rev 215202)
+++ trunk/Websites/perf.webkit.org/public/api/build-requests.php        2017-04-10 21:43:11 UTC (rev 215203)
</span><span class="lines">@@ -35,7 +35,6 @@
</span><span class="cx">         'buildRequests' =&gt; $resolve_id ? $requests_fetcher-&gt;results_with_resolved_ids() : $requests_fetcher-&gt;results(),
</span><span class="cx">         'commitSets' =&gt; $requests_fetcher-&gt;commit_sets(),
</span><span class="cx">         'commits' =&gt; $requests_fetcher-&gt;commits(),
</span><del>-        'uploadedFiles' =&gt; $requests_fetcher-&gt;uploaded_files(),
</del><span class="cx">     ));
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkWebsitesperfwebkitorgpublicapicommitsphp"></a>
<div class="modfile"><h4>Modified: trunk/Websites/perf.webkit.org/public/api/commits.php (215202 => 215203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/perf.webkit.org/public/api/commits.php        2017-04-10 21:38:04 UTC (rev 215202)
+++ trunk/Websites/perf.webkit.org/public/api/commits.php        2017-04-10 21:43:11 UTC (rev 215203)
</span><span class="lines">@@ -30,14 +30,7 @@
</span><span class="cx">     } else if ($filter == 'oldest') {
</span><span class="cx">         $commits = $fetcher-&gt;fetch_oldest($repository_id);
</span><span class="cx">     } else if ($filter == 'latest') {
</span><del>-        $platform_id = array_get($_GET, 'platform');
-        if ($platform_id) {
-            if (!is_numeric($platform_id))
-                exit_with_error('InvalidPlatform', array('platform' =&gt; $platform_id));
-            $platform_id = intval($platform_id);
-            $commits = $fetcher-&gt;fetch_latest_for_platform($repository_id, $platform_id);
-        } else
-            $commits = $fetcher-&gt;fetch_latest($repository_id);
</del><ins>+        $commits = $fetcher-&gt;fetch_latest($repository_id);
</ins><span class="cx">     } else if ($filter == 'last-reported') {
</span><span class="cx">         $from = array_get($_GET, 'from');
</span><span class="cx">         $to = array_get($_GET, 'to');
</span></span></pre></div>
<a id="trunkWebsitesperfwebkitorgpublicapitestgroupsphp"></a>
<div class="modfile"><h4>Modified: trunk/Websites/perf.webkit.org/public/api/test-groups.php (215202 => 215203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/perf.webkit.org/public/api/test-groups.php        2017-04-10 21:38:04 UTC (rev 215202)
+++ trunk/Websites/perf.webkit.org/public/api/test-groups.php        2017-04-10 21:43:11 UTC (rev 215203)
</span><span class="lines">@@ -55,8 +55,7 @@
</span><span class="cx">     exit_with_success(array('testGroups' =&gt; $test_groups,
</span><span class="cx">         'buildRequests' =&gt; $build_requests,
</span><span class="cx">         'commitSets' =&gt; $build_requests_fetcher-&gt;commit_sets(),
</span><del>-        'commits' =&gt; $build_requests_fetcher-&gt;commits(),
-        'uploadedFiles' =&gt; $build_requests_fetcher-&gt;uploaded_files()));
</del><ins>+        'commits' =&gt; $build_requests_fetcher-&gt;commits()));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> function format_test_group($group_row) {
</span></span></pre></div>
<a id="trunkWebsitesperfwebkitorgpublicincludebuildrequestsfetcherphp"></a>
<div class="modfile"><h4>Modified: trunk/Websites/perf.webkit.org/public/include/build-requests-fetcher.php (215202 => 215203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/perf.webkit.org/public/include/build-requests-fetcher.php        2017-04-10 21:38:04 UTC (rev 215202)
+++ trunk/Websites/perf.webkit.org/public/include/build-requests-fetcher.php        2017-04-10 21:43:11 UTC (rev 215203)
</span><span class="lines">@@ -1,7 +1,6 @@
</span><span class="cx"> &lt;?php
</span><span class="cx"> 
</span><span class="cx"> require_once('test-path-resolver.php');
</span><del>-require_once('uploaded-file-helpers.php');
</del><span class="cx"> 
</span><span class="cx"> class BuildRequestsFetcher {
</span><span class="cx">     function __construct($db) {
</span><span class="lines">@@ -11,8 +10,6 @@
</span><span class="cx">         $this-&gt;commits_by_id = array();
</span><span class="cx">         $this-&gt;commits = array();
</span><span class="cx">         $this-&gt;commit_sets_by_id = array();
</span><del>-        $this-&gt;uploaded_files = array();
-        $this-&gt;uploaded_files_by_id = array();
</del><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     function fetch_for_task($task_id) {
</span><span class="lines">@@ -86,37 +83,27 @@
</span><span class="cx">         return $requests;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    function commit_sets() { return $this-&gt;commit_sets; }
-    function commits() { return $this-&gt;commits; }
-    function uploaded_files() { return $this-&gt;uploaded_files; }
</del><ins>+    function commit_sets() {
+        return $this-&gt;commit_sets;
+    }
</ins><span class="cx"> 
</span><ins>+    function commits() {
+        return $this-&gt;commits;
+    }
+
</ins><span class="cx">     private function fetch_commits_for_set_if_needed($commit_set_id, $resolve_ids) {
</span><span class="cx">         if (array_key_exists($commit_set_id, $this-&gt;commit_sets_by_id))
</span><span class="cx">             return;
</span><span class="cx"> 
</span><span class="cx">         $commit_rows = $this-&gt;db-&gt;query_and_fetch_all('SELECT *
</span><del>-            FROM commit_set_relationships LEFT OUTER JOIN  commits ON commitset_commit = commit_id
-                LEFT OUTER JOIN repositories ON repository_id = commit_repository
-                WHERE commitset_set = $1', array($commit_set_id));
</del><ins>+            FROM commit_set_relationships, commits LEFT OUTER JOIN repositories ON commit_repository = repository_id
+            WHERE commitset_commit = commit_id AND commitset_set = $1', array($commit_set_id));
</ins><span class="cx"> 
</span><span class="cx">         $commit_ids = array();
</span><del>-        $custom_roots = array();
-
</del><span class="cx">         foreach ($commit_rows as $row) {
</span><span class="cx">             $repository_id = $resolve_ids ? $row['repository_name'] : $row['repository_id'];
</span><span class="cx">             $revision = $row['commit_revision'];
</span><span class="cx">             $commit_time = $row['commit_time'];
</span><del>-
-            $root_file_id = $row['commitset_root_file'];
-            if ($root_file_id) {
-                if (!array_key_exists($root_file_id, $this-&gt;uploaded_files_by_id)) {
-                    $uploaded_file_row = $this-&gt;db-&gt;select_first_row('uploaded_files', 'file', array('id' =&gt; $root_file_id));
-                    array_push($this-&gt;uploaded_files, format_uploaded_file($uploaded_file_row));
-                }
-                array_push($custom_roots, $root_file_id);
-                continue;
-            }
-
</del><span class="cx">             array_push($commit_ids, $row['commit_id']);
</span><span class="cx"> 
</span><span class="cx">             $commit_id = $row['commit_id'];
</span><span class="lines">@@ -134,7 +121,7 @@
</span><span class="cx"> 
</span><span class="cx">         $this-&gt;commit_sets_by_id[$commit_set_id] = TRUE;
</span><span class="cx"> 
</span><del>-        array_push($this-&gt;commit_sets, array('id' =&gt; $commit_set_id, 'commits' =&gt; $commit_ids, 'customRoots' =&gt; $custom_roots));
</del><ins>+        array_push($this-&gt;commit_sets, array('id' =&gt; $commit_set_id, 'commits' =&gt; $commit_ids));
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkWebsitesperfwebkitorgpublicincludecommitlogfetcherphp"></a>
<div class="modfile"><h4>Modified: trunk/Websites/perf.webkit.org/public/include/commit-log-fetcher.php (215202 => 215203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/perf.webkit.org/public/include/commit-log-fetcher.php        2017-04-10 21:38:04 UTC (rev 215202)
+++ trunk/Websites/perf.webkit.org/public/include/commit-log-fetcher.php        2017-04-10 21:43:11 UTC (rev 215203)
</span><span class="lines">@@ -118,28 +118,6 @@
</span><span class="cx">         return $this-&gt;format_single_commit($this-&gt;db-&gt;select_last_row('commits', 'commit', array('repository' =&gt; $repository_id), array('time', 'order')));
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    function fetch_latest_for_platform($repository_id, $platform_id)
-    {
-        $query_result = $this-&gt;db-&gt;query_and_fetch_all(&quot;SELECT commits.* FROM test_runs, builds, build_commits, commits
-            WHERE run_build = build_id AND NOT EXISTS (SELECT * FROM build_requests WHERE request_build = build_id)
-                AND run_config IN (SELECT config_id FROM test_configurations
-                    WHERE config_type = 'current' AND config_platform = $2 AND config_metric
-                        IN (SELECT metric_id FROM test_metrics, tests WHERE metric_test = test_id and test_parent IS NULL))
-                AND run_build = build_id AND commit_build = build_id AND build_commit = commit_id AND commit_repository = $1
-            ORDER BY build_time DESC LIMIT 1;&quot;, array($repository_id, $platform_id));
-        /* This query is approximation. It finds the commit of the last build instead of the last commit.
-        We would ideally run the following query but it's much slower ~70s compared to 300ms.
-            SELECT commits.*, commit_build, run_id
-                FROM commits, build_commits, test_runs
-                WHERE commit_repository = 9 AND commit_id = build_commit AND commit_build = run_build
-                AND run_config IN (SELECT config_id FROM test_configurations WHERE config_platform = 38 AND config_type = 'current')
-                AND NOT EXISTS (SELECT * FROM build_requests WHERE request_build = commit_build)
-                ORDER BY commit_time DESC, commit_order DESC LIMIT 1; */
-        if (!$query_result)
-            return array();
-        return $this-&gt;format_single_commit($query_result[0]);
-    }
-
</del><span class="cx">     function fetch_last_reported($repository_id) {
</span><span class="cx">         return $this-&gt;format_single_commit($this-&gt;db-&gt;select_last_row('commits', 'commit', array('repository' =&gt; $repository_id, 'reported' =&gt; true), array('time', 'order')));
</span><span class="cx">     }
</span></span></pre></div>
<a id="trunkWebsitesperfwebkitorgpublicprivilegedapicreatetestgroupphp"></a>
<div class="modfile"><h4>Modified: trunk/Websites/perf.webkit.org/public/privileged-api/create-test-group.php (215202 => 215203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/perf.webkit.org/public/privileged-api/create-test-group.php        2017-04-10 21:38:04 UTC (rev 215202)
+++ trunk/Websites/perf.webkit.org/public/privileged-api/create-test-group.php        2017-04-10 21:43:11 UTC (rev 215203)
</span><span class="lines">@@ -11,28 +11,16 @@
</span><span class="cx"> 
</span><span class="cx">     $arguments = validate_arguments($data, array(
</span><span class="cx">         'name' =&gt; '/.+/',
</span><del>-        'task' =&gt; 'int?',
</del><ins>+        'task' =&gt; 'int',
</ins><span class="cx">         'repetitionCount' =&gt; 'int?',
</span><span class="cx">     ));
</span><span class="cx">     $name = $arguments['name'];
</span><del>-    $task_id = array_get($arguments, 'task');
-    $task_name = array_get($data, 'taskName');
</del><ins>+    $task_id = $arguments['task'];
</ins><span class="cx">     $repetition_count = $arguments['repetitionCount'];
</span><del>-    $platform_id = array_get($data, 'platform');
-    $test_id = array_get($data, 'test');
</del><span class="cx">     $revision_set_list = array_get($data, 'revisionSets');
</span><span class="cx">     $commit_sets_info = array_get($data, 'commitSets');
</span><span class="cx"> 
</span><del>-    if (!$task_id == !$task_name)
-        exit_with_error('InvalidTask');
-
-    if ($task_id)
-        require_format('Task', $task_id, '/^\d+$/');
-    if ($task_name || $platform_id || $test_id) {
-        require_format('Platform', $platform_id, '/^\d+$/');
-        require_format('Test', $test_id, '/^\d+$/');
-    }
-
</del><ins>+    require_format('Task', $task_id, '/^\d+$/');
</ins><span class="cx">     if (!$revision_set_list &amp;&amp; !$commit_sets_info)
</span><span class="cx">         exit_with_error('InvalidCommitSets');
</span><span class="cx"> 
</span><span class="lines">@@ -41,65 +29,39 @@
</span><span class="cx">     else if ($repetition_count &lt; 1)
</span><span class="cx">         exit_with_error('InvalidRepetitionCount', array('repetitionCount' =&gt; $repetition_count));
</span><span class="cx"> 
</span><del>-    $triggerable_id = NULL;
-    if ($task_id) {
-        $task = $db-&gt;select_first_row('analysis_tasks', 'task', array('id' =&gt; $task_id));
-        if (!$task)
-            exit_with_error('InvalidTask', array('task' =&gt; $task_id));
-        $triggerable = find_triggerable_for_task($db, $task_id);
-        if ($triggerable) {
-            $triggerable_id = $triggerable['id'];
-            if (!$platform_id &amp;&amp; !$test_id) {
-                $platform_id = $triggerable['platform'];
-                $test_id = $triggerable['test'];
-            } else {
-                if ($triggerable['platform'] &amp;&amp; $platform_id != $triggerable['platform'])
-                    exit_with_error('InconsistentPlatform', array('groupPlatform' =&gt; $platform_id, 'taskPlatform' =&gt; $triggerable['platform']));
-                if ($triggerable['test'] &amp;&amp; $test_id != $triggerable['test'])
-                    exit_with_error('InconsistentTest', array('groupTest' =&gt; $test_id, 'taskTest' =&gt; $triggerable['test']));
-            }
-        }
-    } else if ($platform_id &amp;&amp; $test_id) {
-        $triggerable_configuration = $db-&gt;select_first_row('triggerable_configurations', 'trigconfig',
-            array('test' =&gt; $test_id, 'platform' =&gt; $platform_id));
-        if ($triggerable_configuration)
-            $triggerable_id = $triggerable_configuration['trigconfig_triggerable'];
-    }
</del><ins>+    $task = $db-&gt;select_first_row('analysis_tasks', 'task', array('id' =&gt; $task_id));
+    if (!$task)
+        exit_with_error('InvalidTask', array('task' =&gt; $task_id));
+    $triggerable = find_triggerable_for_task($db, $task_id);
+    if (!$triggerable)
+        exit_with_error('TriggerableNotFoundForTask', array('task' =&gt; $task_id));
</ins><span class="cx"> 
</span><del>-    if (!$triggerable_id)
-        exit_with_error('TriggerableNotFoundForTask', array('task' =&gt; $task_id, 'platform' =&gt; $platform_id, 'test' =&gt; $test_id));
-
</del><span class="cx">     if ($revision_set_list)
</span><del>-        $commit_sets = commit_sets_from_revision_sets($db, $triggerable_id, $revision_set_list);
</del><ins>+        $commit_sets = commit_sets_from_revision_sets($db, $triggerable['id'], $revision_set_list);
</ins><span class="cx">     else // V2 UI compatibility
</span><del>-        $commit_sets = ensure_commit_sets($db, $triggerable_id, $commit_sets_info);
</del><ins>+        $commit_sets = ensure_commit_sets($db, $triggerable['id'], $commit_sets_info);
</ins><span class="cx"> 
</span><span class="cx">     $db-&gt;begin_transaction();
</span><span class="cx"> 
</span><del>-    if ($task_name)
-        $task_id = $db-&gt;insert_row('analysis_tasks', 'task', array('name' =&gt; $task_name, 'author' =&gt; $author));
-
</del><span class="cx">     $configuration_list = array();
</span><span class="cx">     foreach ($commit_sets as $commit_list) {
</span><span class="cx">         $commit_set_id = $db-&gt;insert_row('commit_sets', 'commitset', array());
</span><del>-        foreach ($commit_list['set'] as $commit_row) {
-            $commit_row['set'] = $commit_set_id;
-            $db-&gt;insert_row('commit_set_relationships', 'commitset', $commit_row, 'commit');
-        }
</del><ins>+        foreach ($commit_list['set'] as $commit)
+            $db-&gt;insert_row('commit_set_relationships', 'commitset', array('set' =&gt; $commit_set_id, 'commit' =&gt; $commit), 'commit');
</ins><span class="cx">         array_push($configuration_list, array('commit_set' =&gt; $commit_set_id, 'repository_group' =&gt; $commit_list['repository_group']));
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     $group_id = $db-&gt;insert_row('analysis_test_groups', 'testgroup',
</span><del>-        array('task' =&gt; $task_id, 'name' =&gt; $name, 'author' =&gt; $author));
</del><ins>+        array('task' =&gt; $task['task_id'], 'name' =&gt; $name, 'author' =&gt; $author));
</ins><span class="cx"> 
</span><span class="cx">     $order = 0;
</span><span class="cx">     for ($i = 0; $i &lt; $repetition_count; $i++) {
</span><span class="cx">         foreach ($configuration_list as $config) {
</span><span class="cx">             $db-&gt;insert_row('build_requests', 'request', array(
</span><del>-                'triggerable' =&gt; $triggerable_id,
</del><ins>+                'triggerable' =&gt; $triggerable['id'],
</ins><span class="cx">                 'repository_group' =&gt; $config['repository_group'],
</span><del>-                'platform' =&gt; $platform_id,
-                'test' =&gt; $test_id,
</del><ins>+                'platform' =&gt; $triggerable['platform'],
+                'test' =&gt; $triggerable['test'],
</ins><span class="cx">                 'group' =&gt; $group_id,
</span><span class="cx">                 'order' =&gt; $order,
</span><span class="cx">                 'commit_set' =&gt; $config['commit_set'],));
</span><span class="lines">@@ -109,7 +71,7 @@
</span><span class="cx"> 
</span><span class="cx">     $db-&gt;commit_transaction();
</span><span class="cx"> 
</span><del>-    exit_with_success(array('taskId' =&gt; $task_id, 'testGroupId' =&gt; $group_id));
</del><ins>+    exit_with_success(array('testGroupId' =&gt; $group_id));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> function commit_sets_from_revision_sets($db, $triggerable_id, $revision_set_list)
</span><span class="lines">@@ -125,16 +87,8 @@
</span><span class="cx"> 
</span><span class="cx">         $commit_set = array();
</span><span class="cx">         $repository_list = array();
</span><ins>+
</ins><span class="cx">         foreach ($revision_set as $repository_id =&gt; $revision) {
</span><del>-            if ($repository_id == 'customRoots') {
-                $file_id_list = $revision;
-                foreach ($file_id_list as $file_id) {
-                    if (!$db-&gt;select_first_row('uploaded_files', 'file', array('id' =&gt; $file_id)))
-                        exit_with_error('InvalidUploadedFile', array('file' =&gt; $file_id));
-                    array_push($commit_set, array('root_file' =&gt; $file_id));
-                }
-                continue;
-            }
</del><span class="cx">             if (!is_numeric($repository_id))
</span><span class="cx">                 exit_with_error('InvalidRepository', array('repository' =&gt; $repository_id));
</span><span class="cx">             $commit = $db-&gt;select_first_row('commits', 'commit',
</span><span class="lines">@@ -141,7 +95,7 @@
</span><span class="cx">                 array('repository' =&gt; intval($repository_id), 'revision' =&gt; $revision));
</span><span class="cx">             if (!$commit)
</span><span class="cx">                 exit_with_error('RevisionNotFound', array('repository' =&gt; $repository_id, 'revision' =&gt; $revision));
</span><del>-            array_push($commit_set, array('commit' =&gt; $commit['commit_id']));
</del><ins>+            array_push($commit_set, $commit['commit_id']);
</ins><span class="cx">             array_push($repository_list, $repository_id);
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="lines">@@ -173,7 +127,7 @@
</span><span class="cx">             if (!$commit)
</span><span class="cx">                 exit_with_error('RevisionNotFound', array('repository' =&gt; $repository_name, 'revision' =&gt; $revision));
</span><span class="cx">             array_set_default($commit_sets, $i, array('set' =&gt; array()));
</span><del>-            array_push($commit_sets[$i]['set'], array('commit' =&gt; $commit['commit_id']));
</del><ins>+            array_push($commit_sets[$i]['set'], $commit['commit_id']);
</ins><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkWebsitesperfwebkitorgpublicprivilegedapiuploadfilephp"></a>
<div class="modfile"><h4>Modified: trunk/Websites/perf.webkit.org/public/privileged-api/upload-file.php (215202 => 215203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/perf.webkit.org/public/privileged-api/upload-file.php        2017-04-10 21:38:04 UTC (rev 215202)
+++ trunk/Websites/perf.webkit.org/public/privileged-api/upload-file.php        2017-04-10 21:43:11 UTC (rev 215203)
</span><span class="lines">@@ -10,7 +10,7 @@
</span><span class="cx"> function main()
</span><span class="cx"> {
</span><span class="cx">     if (array_get($_SERVER, 'CONTENT_LENGTH') &amp;&amp; empty($_POST) &amp;&amp; empty($_FILES))
</span><del>-        exit_with_error('FileSizeLimitExceeded');
</del><ins>+        exit_with_error('FileSizeLimitExceeded2');
</ins><span class="cx"> 
</span><span class="cx">     if (!verify_token(array_get($_POST, 'token')))
</span><span class="cx">         exit_with_error('InvalidToken');
</span><span class="lines">@@ -22,9 +22,6 @@
</span><span class="cx">     if (!$input_file)
</span><span class="cx">         exit_with_error('NoFileSpecified');
</span><span class="cx"> 
</span><del>-    if ($input_file['error'] == UPLOAD_ERR_INI_SIZE || $input_file['error'] == UPLOAD_ERR_FORM_SIZE)
-        exit_with_error('FileSizeLimitExceeded');
-
</del><span class="cx">     if ($input_file['error'] != UPLOAD_ERR_OK)
</span><span class="cx">         exit_with_error('FailedToUploadFile', array('name' =&gt; $input_file['name'], 'error' =&gt; $input_file['error']));
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkWebsitesperfwebkitorgpublicv3indexhtml"></a>
<div class="modfile"><h4>Modified: trunk/Websites/perf.webkit.org/public/v3/index.html (215202 => 215203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/perf.webkit.org/public/v3/index.html        2017-04-10 21:38:04 UTC (rev 215202)
+++ trunk/Websites/perf.webkit.org/public/v3/index.html        2017-04-10 21:43:11 UTC (rev 215203)
</span><span class="lines">@@ -65,7 +65,6 @@
</span><span class="cx">         &lt;script src=&quot;models/build-request.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">         &lt;script src=&quot;models/commit-set.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">         &lt;script src=&quot;models/triggerable.js&quot;&gt;&lt;/script&gt;
</span><del>-        &lt;script src=&quot;models/uploaded-file.js&quot;&gt;&lt;/script&gt;
</del><span class="cx">         &lt;script src=&quot;models/manifest.js&quot;&gt;&lt;/script&gt;
</span><span class="cx"> 
</span><span class="cx">         &lt;script src=&quot;components/base.js&quot;&gt;&lt;/script&gt;
</span><span class="lines">@@ -92,8 +91,6 @@
</span><span class="cx">         &lt;script src=&quot;components/mutable-list-view.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">         &lt;script src=&quot;components/analysis-task-bug-list.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">         &lt;script src=&quot;components/ratio-bar-graph.js&quot;&gt;&lt;/script&gt;
</span><del>-        &lt;script src=&quot;components/custom-analysis-task-configurator.js&quot;&gt;&lt;/script&gt;
-        &lt;script src=&quot;components/instant-file-uploader.js&quot;&gt;&lt;/script&gt;
</del><span class="cx"> 
</span><span class="cx">         &lt;script src=&quot;pages/page.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">         &lt;script src=&quot;pages/page-router.js&quot;&gt;&lt;/script&gt;
</span></span></pre></div>
<a id="trunkWebsitesperfwebkitorgpublicv3modelsanalysistaskjs"></a>
<div class="modfile"><h4>Modified: trunk/Websites/perf.webkit.org/public/v3/models/analysis-task.js (215202 => 215203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/perf.webkit.org/public/v3/models/analysis-task.js        2017-04-10 21:38:04 UTC (rev 215202)
+++ trunk/Websites/perf.webkit.org/public/v3/models/analysis-task.js        2017-04-10 21:43:11 UTC (rev 215203)
</span><span class="lines">@@ -7,10 +7,10 @@
</span><span class="cx">         this._author = object.author;
</span><span class="cx">         this._createdAt = object.createdAt;
</span><span class="cx"> 
</span><del>-        console.assert(!object.platform || object.platform instanceof Platform);
</del><ins>+        console.assert(object.platform instanceof Platform);
</ins><span class="cx">         this._platform = object.platform;
</span><span class="cx"> 
</span><del>-        console.assert(!object.metric || object.metric instanceof Metric);
</del><ins>+        console.assert(object.metric instanceof Metric);
</ins><span class="cx">         this._metric = object.metric;
</span><span class="cx"> 
</span><span class="cx">         this._startMeasurementId = object.startRun;
</span><span class="lines">@@ -29,11 +29,7 @@
</span><span class="cx"> 
</span><span class="cx">     static findByPlatformAndMetric(platformId, metricId)
</span><span class="cx">     {
</span><del>-        return this.all().filter((task) =&gt; {
-            const platform = task._platform;
-            const metric = task._metric;
-            return platform &amp;&amp; metric &amp;&amp; platform.id() == platformId &amp;&amp; metric.id() == metricId;
-        });
</del><ins>+        return this.all().filter(function (task) { return task._platform.id() == platformId &amp;&amp; task._metric.id() == metricId; });
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     updateSingleton(object)
</span><span class="lines">@@ -59,8 +55,7 @@
</span><span class="cx">         this._finishedBuildRequestCount = +object.finishedBuildRequestCount;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    isCustom() { return !this._platform; }
-    hasResults() { return !!this._finishedBuildRequestCount; }
</del><ins>+    hasResults() { return this._finishedBuildRequestCount; }
</ins><span class="cx">     hasPendingRequests() { return this._finishedBuildRequestCount &lt; this._buildRequestCount; }
</span><span class="cx">     requestLabel() { return `${this._finishedBuildRequestCount} of ${this._buildRequestCount}`; }
</span><span class="cx"> 
</span><span class="lines">@@ -206,8 +201,6 @@
</span><span class="cx">                 }
</span><span class="cx">             }
</span><span class="cx">             for (var otherTask of AnalysisTask.all()) {
</span><del>-                if (task.isCustom())
-                    continue;
</del><span class="cx">                 if (task.endTime() &lt; otherTask.startTime()
</span><span class="cx">                     || otherTask.endTime() &lt; task.startTime()
</span><span class="cx">                     || task.metric() != otherTask.metric())
</span><span class="lines">@@ -264,6 +257,9 @@
</span><span class="cx">         for (var rawData of data.analysisTasks) {
</span><span class="cx">             rawData.platform = Platform.findById(rawData.platform);
</span><span class="cx">             rawData.metric = Metric.findById(rawData.metric);
</span><ins>+            if (!rawData.platform || !rawData.metric)
+                continue;
+
</ins><span class="cx">             rawData.bugs = taskToBug[rawData.id];
</span><span class="cx">             rawData.causes = resolveCommits(rawData.causes);
</span><span class="cx">             rawData.fixes = resolveCommits(rawData.fixes);
</span></span></pre></div>
<a id="trunkWebsitesperfwebkitorgpublicv3modelsbuildrequestjs"></a>
<div class="modfile"><h4>Modified: trunk/Websites/perf.webkit.org/public/v3/models/build-request.js (215202 => 215203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/perf.webkit.org/public/v3/models/build-request.js        2017-04-10 21:38:04 UTC (rev 215202)
+++ trunk/Websites/perf.webkit.org/public/v3/models/build-request.js        2017-04-10 21:43:11 UTC (rev 215203)
</span><span class="lines">@@ -127,9 +127,6 @@
</span><span class="cx">             commit.repository = Repository.findById(commit.repository);
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        for (let uploadedFile of data['uploadedFiles'])
-            UploadedFile.ensureSingleton(uploadedFile.id, uploadedFile);
-
</del><span class="cx">         const commitSets = data['commitSets'].map((row) =&gt; {
</span><span class="cx">             row.commits = row.commits.map((commitId) =&gt; commitIdMap[commitId]);
</span><span class="cx">             return CommitSet.ensureSingleton(row.id, row);
</span></span></pre></div>
<a id="trunkWebsitesperfwebkitorgpublicv3modelscommitlogjs"></a>
<div class="modfile"><h4>Modified: trunk/Websites/perf.webkit.org/public/v3/models/commit-log.js (215202 => 215203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/perf.webkit.org/public/v3/models/commit-log.js        2017-04-10 21:38:04 UTC (rev 215202)
+++ trunk/Websites/perf.webkit.org/public/v3/models/commit-log.js        2017-04-10 21:43:11 UTC (rev 215203)
</span><span class="lines">@@ -68,20 +68,6 @@
</span><span class="cx">         return {repository: repository, label: label, url: repository.urlForRevisionRange(from, to)};
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    static fetchLatestCommitForPlatform(repository, platform)
-    {
-        console.assert(repository instanceof Repository);
-        console.assert(platform instanceof Platform);
-        return this.cachedFetch(`/api/commits/${repository.id()}/latest`, {platform: platform.id()}).then((data) =&gt; {
-            const commits = data['commits'];
-            if (!commits || !commits.length)
-                return null;
-            const rawData = commits[0];
-            rawData.repository = repository;
-            return CommitLog.ensureSingleton(rawData.id, rawData);
-        });
-    }
-
</del><span class="cx">     static fetchBetweenRevisions(repository, precedingRevision, lastRevision)
</span><span class="cx">     {
</span><span class="cx">         // FIXME: The cache should be smarter about fetching a range within an already fetched range, etc...
</span></span></pre></div>
<a id="trunkWebsitesperfwebkitorgpublicv3modelscommitsetjs"></a>
<div class="modfile"><h4>Modified: trunk/Websites/perf.webkit.org/public/v3/models/commit-set.js (215202 => 215203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/perf.webkit.org/public/v3/models/commit-set.js        2017-04-10 21:38:04 UTC (rev 215202)
+++ trunk/Websites/perf.webkit.org/public/v3/models/commit-set.js        2017-04-10 21:43:11 UTC (rev 215203)
</span><span class="lines">@@ -8,7 +8,6 @@
</span><span class="cx">         this._repositories = [];
</span><span class="cx">         this._repositoryToCommitMap = {};
</span><span class="cx">         this._latestCommitTime = null;
</span><del>-        this._customRoots = [];
</del><span class="cx"> 
</span><span class="cx">         if (!object)
</span><span class="cx">             return;
</span><span class="lines">@@ -19,14 +18,9 @@
</span><span class="cx">             this._repositoryToCommitMap[repositoryId] = CommitLog.ensureSingleton(row.id, row);
</span><span class="cx">             this._repositories.push(row.repository);
</span><span class="cx">         }
</span><del>-        for (let fileId of object.customRoots) {
-            const uploadedFile = UploadedFile.findById(fileId);
-            this._customRoots.push(uploadedFile);
-        }
</del><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     repositories() { return this._repositories; }
</span><del>-    customRoots() { return this._customRoots; }
</del><span class="cx">     commitForRepository(repository) { return this._repositoryToCommitMap[repository.id()]; }
</span><span class="cx"> 
</span><span class="cx">     revisionForRepository(repository)
</span><span class="lines">@@ -55,18 +49,6 @@
</span><span class="cx">             if (this._repositoryToCommitMap[repositoryId] != other._repositoryToCommitMap[repositoryId])
</span><span class="cx">                 return false;
</span><span class="cx">         }
</span><del>-        return CommitSet.areCustomRootsEqual(this._customRoots, other._customRoots);
-    }
-
-    static areCustomRootsEqual(customRoots1, customRoots2)
-    {
-        if (customRoots1.length != customRoots2.length)
-            return false;
-        const set2 = new Set(customRoots2);
-        for (let file of customRoots1) {
-            if (!set2.has(file))
-                return false;
-        }
</del><span class="cx">         return true;
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -124,7 +106,6 @@
</span><span class="cx">     constructor()
</span><span class="cx">     {
</span><span class="cx">         this._revisionListByRepository = new Map;
</span><del>-        this._customRoots = [];
</del><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     setRevisionForRepository(repository, revision)
</span><span class="lines">@@ -133,29 +114,9 @@
</span><span class="cx">         this._revisionListByRepository.set(repository, revision);
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    equals(other)
-    {
-        console.assert(other instanceof CustomCommitSet);
-        if (this._revisionListByRepository.size != other._revisionListByRepository.size)
-            return false;
-        for (let repository of this._revisionListByRepository.keys()) {
-            const thisRevision = this._revisionListByRepository.get(repository);
-            const otherRevision = other._revisionListByRepository.get(repository);
-            if (thisRevision != otherRevision)
-                return false;
-        }
-        return CommitSet.areCustomRootsEqual(this._customRoots, other._customRoots);
-    }
-
</del><span class="cx">     repositories() { return Array.from(this._revisionListByRepository.keys()); }
</span><span class="cx">     revisionForRepository(repository) { return this._revisionListByRepository.get(repository); }
</span><del>-    customRoots() { return this._customRoots; }
</del><span class="cx"> 
</span><del>-    addCustomRoot(uploadedFile)
-    {
-        console.assert(uploadedFile instanceof UploadedFile);
-        this._customRoots.push(uploadedFile);
-    }
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> if (typeof module != 'undefined') {
</span></span></pre></div>
<a id="trunkWebsitesperfwebkitorgpublicv3modelsmanifestjs"></a>
<div class="modfile"><h4>Modified: trunk/Websites/perf.webkit.org/public/v3/models/manifest.js (215202 => 215203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/perf.webkit.org/public/v3/models/manifest.js        2017-04-10 21:38:04 UTC (rev 215202)
+++ trunk/Websites/perf.webkit.org/public/v3/models/manifest.js        2017-04-10 21:43:11 UTC (rev 215203)
</span><span class="lines">@@ -57,9 +57,6 @@
</span><span class="cx">             });
</span><span class="cx">         });
</span><span class="cx"> 
</span><del>-        if (typeof(UploadedFile) != 'undefined')
-            UploadedFile.fileUploadSizeLimit = rawResponse.fileUploadSizeLimit || 0;
-
</del><span class="cx">         Instrumentation.endMeasuringTime('Manifest', '_didFetchManifest');
</span><span class="cx"> 
</span><span class="cx">         return {
</span></span></pre></div>
<a id="trunkWebsitesperfwebkitorgpublicv3modelsmetricjs"></a>
<div class="modfile"><h4>Modified: trunk/Websites/perf.webkit.org/public/v3/models/metric.js (215202 => 215203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/perf.webkit.org/public/v3/models/metric.js        2017-04-10 21:38:04 UTC (rev 215202)
+++ trunk/Websites/perf.webkit.org/public/v3/models/metric.js        2017-04-10 21:43:11 UTC (rev 215203)
</span><span class="lines">@@ -119,14 +119,6 @@
</span><span class="cx">         formatter.divisor = divisor;
</span><span class="cx">         return formatter;
</span><span class="cx">     };
</span><del>-
-    static formatTime(utcTime)
-    {
-        // FIXME: This is incorrect when the offset cross day-life-saving change. It's good enough for now.
-        const offsetInMinutes = (new Date(utcTime)).getTimezoneOffset();
-        const timeInLocalTimeZone = new Date(utcTime - offsetInMinutes * 60 * 1000);
-        return timeInLocalTimeZone.toISOString().replace('T', ' ').replace(/\.\d+Z$/, '');
-    }
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> if (typeof module != 'undefined')
</span></span></pre></div>
<a id="trunkWebsitesperfwebkitorgpublicv3modelstestgroupjs"></a>
<div class="modfile"><h4>Modified: trunk/Websites/perf.webkit.org/public/v3/models/test-group.js (215202 => 215203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/perf.webkit.org/public/v3/models/test-group.js        2017-04-10 21:38:04 UTC (rev 215202)
+++ trunk/Websites/perf.webkit.org/public/v3/models/test-group.js        2017-04-10 21:43:11 UTC (rev 215203)
</span><span class="lines">@@ -178,47 +178,26 @@
</span><span class="cx">         });
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    static createWithTask(taskName, platform, test, groupName, repetitionCount, commitSets)
-    {
-        console.assert(commitSets.length == 2);
-        const revisionSets = this._revisionSetsFromCommitSets(commitSets);
-        const params = {taskName, name: groupName, platform: platform.id(), test: test.id(), repetitionCount, revisionSets};
-        return PrivilegedAPI.sendRequest('create-test-group', params).then((data) =&gt; {
-            return AnalysisTask.fetchById(data['taskId']);
-        }).then((task) =&gt; {
-            return this._fetchTestGroupsForTask(task.id()).then(() =&gt; task);
-        });
-    }
-
</del><span class="cx">     static createAndRefetchTestGroups(task, name, repetitionCount, commitSets)
</span><span class="cx">     {
</span><span class="cx">         console.assert(commitSets.length == 2);
</span><del>-        const revisionSets = this._revisionSetsFromCommitSets(commitSets);
-        return PrivilegedAPI.sendRequest('create-test-group', {
-            task: task.id(),
-            name: name,
-            repetitionCount: repetitionCount,
-            revisionSets: revisionSets,
-        }).then((data) =&gt; this._fetchTestGroupsForTask(task.id()));
-    }
</del><span class="cx"> 
</span><del>-    static _revisionSetsFromCommitSets(commitSets)
-    {
-        return commitSets.map((commitSet) =&gt; {
</del><ins>+        const revisionSets = commitSets.map((commitSet) =&gt; {
</ins><span class="cx">             console.assert(commitSet instanceof CustomCommitSet || commitSet instanceof CommitSet);
</span><span class="cx">             const revisionSet = {};
</span><span class="cx">             for (let repository of commitSet.repositories())
</span><span class="cx">                 revisionSet[repository.id()] = commitSet.revisionForRepository(repository);
</span><del>-            const customRoots = commitSet.customRoots();
-            if (customRoots &amp;&amp; customRoots.length)
-                revisionSet['customRoots'] = customRoots.map((uploadedFile) =&gt; uploadedFile.id());
</del><span class="cx">             return revisionSet;
</span><span class="cx">         });
</span><del>-    }
</del><span class="cx"> 
</span><del>-    static _fetchTestGroupsForTask(taskId)
-    {
-        return this.cachedFetch('/api/test-groups', {task: taskId}, true).then((data) =&gt; this._createModelsFromFetchedTestGroups(data));
</del><ins>+        return PrivilegedAPI.sendRequest('create-test-group', {
+            task: task.id(),
+            name: name,
+            repetitionCount: repetitionCount,
+            revisionSets: revisionSets,
+        }).then((data) =&gt; {
+            return this.cachedFetch('/api/test-groups', {task: task.id()}, true).then((data) =&gt; this._createModelsFromFetchedTestGroups(data));
+        });
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     static fetchByTask(taskId)
</span></span></pre></div>
<a id="trunkWebsitesperfwebkitorgpublicv3modelstriggerablejs"></a>
<div class="modfile"><h4>Modified: trunk/Websites/perf.webkit.org/public/v3/models/triggerable.js (215202 => 215203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/perf.webkit.org/public/v3/models/triggerable.js        2017-04-10 21:38:04 UTC (rev 215202)
+++ trunk/Websites/perf.webkit.org/public/v3/models/triggerable.js        2017-04-10 21:43:11 UTC (rev 215203)
</span><span class="lines">@@ -37,19 +37,6 @@
</span><span class="cx">         }
</span><span class="cx">         return null;
</span><span class="cx">     }
</span><del>-
-    static triggerablePlatformsForTests(tests)
-    {
-        console.assert(tests instanceof Array);
-        if (!tests.length)
-            return [];
-        return this.sortByName(Platform.all().filter((platform) =&gt; {
-            return tests.every((test) =&gt; {
-                const triggerable = Triggerable.findByTestConfiguration(test, platform);
-                return triggerable &amp;&amp; !triggerable.isDisabled();
-            });
-        }));
-    }
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> class TriggerableRepositoryGroup extends LabeledObject {
</span><span class="lines">@@ -77,21 +64,6 @@
</span><span class="cx">     description() { return this._description || this.name(); }
</span><span class="cx">     acceptsCustomRoots() { return this._acceptsCustomRoots; }
</span><span class="cx">     repositories() { return this._repositories; }
</span><del>-
-    static sortByNamePreferringSmallerRepositories(groupList)
-    {
-        return groupList.sort((a, b) =&gt; {
-            if (a.repositories().length &lt; b.repositories().length)
-                return -1;
-            else if (a.repositories().length &gt; b.repositories().length)
-                return 1;
-            if (a.name() &lt; b.name())
-                return -1;
-            else if (a.name() &gt; b.name())
-                return 1;
-            return 0;
-        });
-    }
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> if (typeof module != 'undefined') {
</span></span></pre></div>
<a id="trunkWebsitesperfwebkitorgpublicv3modelsuploadedfilejs"></a>
<div class="modfile"><h4>Modified: trunk/Websites/perf.webkit.org/public/v3/models/uploaded-file.js (215202 => 215203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/perf.webkit.org/public/v3/models/uploaded-file.js        2017-04-10 21:38:04 UTC (rev 215202)
+++ trunk/Websites/perf.webkit.org/public/v3/models/uploaded-file.js        2017-04-10 21:43:11 UTC (rev 215203)
</span><span class="lines">@@ -12,15 +12,8 @@
</span><span class="cx">         this.ensureNamedStaticMap('sha256')[object.sha256] = this;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    createdAt() { return this._createdAt; }
-    filename() { return this._filename; }
-    author() { return this._author; }
-    size() { return this._size; }
-
</del><span class="cx">     static uploadFile(file, uploadProgressCallback = null)
</span><span class="cx">     {
</span><del>-        if (file.size &gt; UploadedFile.fileUploadSizeLimit)
-            return Promise.reject('FileSizeLimitExceeded');
</del><span class="cx">         return PrivilegedAPI.sendRequest('upload-file', {'newFile': file}, {useFormData: true, uploadProgressCallback}).then((rawData) =&gt; {
</span><span class="cx">             return UploadedFile.ensureSingleton(rawData['uploadedFile'].id, rawData['uploadedFile']);
</span><span class="cx">         });
</span><span class="lines">@@ -28,8 +21,6 @@
</span><span class="cx"> 
</span><span class="cx">     static fetchUnloadedFileWithIdenticalHash(file)
</span><span class="cx">     {
</span><del>-        if (file.size &gt; UploadedFile.fileUploadSizeLimit)
-            return Promise.reject('FileSizeLimitExceeded');
</del><span class="cx">         return new Promise((resolve, reject) =&gt; {
</span><span class="cx">             const reader = new FileReader();
</span><span class="cx">             reader.onload = () =&gt; resolve(reader.result);
</span><span class="lines">@@ -41,11 +32,9 @@
</span><span class="cx">             const map = this.namedStaticMap('sha256');
</span><span class="cx">             if (map &amp;&amp; sha256 in map)
</span><span class="cx">                 return map[sha256];
</span><del>-            return RemoteAPI.getJSON(`../api/uploaded-file?sha256=${sha256}`).then((rawData) =&gt; {
-                if (rawData['status'] == 'NotFound' || !rawData['uploadedFile'])
</del><ins>+            return RemoteAPI.getJSONWithStatus(`../api/uploaded-file?sha256=${sha256}`).then((rawData) =&gt; {
+                if (!rawData['uploadedFile'])
</ins><span class="cx">                     return null;
</span><del>-                if (rawData['status'] != 'OK')
-                    return Promise.reject(rawData['status']);
</del><span class="cx">                 return UploadedFile.ensureSingleton(rawData['uploadedFile'].id, rawData['uploadedFile']);
</span><span class="cx">             });
</span><span class="cx">         });
</span><span class="lines">@@ -63,8 +52,3 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx"> }
</span><del>-
-UploadedFile.fileUploadSizeLimit = 0;
-
-if (typeof module != 'undefined')
-    module.exports.UploadedFile = UploadedFile;
</del></span></pre></div>
<a id="trunkWebsitesperfwebkitorgpublicv3pagesanalysiscategorypagejs"></a>
<div class="modfile"><h4>Modified: trunk/Websites/perf.webkit.org/public/v3/pages/analysis-category-page.js (215202 => 215203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/perf.webkit.org/public/v3/pages/analysis-category-page.js        2017-04-10 21:38:04 UTC (rev 215202)
+++ trunk/Websites/perf.webkit.org/public/v3/pages/analysis-category-page.js        2017-04-10 21:43:11 UTC (rev 215203)
</span><span class="lines">@@ -123,9 +123,11 @@
</span><span class="cx">         Instrumentation.startMeasuringTime('AnalysisCategoryPage', 'reconstructTaskList');
</span><span class="cx"> 
</span><span class="cx">         console.assert(this.router());
</span><del>-        const currentCategory = this._categoryToolbar.currentCategory();
</del><ins>+        var currentCategory = this._categoryToolbar.currentCategory();
</ins><span class="cx"> 
</span><del>-        const tasks = AnalysisTask.all().filter((task) =&gt; task.category() == currentCategory).sort((a, b) =&gt; {
</del><ins>+        var tasks = AnalysisTask.all().filter(function (task) {
+            return task.category() == currentCategory;
+        }).sort(function (a, b) {
</ins><span class="cx">             if (a.hasPendingRequests() == b.hasPendingRequests())
</span><span class="cx">                 return b.createdAt() - a.createdAt();
</span><span class="cx">             else if (a.hasPendingRequests()) // a &lt; b
</span><span class="lines">@@ -135,25 +137,25 @@
</span><span class="cx">             return 0;
</span><span class="cx">         });
</span><span class="cx"> 
</span><del>-        const element = ComponentBase.createElement;
-        const link = ComponentBase.createLink;
-        const router = this.router();
</del><ins>+        var element = ComponentBase.createElement;
+        var link = ComponentBase.createLink;
+        var router = this.router();
</ins><span class="cx">         this.renderReplace(this.content().querySelector('tbody.analysis-tasks'),
</span><del>-            tasks.map((task) =&gt; {
-                const status = AnalysisCategoryPage._computeStatus(task);
</del><ins>+            tasks.map(function (task) {
+                var status = AnalysisCategoryPage._computeStatus(task);
</ins><span class="cx">                 return element('tr', [
</span><span class="cx">                     element('td', {class: 'status'},
</span><span class="cx">                         element('span', {class: status.class}, status.label)),
</span><span class="cx">                     element('td', link(task.label(), router.url(`analysis/task/${task.id()}`))),    
</span><span class="cx">                     element('td', {class: 'bugs'},
</span><del>-                        element('ul', task.bugs().map((bug) =&gt; {
-                            const url = bug.url();
-                            const title = bug.title();
</del><ins>+                        element('ul', task.bugs().map(function (bug) {
+                            var url = bug.url();
+                            var title = bug.title();
</ins><span class="cx">                             return element('li', url ? link(bug.label(), title, url, true) : title);
</span><span class="cx">                         }))),
</span><span class="cx">                     element('td', {class: 'author'}, task.author()),
</span><del>-                    element('td', {class: 'platform'}, task.platform() ? task.platform().label() : null),
-                    element('td', task.metric() ? task.metric().fullName() : null),
</del><ins>+                    element('td', {class: 'platform'}, task.platform().label()),
+                    element('td', task.metric().fullName()),
</ins><span class="cx">                     ]);
</span><span class="cx">             }));
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkWebsitesperfwebkitorgpublicv3pagesanalysistaskpagejs"></a>
<div class="modfile"><h4>Modified: trunk/Websites/perf.webkit.org/public/v3/pages/analysis-task-page.js (215202 => 215203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/perf.webkit.org/public/v3/pages/analysis-task-page.js        2017-04-10 21:38:04 UTC (rev 215202)
+++ trunk/Websites/perf.webkit.org/public/v3/pages/analysis-task-page.js        2017-04-10 21:43:11 UTC (rev 215203)
</span><span class="lines">@@ -409,13 +409,7 @@
</span><span class="cx">         console.assert(!this._task);
</span><span class="cx"> 
</span><span class="cx">         this._task = task;
</span><del>-        const bugList = this.part('bug-list');
-        this.part('bug-list').setTask(this._task);
-        this.enqueueToRender();
</del><span class="cx"> 
</span><del>-        if (task.isCustom())
-            return task;
-
</del><span class="cx">         const platform = task.platform();
</span><span class="cx">         const metric = task.metric();
</span><span class="cx">         const lastModified = platform.lastModified(metric);
</span><span class="lines">@@ -432,6 +426,11 @@
</span><span class="cx">         chart.setOverviewDomain(domain[0], domain[1]);
</span><span class="cx">         chart.setMainDomain(domain[0], domain[1]);
</span><span class="cx"> 
</span><ins>+        const bugList = this.part('bug-list');
+        this.part('bug-list').setTask(this._task);
+
+        this.enqueueToRender();
+
</ins><span class="cx">         return task;
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -508,10 +507,10 @@
</span><span class="cx">         this._renderCauseAndFixesLazily.evaluate(this._startPoint, this._task);
</span><span class="cx">         this._renderRelatedTasksLazily.evaluate(this._task, this._relatedTasks);
</span><span class="cx"> 
</span><del>-        this.content('chart-pane').style.display = this._task &amp;&amp; !this._task.isCustom() ? null : 'none';
</del><ins>+        this.content('chart-pane').style.display = this._task ? null : 'none';
</ins><span class="cx">         this.part('chart-pane').setShowForm(!!this._triggerable);
</span><span class="cx"> 
</span><del>-        this.content('results-pane').style.display = this._task &amp;&amp; !this._task.isCustom() ? null : 'none';
</del><ins>+        this.content('results-pane').style.display = this._task ? null : 'none';
</ins><span class="cx">         this.part('results-pane').setShowForm(!!this._triggerable);
</span><span class="cx"> 
</span><span class="cx">         Instrumentation.endMeasuringTime('AnalysisTaskPage', 'render');
</span><span class="lines">@@ -520,7 +519,7 @@
</span><span class="cx">     _renderTaskNameAndStatus(task, taskName, changeType)
</span><span class="cx">     {
</span><span class="cx">         this.part('analysis-task-name').setText(taskName);
</span><del>-        if (task &amp;&amp; !task.isCustom()) {
</del><ins>+        if (task) {
</ins><span class="cx">             const link = ComponentBase.createLink;
</span><span class="cx">             const platform = task.platform();
</span><span class="cx">             const metric = task.metric();
</span></span></pre></div>
<a id="trunkWebsitesperfwebkitorgpublicv3pageschartpanestatusviewjs"></a>
<div class="modfile"><h4>Modified: trunk/Websites/perf.webkit.org/public/v3/pages/chart-pane-status-view.js (215202 => 215203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/perf.webkit.org/public/v3/pages/chart-pane-status-view.js        2017-04-10 21:38:04 UTC (rev 215202)
+++ trunk/Websites/perf.webkit.org/public/v3/pages/chart-pane-status-view.js        2017-04-10 21:43:11 UTC (rev 215203)
</span><span class="lines">@@ -49,7 +49,7 @@
</span><span class="cx">                 element('td', 'Build'),
</span><span class="cx">                 element('td', {colspan: 2}, [
</span><span class="cx">                     url ? link(buildNumber, build.label(), url, true) : buildNumber,
</span><del>-                    ` (${Metric.formatTime(build.buildTime())})`
</del><ins>+                    ` (${this._formatTime(build.buildTime())})`
</ins><span class="cx">                 ]),
</span><span class="cx">             ]));
</span><span class="cx">         }
</span><span class="lines">@@ -72,6 +72,12 @@
</span><span class="cx">         this.renderReplace(this.content('build-revision'), tableContent);
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    _formatTime(date)
+    {
+        console.assert(date instanceof Date);
+        return date.toISOString().replace('T', ' ').replace(/\.\d+Z$/, '');
+    }
+
</ins><span class="cx">     setCurrentRepository(repository)
</span><span class="cx">     {
</span><span class="cx">         this._currentRepository = repository;
</span></span></pre></div>
<a id="trunkWebsitesperfwebkitorgpublicv3pageschartpanejs"></a>
<div class="modfile"><h4>Modified: trunk/Websites/perf.webkit.org/public/v3/pages/chart-pane.js (215202 => 215203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/perf.webkit.org/public/v3/pages/chart-pane.js        2017-04-10 21:38:04 UTC (rev 215202)
+++ trunk/Websites/perf.webkit.org/public/v3/pages/chart-pane.js        2017-04-10 21:43:11 UTC (rev 215203)
</span><span class="lines">@@ -19,7 +19,7 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-const ChartTrendLineTypes = [
</del><ins>+var ChartTrendLineTypes = [
</ins><span class="cx">     {
</span><span class="cx">         id: 0,
</span><span class="cx">         label: 'None',
</span><span class="lines">@@ -196,15 +196,15 @@
</span><span class="cx"> 
</span><span class="cx">     _analyzeRange(startPoint, endPoint)
</span><span class="cx">     {
</span><del>-        const router = this._chartsPage.router();
-        const newWindow = window.open(router.url('analysis/task/create', {inProgress: true}), '_blank');
</del><ins>+        var router = this._chartsPage.router();
+        var newWindow = window.open(router.url('analysis/task/create'), '_blank');
</ins><span class="cx"> 
</span><del>-        const analyzePopover = this.content().querySelector('.chart-pane-analyze-popover');
-        const name = analyzePopover.querySelector('input').value;
</del><ins>+        var analyzePopover = this.content().querySelector('.chart-pane-analyze-popover');
+        var name = analyzePopover.querySelector('input').value;
</ins><span class="cx">         AnalysisTask.create(name, startPoint.id, endPoint.id).then((data) =&gt; {
</span><span class="cx">             newWindow.location.href = router.url('analysis/task/' + data['taskId']);
</span><span class="cx">             this.fetchAnalysisTasks(true);
</span><del>-        }, (error) =&gt; {
</del><ins>+        }, function (error) {
</ins><span class="cx">             newWindow.location.href = router.url('analysis/task/create', {error: error});
</span><span class="cx">         });
</span><span class="cx">     }
</span><span class="lines">@@ -272,6 +272,7 @@
</span><span class="cx">         if (hasSelectedPoints) {
</span><span class="cx">             actions.push(this._makePopoverActionItem(analyzePopover, 'Analyze', false));
</span><span class="cx">             analyzePopover.onsubmit = this.createEventHandler(() =&gt; {
</span><ins>+                console.log(selectedPoints.length());
</ins><span class="cx">                 this._analyzeRange(selectedPoints.firstPoint(), selectedPoints.lastPoint());
</span><span class="cx">             });
</span><span class="cx">         } else {
</span></span></pre></div>
<a id="trunkWebsitesperfwebkitorgpublicv3pagescreateanalysistaskpagejs"></a>
<div class="modfile"><h4>Modified: trunk/Websites/perf.webkit.org/public/v3/pages/create-analysis-task-page.js (215202 => 215203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/perf.webkit.org/public/v3/pages/create-analysis-task-page.js        2017-04-10 21:38:04 UTC (rev 215202)
+++ trunk/Websites/perf.webkit.org/public/v3/pages/create-analysis-task-page.js        2017-04-10 21:43:11 UTC (rev 215203)
</span><span class="lines">@@ -3,8 +3,7 @@
</span><span class="cx">     constructor()
</span><span class="cx">     {
</span><span class="cx">         super('Create Analysis Task');
</span><del>-        this._message = null;
-        this._renderMessageLazily = new LazilyEvaluatedFunction(this._renderMessage.bind(this));
</del><ins>+        this._errorMessage = null;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     title() { return 'Creating a New Analysis Task'; }
</span><span class="lines">@@ -14,111 +13,43 @@
</span><span class="cx">     {
</span><span class="cx">         if (state.error instanceof Set)
</span><span class="cx">             state.error = Array.from(state.error.values())[0];
</span><del>-        this._message = state.error || (state.inProgress ? 'Creating the analysis task page...' : '');
-    }
</del><span class="cx"> 
</span><del>-    didConstructShadowTree()
-    {
-        this.part('configurator').listenToAction('commitSetChange', () =&gt; this.enqueueToRender());
-        this.content('start-button').onclick = this.createEventHandler(() =&gt; this._createAnalysisTaskWithGroup());
</del><ins>+        this._errorMessage = state.error;
+        if (!isOpen)
+            this.enqueueToRender();
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    _createAnalysisTaskWithGroup()
-    {
-        const taskNameInput = this.content('task-name');
-        if (!taskNameInput.reportValidity())
-            return;
-
-        const testGroupInput = this.content('test-group-name');
-        if (!testGroupInput.reportValidity())
-            return;
-
-        const configurator = this.part('configurator');
-        const tests = configurator.tests();
-        if (tests.length != 1)
-            return alert('Exactly one test must be selected');
-
-        const taskName = taskNameInput.value;
-        const testGroupName = testGroupInput.value;
-        const iterationCount = this.content('iteration-count').value;
-        const platform = configurator.platform();
-        const commitSets = configurator.commitSets();
-
-        TestGroup.createWithTask(taskName, platform, tests[0], testGroupName, iterationCount, commitSets).then((task) =&gt; {
-            console.log('yay?', task);
-            const url = this.router().url(`analysis/task/${task.id()}`);
-            console.log('moving to ' + url);
-            location.href = this.router().url(`analysis/task/${task.id()}`);
-        }, (error) =&gt; {
-            alert('Failed to create a new test group: ' + error);
-        });
-    }
-
</del><span class="cx">     render()
</span><span class="cx">     {
</span><span class="cx">         super.render();
</span><del>-        const configurator = this.part('configurator');
-        this._renderMessageLazily.evaluate(this._message, !!configurator.commitSets(), configurator.tests(), configurator.platform());
</del><ins>+        if (this._errorMessage)
+            this.content().querySelector('.message').textContent = this._errorMessage;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    _renderMessage(message, hasValidCommitSets, tests, platform)
-    {
-        const messageContainer = this.content('message');
-        messageContainer.textContent = this._message;
-        messageContainer.style.display = this._message ? null : 'none';
-        this.content('new-task').style.display = this._message ? 'none' : null;
-        if (platform)
-            this.content('test-group-name').value = `${tests.map((test) =&gt; test.name()).join(', ')} on ${platform.name()}`;
-        this.content('iteration-start-pane').style.display = !this._message &amp;&amp; hasValidCommitSets ? null : 'none';
-      }
-
</del><span class="cx">     static htmlTemplate()
</span><span class="cx">     {
</span><span class="cx">         return `
</span><del>-            &lt;p id=&quot;message&quot;&gt;&lt;/p&gt;
-            &lt;div id=&quot;new-task&quot;&gt;
-                &lt;input id=&quot;task-name&quot; type=&quot;text&quot; placeholder=&quot;Name this task&quot; required&gt;
-                &lt;custom-analysis-task-configurator id=&quot;configurator&quot;&gt;&lt;/custom-analysis-task-configurator&gt;
-                &lt;div id=&quot;iteration-start-pane&quot;&gt;
-                    &lt;input id=&quot;test-group-name&quot; placeholder=&quot;Name this test group&quot; required&gt;
-                    &lt;label&gt;&lt;select id=&quot;iteration-count&quot;&gt;
-                        &lt;option&gt;1&lt;/option&gt;
-                        &lt;option&gt;2&lt;/option&gt;
-                        &lt;option&gt;3&lt;/option&gt;
-                        &lt;option selected&gt;4&lt;/option&gt;
-                        &lt;option&gt;5&lt;/option&gt;
-                        &lt;option&gt;6&lt;/option&gt;
-                    &lt;/select&gt; iterations per configuration&lt;/label&gt;
-                    &lt;button id=&quot;start-button&quot;&gt;Start&lt;/button&gt;
-                &lt;/div&gt;
-            &lt;/div&gt;`;
</del><ins>+            &lt;div class=&quot;create-analysis-task-container&quot;&gt;
+                &lt;p class=&quot;message&quot;&gt;Creating the analysis task page...&lt;/p&gt;
+            &lt;/div&gt;
+`;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     static cssTemplate()
</span><span class="cx">     {
</span><span class="cx">         return `
</span><del>-            #message {
-                text-align: center;
</del><ins>+            .create-analysis-task-container {
+                display: flex;
</ins><span class="cx">             }
</span><span class="cx"> 
</span><del>-            #new-task &gt; * {
-                display: block;
-                margin: 1rem;
</del><ins>+            .create-analysis-task-container &gt; * {
+                margin: 1rem auto;
+                display: inline-block;
</ins><span class="cx">             }
</span><span class="cx"> 
</span><del>-            #new-task input {
-                width: 30%;
-                min-width: 10rem;
-                font-size: 1rem;
-                font-weight: inherit;
</del><ins>+            .create-analysis-task input {
+                font-size: inherit;
</ins><span class="cx">             }
</span><del>-
-            #start-button {
-                display: block;
-                margin-top: 0.5rem;
-                font-size: 1.2rem;
-                font-weight: inherit;
-            }
</del><span class="cx"> `;
</span><span class="cx">     }
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkWebsitesperfwebkitorgpublicv3pagespagerouterjs"></a>
<div class="modfile"><h4>Modified: trunk/Websites/perf.webkit.org/public/v3/pages/page-router.js (215202 => 215203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/perf.webkit.org/public/v3/pages/page-router.js        2017-04-10 21:38:04 UTC (rev 215202)
+++ trunk/Websites/perf.webkit.org/public/v3/pages/page-router.js        2017-04-10 21:43:11 UTC (rev 215203)
</span><span class="lines">@@ -52,7 +52,6 @@
</span><span class="cx">             destinationPage.open(parsed.state);
</span><span class="cx">         } else
</span><span class="cx">             destinationPage.updateFromSerializedState(parsed.state, false);
</span><del>-        destinationPage.enqueueToRender();
</del><span class="cx"> 
</span><span class="cx">         return true;
</span><span class="cx">     }
</span></span></pre></div>
<a id="trunkWebsitesperfwebkitorgservertestsapibuildrequeststestsjs"></a>
<div class="modfile"><h4>Modified: trunk/Websites/perf.webkit.org/server-tests/api-build-requests-tests.js (215202 => 215203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/perf.webkit.org/server-tests/api-build-requests-tests.js        2017-04-10 21:38:04 UTC (rev 215202)
+++ trunk/Websites/perf.webkit.org/server-tests/api-build-requests-tests.js        2017-04-10 21:43:11 UTC (rev 215203)
</span><span class="lines">@@ -23,7 +23,7 @@
</span><span class="cx">             assert.deepEqual(content['buildRequests'], []);
</span><span class="cx">             assert.deepEqual(content['commitSets'], []);
</span><span class="cx">             assert.deepEqual(content['commits'], []);
</span><del>-            assert.deepEqual(Object.keys(content).sort(), ['buildRequests', 'commitSets', 'commits', 'status', 'uploadedFiles']);
</del><ins>+            assert.deepEqual(Object.keys(content).sort(), ['buildRequests', 'commitSets', 'commits', 'status']);
</ins><span class="cx">         });
</span><span class="cx">     });
</span><span class="cx"> 
</span><span class="lines">@@ -31,7 +31,7 @@
</span><span class="cx">         return MockData.addMockData(TestServer.database()).then(() =&gt; {
</span><span class="cx">             return TestServer.remoteAPI().getJSONWithStatus('/api/build-requests/build-webkit');
</span><span class="cx">         }).then((content) =&gt; {
</span><del>-            assert.deepEqual(Object.keys(content).sort(), ['buildRequests', 'commitSets', 'commits', 'status', 'uploadedFiles']);
</del><ins>+            assert.deepEqual(Object.keys(content).sort(), ['buildRequests', 'commitSets', 'commits', 'status']);
</ins><span class="cx"> 
</span><span class="cx">             assert.equal(content['commitSets'].length, 2);
</span><span class="cx">             assert.equal(content['commitSets'][0].id, 401);
</span><span class="lines">@@ -85,7 +85,7 @@
</span><span class="cx">         return MockData.addMockData(TestServer.database()).then(() =&gt; {
</span><span class="cx">             return TestServer.remoteAPI().getJSONWithStatus('/api/build-requests/build-webkit?useLegacyIdResolution=true');
</span><span class="cx">         }).then((content) =&gt; {
</span><del>-            assert.deepEqual(Object.keys(content).sort(), ['buildRequests', 'commitSets', 'commits', 'status', 'uploadedFiles']);
</del><ins>+            assert.deepEqual(Object.keys(content).sort(), ['buildRequests', 'commitSets', 'commits', 'status']);
</ins><span class="cx"> 
</span><span class="cx">             assert.equal(content['commitSets'].length, 2);
</span><span class="cx">             assert.equal(content['commitSets'][0].id, 401);
</span><span class="lines">@@ -217,11 +217,11 @@
</span><span class="cx"> 
</span><span class="cx">             let firstWebKitCommit = firstCommitSet.commitForRepository(webkit);
</span><span class="cx">             assert.equal(firstWebKitCommit.revision(), '191622');
</span><del>-            assert.equal(+firstWebKitCommit.time(), +new Date('2015-10-27T11:36:56.88Z'));
</del><ins>+            assert.equal(+firstWebKitCommit.time(), 1445945816878);
</ins><span class="cx"> 
</span><span class="cx">             let secondWebKitCommit = secondCommitSet.commitForRepository(webkit);
</span><span class="cx">             assert.equal(secondWebKitCommit.revision(), '192736');
</span><del>-            assert.equal(+secondWebKitCommit.time(), +new Date('2015-11-22T20:48:45.65Z'));
</del><ins>+            assert.equal(+secondWebKitCommit.time(), 1448225325650);
</ins><span class="cx">         });
</span><span class="cx">     });
</span><span class="cx"> 
</span><span class="lines">@@ -396,50 +396,4 @@
</span><span class="cx">             assert.strictEqual(buildRequests[7].order(), 3);
</span><span class="cx">         });
</span><span class="cx">     });
</span><del>-
-    it('should place build requests created by user before automatically created ones', () =&gt; {
-        const db = TestServer.database();
-        const someSize = 24 * 1024; // hashlib.sha256('1' * 24 * 1024).hexdigest()
-        const someHash = '3ffaa9e09f49d4d212582c092af2c1dcb2c9b52c8ca49c72ff99dcc5dc503a2b';
-        const otherSize = 42; // hashlib.sha256('2' * 42).hexdigest()
-        const otherHash = '66e378b3fb356925154435803c01afd10daebbf4a2edb583b34034aaca775a26';
-        return MockData.addMockData(db).then(() =&gt; Manifest.fetch()).then(() =&gt; {
-            return BuildRequest.fetchForTriggerable('build-webkit');
-        }).then((buildRequests) =&gt; {
-            assert.deepEqual(UploadedFile.all(), []);
-            assert.equal(buildRequests.length, 4);
-            const set0 = buildRequests[0].commitSet();
-            const set1 = buildRequests[1].commitSet();
-            assert.equal(buildRequests[2].commitSet(), set0);
-            assert.equal(buildRequests[3].commitSet(), set1);
-            assert.deepEqual(set0.customRoots(), []);
-            assert.deepEqual(set1.customRoots(), []);
-            return Promise.all([
-                db.insert('uploaded_files', {id: 1, filename: 'some-file.tar.gz', extension: '.tar.gz', size: someSize, sha256: someHash}),
-                db.insert('uploaded_files', {id: 2, filename: 'other-file.zip', extension: '.zip', size: otherSize, sha256: otherHash}),
-            ]).then(() =&gt; {
-                return db.insert('commit_set_relationships', {set: set0.id(), root_file: 1});
-            });
-        }).then(() =&gt; {
-            CommitSet.clearStaticMap();
-            BuildRequest.clearStaticMap();
-            return BuildRequest.fetchForTriggerable('build-webkit');
-        }).then((buildRequests) =&gt; {
-            const uploadedFiles = UploadedFile.all();
-            assert.equal(uploadedFiles.length, 1);
-
-            const someFile = UploadedFile.findById(1);
-            assert.equal(someFile.filename(), 'some-file.tar.gz');
-            assert.equal(someFile.size(), someSize);
-
-            assert.equal(buildRequests.length, 4);
-            const set0 = buildRequests[0].commitSet();
-            const set1 = buildRequests[1].commitSet();
-            assert.equal(buildRequests[2].commitSet(), set0);
-            assert.equal(buildRequests[3].commitSet(), set1);
-            assert.deepEqual(set0.customRoots(), [someFile]);
-            assert.deepEqual(set1.customRoots(), []);
-        });
-    });
-
</del><span class="cx"> });
</span></span></pre></div>
<a id="trunkWebsitesperfwebkitorgservertestsapicommitstestsjs"></a>
<div class="modfile"><h4>Modified: trunk/Websites/perf.webkit.org/server-tests/api-commits-tests.js (215202 => 215203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/perf.webkit.org/server-tests/api-commits-tests.js        2017-04-10 21:38:04 UTC (rev 215202)
+++ trunk/Websites/perf.webkit.org/server-tests/api-commits-tests.js        2017-04-10 21:43:11 UTC (rev 215203)
</span><span class="lines">@@ -2,7 +2,6 @@
</span><span class="cx"> 
</span><span class="cx"> const assert = require('assert');
</span><span class="cx"> 
</span><del>-const MockData = require('./resources/mock-data.js');
</del><span class="cx"> const TestServer = require('./resources/test-server.js');
</span><span class="cx"> const addSlaveForReport = require('./resources/common-operations.js').addSlaveForReport;
</span><span class="cx"> const prepareServerTest = require('./resources/common-operations.js').prepareServerTest;
</span><span class="lines">@@ -214,7 +213,7 @@
</span><span class="cx">             });
</span><span class="cx">         });
</span><span class="cx"> 
</span><del>-        it(&quot;should return the latest commit&quot;, () =&gt; {
</del><ins>+        it(&quot;should return the oldest commit&quot;, () =&gt; {
</ins><span class="cx">             const remote = TestServer.remoteAPI();
</span><span class="cx">             return addSlaveForReport(subversionCommits).then(() =&gt; {
</span><span class="cx">                 return remote.postJSONWithStatus('/api/report-commits/', subversionCommits);
</span><span class="lines">@@ -239,50 +238,6 @@
</span><span class="cx">                 assert.equal(result['commits'][0]['revision'], systemVersionCommits['commits'][0]['revision']);
</span><span class="cx">             });
</span><span class="cx">         });
</span><del>-
-        it(&quot;should return the latest commit for a given platform&quot;, () =&gt; {
-            const mockDataCommitReports = {
-                &quot;slaveName&quot;: &quot;someSlave&quot;,
-                &quot;slavePassword&quot;: &quot;somePassword&quot;,
-                &quot;commits&quot;: [
-                    {
-                        &quot;repository&quot;: &quot;WebKit&quot;,
-                        &quot;revision&quot;: &quot;191622&quot;,
-                        &quot;time&quot;: &quot;2015-10-27T11:36:56.88Z&quot;,
-                        &quot;author&quot;: {&quot;account&quot;: &quot;calvaris@igalia.com&quot;},
-                        &quot;message&quot;: &quot;a message&quot;,
-                    },
-                    {
-                        &quot;repository&quot;: &quot;WebKit&quot;,
-                        &quot;revision&quot;: &quot;192736&quot;,
-                        &quot;time&quot;: &quot;2015-11-22T20:48:45.65Z&quot;,
-                        &quot;author&quot;: {&quot;account&quot;: &quot;aestes@apple.com&quot;},
-                        &quot;message&quot;: &quot;some message&quot;,
-                    },
-                    {
-                        &quot;repository&quot;: &quot;WebKit&quot;,
-                        &quot;revision&quot;: &quot;192903&quot;,
-                        &quot;time&quot;: &quot;2015-12-01T21:14:46.99Z&quot;,
-                        &quot;author&quot;: {&quot;account&quot;: &quot;darin@apple.com&quot;},
-                        &quot;message&quot;: &quot;another message&quot;,
-                    }
-                ]
-            }
-            const remote = TestServer.remoteAPI();
-            return MockData.addMockData(TestServer.database()).then(() =&gt; {
-                return addSlaveForReport(mockDataCommitReports);
-            }).then(() =&gt; {
-                return remote.postJSONWithStatus('/api/report-commits/', mockDataCommitReports);
-            }).then(() =&gt; {
-                return remote.getJSON('/api/commits/WebKit/latest?platform=' + MockData.somePlatformId());
-            }).then((result) =&gt; {
-                assert.equal(result['status'], 'OK');
-                assert.equal(result['commits'].length, 1);
-                const commit = result['commits'][0];
-                assert.equal(commit['revision'], '192736');
-                assert.equal(commit['time'], +new Date('2015-11-22T20:48:45.65Z'));
-            });
-        });
</del><span class="cx">     });
</span><span class="cx"> 
</span><span class="cx">     describe('/api/commits/&lt;repository&gt;/last-reported', () =&gt; {
</span></span></pre></div>
<a id="trunkWebsitesperfwebkitorgservertestsprivilegedapicreatetestgrouptestsjs"></a>
<div class="modfile"><h4>Modified: trunk/Websites/perf.webkit.org/server-tests/privileged-api-create-test-group-tests.js (215202 => 215203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/perf.webkit.org/server-tests/privileged-api-create-test-group-tests.js        2017-04-10 21:38:04 UTC (rev 215202)
+++ trunk/Websites/perf.webkit.org/server-tests/privileged-api-create-test-group-tests.js        2017-04-10 21:43:11 UTC (rev 215203)
</span><span class="lines">@@ -1,10 +1,9 @@
</span><span class="cx"> 'use strict';
</span><span class="cx"> 
</span><del>-const assert = require('assert');
</del><ins>+let assert = require('assert');
</ins><span class="cx"> 
</span><del>-const MockData = require('./resources/mock-data.js');
-const TestServer = require('./resources/test-server.js');
-const TemporaryFile = require('./resources/temporary-file.js').TemporaryFile;
</del><ins>+let MockData = require('./resources/mock-data.js');
+let TestServer = require('./resources/test-server.js');
</ins><span class="cx"> const addSlaveForReport = require('./resources/common-operations.js').addSlaveForReport;
</span><span class="cx"> const prepareServerTest = require('./resources/common-operations.js').prepareServerTest;
</span><span class="cx"> 
</span><span class="lines">@@ -117,7 +116,6 @@
</span><span class="cx"> 
</span><span class="cx"> describe('/privileged-api/create-test-group', function () {
</span><span class="cx">     prepareServerTest(this);
</span><del>-    TemporaryFile.inject();
</del><span class="cx"> 
</span><span class="cx">     it('should return &quot;InvalidName&quot; on an empty request', () =&gt; {
</span><span class="cx">         return PrivilegedAPI.sendRequest('create-test-group', {}).then((content) =&gt; {
</span><span class="lines">@@ -264,18 +262,6 @@
</span><span class="cx">         });
</span><span class="cx">     });
</span><span class="cx"> 
</span><del>-    it('should return &quot;InvalidUploadedFile&quot; when revision sets contains an invalid file ID', () =&gt; {
-        return addTriggerableAndCreateTask('some task').then((taskId) =&gt; {
-            const webkit = Repository.all().find((repository) =&gt; repository.name() == 'WebKit');
-            const revisionSets = [{[webkit.id()]: '191622', 'customRoots': ['1']}, {[webkit.id()]: '1'}];
-            return PrivilegedAPI.sendRequest('create-test-group', {name: 'test', task: taskId, revisionSets}).then((content) =&gt; {
-                assert(false, 'should never be reached');
-            }, (error) =&gt; {
-                assert.equal(error, 'InvalidUploadedFile');
-            });
-        });
-    });
-
</del><span class="cx">     it('should return &quot;InvalidRepository&quot; when a revision set uses a repository name instead of a repository id', () =&gt; {
</span><span class="cx">         return addTriggerableAndCreateTask('some task').then((taskId) =&gt; {
</span><span class="cx">             return PrivilegedAPI.sendRequest('create-test-group', {name: 'test', task: taskId, revisionSets: [{'WebKit': '191622'}, {}]}).then((content) =&gt; {
</span><span class="lines">@@ -447,81 +433,4 @@
</span><span class="cx">         });
</span><span class="cx">     });
</span><span class="cx"> 
</span><del>-    it('should create a test group with a custom root', () =&gt; {
-        return addTriggerableAndCreateTask('some task').then((taskId) =&gt; {
-            let insertedGroupId;
-            const webkit = Repository.all().filter((repository) =&gt; repository.name() == 'WebKit')[0];
-            const macos = Repository.all().filter((repository) =&gt; repository.name() == 'macOS')[0];
-            let uploadedFile;
-            return TemporaryFile.makeTemporaryFile('some.dat', 'some content').then((stream) =&gt; {
-                return PrivilegedAPI.sendRequest('upload-file', {newFile: stream}, {useFormData: true});
-            }).then((response) =&gt; {
-                uploadedFile = response['uploadedFile'];
-                const revisionSets = [{[webkit.id()]: '191622', [macos.id()]: '15A284'},
-                    {[webkit.id()]: '191622', [macos.id()]: '15A284', 'customRoots': [uploadedFile['id']]}];
-                return PrivilegedAPI.sendRequest('create-test-group', {name: 'test', task: taskId, repetitionCount: 2, revisionSets}).then((content) =&gt; {
-                    insertedGroupId = content['testGroupId'];
-                    return TestGroup.fetchByTask(taskId);
-                });
-            }).then((testGroups) =&gt; {
-                assert.equal(testGroups.length, 1);
-                const group = testGroups[0];
-                assert.equal(group.id(), insertedGroupId);
-                assert.equal(group.repetitionCount(), 2);
-                const requests = group.buildRequests();
-                assert.equal(requests.length, 4);
-
-                const set0 = requests[0].commitSet();
-                const set1 = requests[1].commitSet();
-                assert.equal(requests[2].commitSet(), set0);
-                assert.equal(requests[3].commitSet(), set1);
-                assert.deepEqual(Repository.sortByNamePreferringOnesWithURL(set0.repositories()), [webkit, macos]);
-                assert.deepEqual(set0.customRoots(), []);
-                assert.deepEqual(Repository.sortByNamePreferringOnesWithURL(set1.repositories()), [webkit, macos]);
-                assert.deepEqual(set1.customRoots(), [UploadedFile.ensureSingleton(uploadedFile['id'], uploadedFile)]);
-                assert.equal(set0.revisionForRepository(webkit), '191622');
-                assert.equal(set0.revisionForRepository(webkit), set1.revisionForRepository(webkit));
-                assert.equal(set0.commitForRepository(webkit), set1.commitForRepository(webkit));
-                assert.equal(set0.revisionForRepository(macos), '15A284');
-                assert.equal(set0.commitForRepository(macos), set1.commitForRepository(macos));
-                assert.equal(set0.revisionForRepository(macos), set1.revisionForRepository(macos));
-                assert(!set0.equals(set1));
-            });
-        });
-    });
-
-    it('should create a test group with an analysis task', () =&gt; {
-        let insertedGroupId;
-        let webkit;
-        return addTriggerableAndCreateTask('some task').then(() =&gt; {
-            webkit = Repository.all().filter((repository) =&gt; repository.name() == 'WebKit')[0];
-            const revisionSets = [{[webkit.id()]: '191622'}, {[webkit.id()]: '191623'}];
-            return PrivilegedAPI.sendRequest('create-test-group',
-                {name: 'test', taskName: 'other task', platform: MockData.somePlatformId(), test: MockData.someTestId(), revisionSets});
-        }).then((result) =&gt; {
-            insertedGroupId = result['testGroupId'];
-            return Promise.all([AnalysisTask.fetchById(result['taskId']), TestGroup.fetchByTask(result['taskId'])]);
-        }).then((result) =&gt; {
-            const [analysisTask, testGroups] = result;
-
-            assert.equal(analysisTask.name(), 'other task');
-
-            assert.equal(testGroups.length, 1);
-            const group = testGroups[0];
-            assert.equal(group.id(), insertedGroupId);
-            assert.equal(group.repetitionCount(), 1);
-            const requests = group.buildRequests();
-            assert.equal(requests.length, 2);
-
-            const set0 = requests[0].commitSet();
-            const set1 = requests[1].commitSet();
-            assert.deepEqual(set0.repositories(), [webkit]);
-            assert.deepEqual(set0.customRoots(), []);
-            assert.deepEqual(set1.repositories(), [webkit]);
-            assert.deepEqual(set1.customRoots(), []);
-            assert.equal(set0.revisionForRepository(webkit), '191622');
-            assert.equal(set1.revisionForRepository(webkit), '191623');
-        });
-    });
-
</del><span class="cx"> });
</span></span></pre></div>
<a id="trunkWebsitesperfwebkitorgservertestsresourcesmockdatajs"></a>
<div class="modfile"><h4>Modified: trunk/Websites/perf.webkit.org/server-tests/resources/mock-data.js (215202 => 215203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/perf.webkit.org/server-tests/resources/mock-data.js        2017-04-10 21:38:04 UTC (rev 215202)
+++ trunk/Websites/perf.webkit.org/server-tests/resources/mock-data.js        2017-04-10 21:43:11 UTC (rev 215203)
</span><span class="lines">@@ -37,19 +37,12 @@
</span><span class="cx">             db.insert('triggerable_repositories', {repository: this.macosRepositoryId(), group: 2001}),
</span><span class="cx">             db.insert('triggerable_repositories', {repository: this.webkitRepositoryId(), group: 2001}),
</span><span class="cx">             db.insert('commits', {id: 87832, repository: this.macosRepositoryId(), revision: '10.11 15A284'}),
</span><del>-            db.insert('commits', {id: 93116, repository: this.webkitRepositoryId(), revision: '191622', time: '2015-10-27T11:36:56.88Z'}),
-            db.insert('commits', {id: 96336, repository: this.webkitRepositoryId(), revision: '192736', time: '2015-11-22T20:48:45.65Z'}),
-            db.insert('commits', {id: 96629, repository: this.webkitRepositoryId(), revision: '192903', time: '2015-12-01T21:14:46.99Z'}),
-            db.insert('builds', {id: 901, number: '901', time: '2015-10-27T12:05:27.1Z'}),
-            db.insert('builds', {id: 902, number: '902', time: '2015-10-27T12:06:54.2Z'}),
-            db.insert('build_commits', {commit_build: 901, build_commit: 93116}),
-            db.insert('build_commits', {commit_build: 902, build_commit: 96336}),
</del><ins>+            db.insert('commits', {id: 93116, repository: this.webkitRepositoryId(), revision: '191622', time: (new Date(1445945816878)).toISOString()}),
+            db.insert('commits', {id: 96336, repository: this.webkitRepositoryId(), revision: '192736', time: (new Date(1448225325650)).toISOString()}),
</ins><span class="cx">             db.insert('platforms', {id: MockData.somePlatformId(), name: 'some platform'}),
</span><span class="cx">             db.insert('tests', {id: MockData.someTestId(), name: 'some test'}),
</span><del>-            db.insert('test_metrics', {id: 300, test: MockData.someTestId(), name: 'some metric'}),
-            db.insert('test_configurations', {id: 301, metric: 300, platform: MockData.somePlatformId(), type: 'current'}),
-            db.insert('test_runs', {id: 801, config: 301, build: 901, mean_cache: 101}),
-            db.insert('test_runs', {id: 802, config: 301, build: 902, mean_cache: 92}),
</del><ins>+            db.insert('test_metrics', {id: 300, test: 200, name: 'some metric'}),
+            db.insert('test_configurations', {id: 301, metric: 300, platform: 65, type: 'current'}),
</ins><span class="cx">             db.insert('commit_sets', {id: 401}),
</span><span class="cx">             db.insert('commit_set_relationships', {set: 401, commit: 87832}),
</span><span class="cx">             db.insert('commit_set_relationships', {set: 401, commit: 93116}),
</span><span class="lines">@@ -56,9 +49,7 @@
</span><span class="cx">             db.insert('commit_sets', {id: 402}),
</span><span class="cx">             db.insert('commit_set_relationships', {set: 402, commit: 87832}),
</span><span class="cx">             db.insert('commit_set_relationships', {set: 402, commit: 96336}),
</span><del>-            db.insert('analysis_tasks', {id: 500, platform: 65, metric: 300, name: 'some task',
-                start_run: 801, start_run_time: '2015-10-27T12:05:27.1Z',
-                end_run: 801, end_run_time: '2015-10-27T12:05:27.1Z'}),
</del><ins>+            db.insert('analysis_tasks', {id: 500, platform: 65, metric: 300, name: 'some task'}),
</ins><span class="cx">             db.insert('analysis_test_groups', {id: 600, task: 500, name: 'some test group'}),
</span><span class="cx">             db.insert('build_requests', {id: 700, status: statusList[0], triggerable: 1000, repository_group: 2001, platform: 65, test: 200, group: 600, order: 0, commit_set: 401}),
</span><span class="cx">             db.insert('build_requests', {id: 701, status: statusList[1], triggerable: 1000, repository_group: 2001, platform: 65, test: 200, group: 600, order: 1, commit_set: 402}),
</span></span></pre></div>
<a id="trunkWebsitesperfwebkitorgtoolsjsremotejs"></a>
<div class="modfile"><h4>Modified: trunk/Websites/perf.webkit.org/tools/js/remote.js (215202 => 215203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/perf.webkit.org/tools/js/remote.js        2017-04-10 21:38:04 UTC (rev 215202)
+++ trunk/Websites/perf.webkit.org/tools/js/remote.js        2017-04-10 21:43:11 UTC (rev 215203)
</span><span class="lines">@@ -1,13 +1,11 @@
</span><span class="cx"> 'use strict';
</span><span class="cx"> 
</span><del>-const assert = require('assert');
-const http = require('http');
-const https = require('https');
-const querystring = require('querystring');
-const CommonRemoteAPI = require('../../public/shared/common-remote.js').CommonRemoteAPI;
</del><ins>+let assert = require('assert');
+let http = require('http');
+let https = require('https');
+let querystring = require('querystring');
+let CommonRemoteAPI = require('../../public/shared/common-remote.js').CommonRemoteAPI;
</ins><span class="cx"> 
</span><del>-global.FormData = require('form-data');
-
</del><span class="cx"> class NodeRemoteAPI extends CommonRemoteAPI {
</span><span class="cx">     constructor(server)
</span><span class="cx">     {
</span></span></pre></div>
<a id="trunkWebsitesperfwebkitorgunittestsanalysistasktestsjs"></a>
<div class="modfile"><h4>Modified: trunk/Websites/perf.webkit.org/unit-tests/analysis-task-tests.js (215202 => 215203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/perf.webkit.org/unit-tests/analysis-task-tests.js        2017-04-10 21:38:04 UTC (rev 215202)
+++ trunk/Websites/perf.webkit.org/unit-tests/analysis-task-tests.js        2017-04-10 21:43:11 UTC (rev 215203)
</span><span class="lines">@@ -15,6 +15,7 @@
</span><span class="cx">                 'bugs': [],
</span><span class="cx">                 'buildRequestCount': '14',
</span><span class="cx">                 'finishedBuildRequestCount': '6',
</span><ins>+                'category': 'identified',
</ins><span class="cx">                 'causes': [
</span><span class="cx">                     '105975'
</span><span class="cx">                 ],
</span><span class="lines">@@ -23,10 +24,10 @@
</span><span class="cx">                 'endRunTime': 1454515020303,
</span><span class="cx">                 'fixes': [],
</span><span class="cx">                 'id': '1082',
</span><del>-                'metric': MockModels.someMetric.id(),
</del><ins>+                'metric': '2884',
</ins><span class="cx">                 'name': 'Potential 1.2% regression between 2016-02-02 20:20 and 02-03 15:57',
</span><span class="cx">                 'needed': null,
</span><del>-                'platform': MockModels.somePlatform.id(),
</del><ins>+                'platform': '65',
</ins><span class="cx">                 'result': 'regression',
</span><span class="cx">                 'segmentationStrategy': '1',
</span><span class="cx">                 'startRun': '37117949',
</span><span class="lines">@@ -52,38 +53,6 @@
</span><span class="cx">     };
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-function sampleCustomAnalysisTask()
-{
-    return {
-        'analysisTasks': [
-            {
-                'id': '1000',
-                'createdAt': 1454594330000,
-                'author': null,
-                'buildRequestCount': '0',
-                'finishedBuildRequestCount': '0',
-                'bugs': [],
-                'causes': [ ],
-                'fixes': [],
-                'startRun': null,
-                'startRunTime': null,
-                'endRun': null,
-                'endRunTime': null,
-                'metric': null,
-                'name': 'Potential 1.2% regression between 2016-02-02 20:20 and 02-03 15:57',
-                'needed': null,
-                'platform': null,
-                'result': null,
-                'segmentationStrategy': null,
-                'testRangeStragegy': null,
-            }
-        ],
-        'commits': [],
-        'bugs': [],
-        'status': 'OK'
-    };
-}
-
</del><span class="cx"> function measurementCluster()
</span><span class="cx"> {
</span><span class="cx">     return {
</span><span class="lines">@@ -151,43 +120,6 @@
</span><span class="cx">     MockModels.inject();
</span><span class="cx">     let requests = MockRemoteAPI.inject();
</span><span class="cx"> 
</span><del>-    function loadAnalysisTasks(rawData)
-    {
-        AnalysisTask._constructAnalysisTasksFromRawData(rawData);
-        return Promise.resolve();
-    }
-
-    describe('findByPlatformAndMetric', () =&gt; {
-        it('should return an empty array when there are no analysis tasks', () =&gt; {
-            assert.deepEqual(AnalysisTask.findByPlatformAndMetric(MockModels.somePlatform, MockModels.someMetric), []);
-        });
-
-        it('should return an array containing the matching non-custom analysis tasks', () =&gt; {
-            return loadAnalysisTasks(sampleAnalysisTask()).then(() =&gt; {
-                return loadAnalysisTasks(sampleCustomAnalysisTask());
-            }).then(() =&gt; {
-                const tasks = AnalysisTask.findByPlatformAndMetric(MockModels.somePlatform.id(), MockModels.someMetric.id());
-                assert.equal(tasks.length, 1);
-                const task = tasks[0];
-                assert.equal(task.id(), 1082);
-                assert.equal(task.isCustom(), false);
-                assert.equal(task.hasResults(), true);
-                assert.equal(task.hasPendingRequests(), true);
-                assert.equal(task.requestLabel(), '6 of 14');
-                assert.equal(task.startMeasurementId(), 37117949);
-                assert.equal(task.endMeasurementId(), 37253448);
-                assert.equal(task.author(), '');
-                assert.deepEqual(task.bugs(), []);
-                assert.deepEqual(task.causes(), [CommitLog.findById(105975)]);
-                assert.deepEqual(task.fixes(), []);
-                assert.deepEqual(task.platform(), MockModels.somePlatform);
-                assert.deepEqual(task.metric(), MockModels.someMetric);
-                assert.deepEqual(task.changeType(), 'regression');
-                assert.deepEqual(task.category(), 'investigated');
-            });
-        });
-    });
-
</del><span class="cx">     describe('fetchAll', () =&gt; {
</span><span class="cx">         it('should request all analysis tasks', () =&gt; {
</span><span class="cx">             let callCount = 0;
</span></span></pre></div>
<a id="trunkWebsitesperfwebkitorgunittestsbuildrequesttestsjs"></a>
<div class="modfile"><h4>Modified: trunk/Websites/perf.webkit.org/unit-tests/build-request-tests.js (215202 => 215203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/perf.webkit.org/unit-tests/build-request-tests.js        2017-04-10 21:38:04 UTC (rev 215202)
+++ trunk/Websites/perf.webkit.org/unit-tests/build-request-tests.js        2017-04-10 21:43:11 UTC (rev 215203)
</span><span class="lines">@@ -23,12 +23,10 @@
</span><span class="cx">         }],
</span><span class="cx">         &quot;commitSets&quot;: [{
</span><span class="cx">             &quot;id&quot;: &quot;4255&quot;,
</span><del>-            &quot;commits&quot;: [&quot;87832&quot;, &quot;93116&quot;],
-            &quot;customRoots&quot;: [],
</del><ins>+            &quot;commits&quot;: [&quot;87832&quot;, &quot;93116&quot;]
</ins><span class="cx">         }, {
</span><span class="cx">             &quot;id&quot;: &quot;4256&quot;,
</span><del>-            &quot;commits&quot;: [&quot;87832&quot;, &quot;96336&quot;],
-            &quot;customRoots&quot;: [],
</del><ins>+            &quot;commits&quot;: [&quot;87832&quot;, &quot;96336&quot;]
</ins><span class="cx">         }],
</span><span class="cx">         &quot;commits&quot;: [{
</span><span class="cx">             &quot;id&quot;: &quot;87832&quot;,
</span><span class="lines">@@ -51,7 +49,6 @@
</span><span class="cx">             &quot;revision&quot;: &quot;192736&quot;,
</span><span class="cx">             &quot;time&quot;: 1448225325650
</span><span class="cx">         }],
</span><del>-        &quot;uploadedFiles&quot;: [],
</del><span class="cx">         &quot;status&quot;: &quot;OK&quot;
</span><span class="cx">     };
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkWebsitesperfwebkitorgunittestsbuildbotsyncertestsjs"></a>
<div class="modfile"><h4>Modified: trunk/Websites/perf.webkit.org/unit-tests/buildbot-syncer-tests.js (215202 => 215203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/perf.webkit.org/unit-tests/buildbot-syncer-tests.js        2017-04-10 21:38:04 UTC (rev 215202)
+++ trunk/Websites/perf.webkit.org/unit-tests/buildbot-syncer-tests.js        2017-04-10 21:43:11 UTC (rev 215203)
</span><span class="lines">@@ -192,7 +192,7 @@
</span><span class="cx">     assert(platform instanceof Platform);
</span><span class="cx">     assert(test instanceof Test);
</span><span class="cx"> 
</span><del>-    let commitSet = CommitSet.ensureSingleton('4197', {customRoots: [], commits: [
</del><ins>+    let commitSet = CommitSet.ensureSingleton('4197', {commits: [
</ins><span class="cx">         {'id': '111127', 'time': 1456955807334, 'repository': MockModels.webkit, 'revision': '197463'},
</span><span class="cx">         {'id': '111237', 'time': 1456931874000, 'repository': MockModels.sharedRepository, 'revision': '80229'},
</span><span class="cx">         {'id': '88930', 'time': 0, 'repository': MockModels.ios, 'revision': '13A452'},
</span></span></pre></div>
<a id="trunkWebsitesperfwebkitorgunitteststestgroupstestsjs"></a>
<div class="modfile"><h4>Modified: trunk/Websites/perf.webkit.org/unit-tests/test-groups-tests.js (215202 => 215203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/perf.webkit.org/unit-tests/test-groups-tests.js        2017-04-10 21:38:04 UTC (rev 215202)
+++ trunk/Websites/perf.webkit.org/unit-tests/test-groups-tests.js        2017-04-10 21:43:11 UTC (rev 215203)
</span><span class="lines">@@ -15,8 +15,9 @@
</span><span class="cx">             &quot;createdAt&quot;: 1458688514000,
</span><span class="cx">             &quot;hidden&quot;: false,
</span><span class="cx">             &quot;buildRequests&quot;: [&quot;16985&quot;, &quot;16986&quot;, &quot;16987&quot;, &quot;16988&quot;, &quot;16989&quot;, &quot;16990&quot;, &quot;16991&quot;, &quot;16992&quot;],
</span><del>-            &quot;commitSets&quot;: [&quot;4255&quot;, &quot;4256&quot;],
-        }],
</del><ins>+            &quot;commitSets&quot;: [&quot;4255&quot;, &quot;4256&quot;, &quot;4255&quot;, &quot;4256&quot;, &quot;4255&quot;, &quot;4256&quot;, &quot;4255&quot;, &quot;4256&quot;]
+        }
+        ],
</ins><span class="cx">         &quot;buildRequests&quot;: [{
</span><span class="cx">             &quot;id&quot;: &quot;16985&quot;,
</span><span class="cx">             &quot;triggerable&quot;: &quot;3&quot;,
</span><span class="lines">@@ -66,16 +67,16 @@
</span><span class="cx">             &quot;url&quot;: null,
</span><span class="cx">             &quot;build&quot;: null,
</span><span class="cx">             &quot;createdAt&quot;: 1458688514000
</span><del>-        }],
</del><ins>+        }
+        ],
</ins><span class="cx">         &quot;commitSets&quot;: [{
</span><span class="cx">             &quot;id&quot;: &quot;4255&quot;,
</span><del>-            &quot;commits&quot;: [&quot;87832&quot;, &quot;93116&quot;],
-            &quot;customRoots&quot;: [],
</del><ins>+            &quot;commits&quot;: [&quot;87832&quot;, &quot;93116&quot;]
</ins><span class="cx">         }, {
</span><span class="cx">             &quot;id&quot;: &quot;4256&quot;,
</span><del>-            &quot;commits&quot;: [&quot;87832&quot;, &quot;96336&quot;],
-            &quot;customRoots&quot;: [],
-        }],
</del><ins>+            &quot;commits&quot;: [&quot;87832&quot;, &quot;96336&quot;]
+        }
+        ],
</ins><span class="cx">         &quot;commits&quot;: [{
</span><span class="cx">             &quot;id&quot;: &quot;87832&quot;,
</span><span class="cx">             &quot;repository&quot;: &quot;9&quot;,
</span><span class="lines">@@ -96,8 +97,8 @@
</span><span class="cx">             &quot;repository&quot;: &quot;11&quot;,
</span><span class="cx">             &quot;revision&quot;: &quot;192736&quot;,
</span><span class="cx">             &quot;time&quot;: 1448225325650
</span><del>-        }],
-        &quot;uploadedFiles&quot;: [],
</del><ins>+        }
+        ],
</ins><span class="cx">         &quot;status&quot;: &quot;OK&quot;
</span><span class="cx">     };
</span><span class="cx"> }
</span></span></pre>
</div>
</div>

</body>
</html>