.:
authorrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 10 Apr 2017 21:43:11 +0000 (21:43 +0000)
committerrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 10 Apr 2017 21:43:11 +0000 (21:43 +0000)
Elftoolchain ar doesn't support response files
https://bugs.webkit.org/show_bug.cgi?id=170105

Patch by Ting-Wei Lan <lantw44@gmail.com> 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 r215202.
https://bugs.webkit.org/show_bug.cgi?id=170694

Committed incorrectly (Requested by rniwa on #webkit).

Reverted changeset:

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

Patch by Commit Queue <commit-queue@webkit.org> on 2017-04-10

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@215203 268f45cc-cd09-0410-ab3c-d52691b4dbfc

38 files changed:
ChangeLog
Websites/perf.webkit.org/ChangeLog
Websites/perf.webkit.org/ReadMe.md
Websites/perf.webkit.org/init-database.sql
Websites/perf.webkit.org/public/api/build-requests.php
Websites/perf.webkit.org/public/api/commits.php
Websites/perf.webkit.org/public/api/test-groups.php
Websites/perf.webkit.org/public/include/build-requests-fetcher.php
Websites/perf.webkit.org/public/include/commit-log-fetcher.php
Websites/perf.webkit.org/public/privileged-api/create-test-group.php
Websites/perf.webkit.org/public/privileged-api/upload-file.php
Websites/perf.webkit.org/public/v3/index.html
Websites/perf.webkit.org/public/v3/models/analysis-task.js
Websites/perf.webkit.org/public/v3/models/build-request.js
Websites/perf.webkit.org/public/v3/models/commit-log.js
Websites/perf.webkit.org/public/v3/models/commit-set.js
Websites/perf.webkit.org/public/v3/models/manifest.js
Websites/perf.webkit.org/public/v3/models/metric.js
Websites/perf.webkit.org/public/v3/models/test-group.js
Websites/perf.webkit.org/public/v3/models/triggerable.js
Websites/perf.webkit.org/public/v3/models/uploaded-file.js
Websites/perf.webkit.org/public/v3/pages/analysis-category-page.js
Websites/perf.webkit.org/public/v3/pages/analysis-task-page.js
Websites/perf.webkit.org/public/v3/pages/chart-pane-status-view.js
Websites/perf.webkit.org/public/v3/pages/chart-pane.js
Websites/perf.webkit.org/public/v3/pages/create-analysis-task-page.js
Websites/perf.webkit.org/public/v3/pages/page-router.js
Websites/perf.webkit.org/server-tests/api-build-requests-tests.js
Websites/perf.webkit.org/server-tests/api-commits-tests.js
Websites/perf.webkit.org/server-tests/privileged-api-create-test-group-tests.js
Websites/perf.webkit.org/server-tests/resources/mock-data.js
Websites/perf.webkit.org/tools/js/remote.js
Websites/perf.webkit.org/unit-tests/analysis-task-tests.js
Websites/perf.webkit.org/unit-tests/build-request-tests.js
Websites/perf.webkit.org/unit-tests/buildbot-syncer-tests.js
Websites/perf.webkit.org/unit-tests/test-groups-tests.js
public/v3/components/custom-analysis-task-configurator.js [deleted file]
public/v3/components/instant-file-uploader.js [deleted file]

index 5ea7552b7a1b4ae0932f46454911b05932f8fb07..0e247bd49bea62f4976bacdf86395e5eafecafc3 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,237 +1,3 @@
-2017-04-10  Ryosuke Niwa  <rniwa@webkit.org>
-
-        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 "baseline", and the second configuration is referred as "comparison" 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
-        "comparison" 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 "selected" 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 "baseline" and "comparison" commit sets. Pretend "comparison" 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 "baseline" and "comparison".
-        (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 "baseline"
-        or "comparison" configurations of CustomAnalysisTaskConfigurator. It's "instant" 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 "comparison"
-        configuration when the uploader for "baseline" configuration dipsatches "uploadedFile" action to automatically
-        mirror the newly uploaded custom root to "comparision" 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/<repository-name>/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/<repository-name>/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.
-
 2017-04-08  Ting-Wei Lan  <lantw44@gmail.com>
 
         Elftoolchain ar doesn't support response files
index c362dc8784debd34e3de5754adec3fc948633d40..bd8921cbf5a1e9352202d385ae5d74ace5d029e9 100644 (file)
@@ -1,3 +1,16 @@
+2017-04-10  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r215202.
+        https://bugs.webkit.org/show_bug.cgi?id=170694
+
+        Committed incorrectly (Requested by rniwa on #webkit).
+
+        Reverted changeset:
+
+        "Add the UI for scheduling a A/B testing with a custom root"
+        https://bugs.webkit.org/show_bug.cgi?id=170622
+        http://trac.webkit.org/changeset/215202
+
 2017-04-10  Ryosuke Niwa  <rniwa@webkit.org>
 
         Add the UI for scheduling a A/B testing with a custom root
index f2ae759d8d596dba9efc480029fb0ac8829486c1..f02c738a8fcaa435309834f22130342db8d30fc7 100644 (file)
@@ -71,11 +71,11 @@ Run `database/init-database.sql` in psql as `webkit-perf-db-user`:
 
 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).
 
-- 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=<path to backup directory>`
+- Making the fullbackup of the database: `/Applications/Server.app/Contents/ServerRoot/usr/bin/pg_dump -h localhost webkit-perf-db --format=directory --file=<path to backup directory> --jobs=4 --no-owner --compress=7`
 
-- 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=<path to backup directory>`
+- 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=<path to backup directory> --jobs=4 --no-owner --compress=7 --exclude-table=run_iterations`
 
-- 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 <path to backup directory>`
+- 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 <path to backup directory> --dbname=webkit-perf-db`
     
 ## Configuring Apache
 
@@ -88,7 +88,7 @@ Use `pg_dump` and `pg_restore` to backup and restore the database. If you're rep
 
 ### Instructions if you're not using Server.app
 
- - Edit `/private/etc/apache2/httpd.conf`
+ - Edit /private/etc/apache2/httpd.conf
 
      1. Change DocumentRoot to `/Volumes/Data/perf.webkit.org/public/`
      2. Uncomment `LoadModule php5_module libexec/apache2/libphp5.so`
index 8a153e9f28c5fbf11cd98d803763e052ddcc058d..a448cbf8a358b940b70935ff333aac7271b7d626 100644 (file)
@@ -204,8 +204,8 @@ CREATE TABLE analysis_tasks (
     task_segmentation integer REFERENCES analysis_strategies,
     task_test_range integer REFERENCES analysis_strategies,
     task_created_at timestamp NOT NULL DEFAULT (CURRENT_TIMESTAMP AT TIME ZONE 'UTC'),
-    task_platform integer REFERENCES platforms,
-    task_metric integer REFERENCES test_metrics,
+    task_platform integer REFERENCES platforms NOT NULL,
+    task_metric integer REFERENCES test_metrics NOT NULL,
     task_start_run integer REFERENCES test_runs,
     task_start_run_time timestamp,
     task_end_run integer REFERENCES test_runs,
@@ -213,13 +213,8 @@ CREATE TABLE analysis_tasks (
     task_result analysis_task_result_type,
     task_needed boolean,
     CONSTRAINT analysis_task_should_be_unique_for_range UNIQUE(task_start_run, task_end_run),
-    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)));
+    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)));
 
 CREATE TABLE task_commits (
     taskcommit_task integer NOT NULL REFERENCES analysis_tasks ON DELETE CASCADE,
@@ -285,9 +280,7 @@ CREATE TABLE commit_sets (
 
 CREATE TABLE commit_set_relationships (
     commitset_set integer REFERENCES commit_sets NOT NULL,
-    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));
+    commitset_commit integer REFERENCES commits NOT NULL);
 
 CREATE TYPE build_request_status_type as ENUM ('pending', 'scheduled', 'running', 'failed', 'completed', 'canceled');
 CREATE TABLE build_requests (
index 76b9c86d3bb42f95a72eba34764ba6a369256b04..4f3218d478c8044984c2eca717da4199f817b17c 100644 (file)
@@ -35,7 +35,6 @@ function main($id, $path, $post_data) {
         'buildRequests' => $resolve_id ? $requests_fetcher->results_with_resolved_ids() : $requests_fetcher->results(),
         'commitSets' => $requests_fetcher->commit_sets(),
         'commits' => $requests_fetcher->commits(),
-        'uploadedFiles' => $requests_fetcher->uploaded_files(),
     ));
 }
 
index 25951627fba59c4db067e7e8b52ab6db72342669..54316dbb7efb43c6aafa9fbdd5302cf0232a7507 100644 (file)
@@ -30,14 +30,7 @@ function main($paths) {
     } else if ($filter == 'oldest') {
         $commits = $fetcher->fetch_oldest($repository_id);
     } else if ($filter == 'latest') {
-        $platform_id = array_get($_GET, 'platform');
-        if ($platform_id) {
-            if (!is_numeric($platform_id))
-                exit_with_error('InvalidPlatform', array('platform' => $platform_id));
-            $platform_id = intval($platform_id);
-            $commits = $fetcher->fetch_latest_for_platform($repository_id, $platform_id);
-        } else
-            $commits = $fetcher->fetch_latest($repository_id);
+        $commits = $fetcher->fetch_latest($repository_id);
     } else if ($filter == 'last-reported') {
         $from = array_get($_GET, 'from');
         $to = array_get($_GET, 'to');
index 8cdd696e5c084b8035d39832bb39d0cb16f3c3d8..f48e0222feb906aa4561fe57cbac45cb5e8d70dd 100644 (file)
@@ -55,8 +55,7 @@ function main($path) {
     exit_with_success(array('testGroups' => $test_groups,
         'buildRequests' => $build_requests,
         'commitSets' => $build_requests_fetcher->commit_sets(),
-        'commits' => $build_requests_fetcher->commits(),
-        'uploadedFiles' => $build_requests_fetcher->uploaded_files()));
+        'commits' => $build_requests_fetcher->commits()));
 }
 
 function format_test_group($group_row) {
index 1f51cf60cc0500766d011a82d0e3224267f59a19..9a929b4b28ab495e61f5909b287c218cbdaa9c38 100644 (file)
@@ -1,7 +1,6 @@
 <?php
 
 require_once('test-path-resolver.php');
-require_once('uploaded-file-helpers.php');
 
 class BuildRequestsFetcher {
     function __construct($db) {
@@ -11,8 +10,6 @@ class BuildRequestsFetcher {
         $this->commits_by_id = array();
         $this->commits = array();
         $this->commit_sets_by_id = array();
-        $this->uploaded_files = array();
-        $this->uploaded_files_by_id = array();
     }
 
     function fetch_for_task($task_id) {
@@ -86,37 +83,27 @@ class BuildRequestsFetcher {
         return $requests;
     }
 
-    function commit_sets() { return $this->commit_sets; }
-    function commits() { return $this->commits; }
-    function uploaded_files() { return $this->uploaded_files; }
+    function commit_sets() {
+        return $this->commit_sets;
+    }
+
+    function commits() {
+        return $this->commits;
+    }
 
     private function fetch_commits_for_set_if_needed($commit_set_id, $resolve_ids) {
         if (array_key_exists($commit_set_id, $this->commit_sets_by_id))
             return;
 
         $commit_rows = $this->db->query_and_fetch_all('SELECT *
-            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));
+            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));
 
         $commit_ids = array();
-        $custom_roots = array();
-
         foreach ($commit_rows as $row) {
             $repository_id = $resolve_ids ? $row['repository_name'] : $row['repository_id'];
             $revision = $row['commit_revision'];
             $commit_time = $row['commit_time'];
-
-            $root_file_id = $row['commitset_root_file'];
-            if ($root_file_id) {
-                if (!array_key_exists($root_file_id, $this->uploaded_files_by_id)) {
-                    $uploaded_file_row = $this->db->select_first_row('uploaded_files', 'file', array('id' => $root_file_id));
-                    array_push($this->uploaded_files, format_uploaded_file($uploaded_file_row));
-                }
-                array_push($custom_roots, $root_file_id);
-                continue;
-            }
-
             array_push($commit_ids, $row['commit_id']);
 
             $commit_id = $row['commit_id'];
@@ -134,7 +121,7 @@ class BuildRequestsFetcher {
 
         $this->commit_sets_by_id[$commit_set_id] = TRUE;
 
-        array_push($this->commit_sets, array('id' => $commit_set_id, 'commits' => $commit_ids, 'customRoots' => $custom_roots));
+        array_push($this->commit_sets, array('id' => $commit_set_id, 'commits' => $commit_ids));
     }
 }
 
index 4421e1946d28e4c98680487ae893ea82cfe8ad04..7c15660bba12568e879dc6d7bbbcd234a89c37a2 100644 (file)
@@ -118,28 +118,6 @@ class CommitLogFetcher {
         return $this->format_single_commit($this->db->select_last_row('commits', 'commit', array('repository' => $repository_id), array('time', 'order')));
     }
 
-    function fetch_latest_for_platform($repository_id, $platform_id)
-    {
-        $query_result = $this->db->query_and_fetch_all("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;", 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->format_single_commit($query_result[0]);
-    }
-
     function fetch_last_reported($repository_id) {
         return $this->format_single_commit($this->db->select_last_row('commits', 'commit', array('repository' => $repository_id, 'reported' => true), array('time', 'order')));
     }
index a8c3705589ef374dc1da8a87a760af9f3048c8a3..656105036cc77f4bc13daaf73e08c1ec18c286af 100644 (file)
@@ -11,28 +11,16 @@ function main()
 
     $arguments = validate_arguments($data, array(
         'name' => '/.+/',
-        'task' => 'int?',
+        'task' => 'int',
         'repetitionCount' => 'int?',
     ));
     $name = $arguments['name'];
-    $task_id = array_get($arguments, 'task');
-    $task_name = array_get($data, 'taskName');
+    $task_id = $arguments['task'];
     $repetition_count = $arguments['repetitionCount'];
-    $platform_id = array_get($data, 'platform');
-    $test_id = array_get($data, 'test');
     $revision_set_list = array_get($data, 'revisionSets');
     $commit_sets_info = array_get($data, 'commitSets');
 
-    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+$/');
-    }
-
+    require_format('Task', $task_id, '/^\d+$/');
     if (!$revision_set_list && !$commit_sets_info)
         exit_with_error('InvalidCommitSets');
 
@@ -41,65 +29,39 @@ function main()
     else if ($repetition_count < 1)
         exit_with_error('InvalidRepetitionCount', array('repetitionCount' => $repetition_count));
 
-    $triggerable_id = NULL;
-    if ($task_id) {
-        $task = $db->select_first_row('analysis_tasks', 'task', array('id' => $task_id));
-        if (!$task)
-            exit_with_error('InvalidTask', array('task' => $task_id));
-        $triggerable = find_triggerable_for_task($db, $task_id);
-        if ($triggerable) {
-            $triggerable_id = $triggerable['id'];
-            if (!$platform_id && !$test_id) {
-                $platform_id = $triggerable['platform'];
-                $test_id = $triggerable['test'];
-            } else {
-                if ($triggerable['platform'] && $platform_id != $triggerable['platform'])
-                    exit_with_error('InconsistentPlatform', array('groupPlatform' => $platform_id, 'taskPlatform' => $triggerable['platform']));
-                if ($triggerable['test'] && $test_id != $triggerable['test'])
-                    exit_with_error('InconsistentTest', array('groupTest' => $test_id, 'taskTest' => $triggerable['test']));
-            }
-        }
-    } else if ($platform_id && $test_id) {
-        $triggerable_configuration = $db->select_first_row('triggerable_configurations', 'trigconfig',
-            array('test' => $test_id, 'platform' => $platform_id));
-        if ($triggerable_configuration)
-            $triggerable_id = $triggerable_configuration['trigconfig_triggerable'];
-    }
-
-    if (!$triggerable_id)
-        exit_with_error('TriggerableNotFoundForTask', array('task' => $task_id, 'platform' => $platform_id, 'test' => $test_id));
+    $task = $db->select_first_row('analysis_tasks', 'task', array('id' => $task_id));
+    if (!$task)
+        exit_with_error('InvalidTask', array('task' => $task_id));
+    $triggerable = find_triggerable_for_task($db, $task_id);
+    if (!$triggerable)
+        exit_with_error('TriggerableNotFoundForTask', array('task' => $task_id));
 
     if ($revision_set_list)
-        $commit_sets = commit_sets_from_revision_sets($db, $triggerable_id, $revision_set_list);
+        $commit_sets = commit_sets_from_revision_sets($db, $triggerable['id'], $revision_set_list);
     else // V2 UI compatibility
-        $commit_sets = ensure_commit_sets($db, $triggerable_id, $commit_sets_info);
+        $commit_sets = ensure_commit_sets($db, $triggerable['id'], $commit_sets_info);
 
     $db->begin_transaction();
 
-    if ($task_name)
-        $task_id = $db->insert_row('analysis_tasks', 'task', array('name' => $task_name, 'author' => $author));
-
     $configuration_list = array();
     foreach ($commit_sets as $commit_list) {
         $commit_set_id = $db->insert_row('commit_sets', 'commitset', array());
-        foreach ($commit_list['set'] as $commit_row) {
-            $commit_row['set'] = $commit_set_id;
-            $db->insert_row('commit_set_relationships', 'commitset', $commit_row, 'commit');
-        }
+        foreach ($commit_list['set'] as $commit)
+            $db->insert_row('commit_set_relationships', 'commitset', array('set' => $commit_set_id, 'commit' => $commit), 'commit');
         array_push($configuration_list, array('commit_set' => $commit_set_id, 'repository_group' => $commit_list['repository_group']));
     }
 
     $group_id = $db->insert_row('analysis_test_groups', 'testgroup',
-        array('task' => $task_id, 'name' => $name, 'author' => $author));
+        array('task' => $task['task_id'], 'name' => $name, 'author' => $author));
 
     $order = 0;
     for ($i = 0; $i < $repetition_count; $i++) {
         foreach ($configuration_list as $config) {
             $db->insert_row('build_requests', 'request', array(
-                'triggerable' => $triggerable_id,
+                'triggerable' => $triggerable['id'],
                 'repository_group' => $config['repository_group'],
-                'platform' => $platform_id,
-                'test' => $test_id,
+                'platform' => $triggerable['platform'],
+                'test' => $triggerable['test'],
                 'group' => $group_id,
                 'order' => $order,
                 'commit_set' => $config['commit_set'],));
@@ -109,7 +71,7 @@ function main()
 
     $db->commit_transaction();
 
-    exit_with_success(array('taskId' => $task_id, 'testGroupId' => $group_id));
+    exit_with_success(array('testGroupId' => $group_id));
 }
 
 function commit_sets_from_revision_sets($db, $triggerable_id, $revision_set_list)
@@ -125,23 +87,15 @@ function commit_sets_from_revision_sets($db, $triggerable_id, $revision_set_list
 
         $commit_set = array();
         $repository_list = array();
+
         foreach ($revision_set as $repository_id => $revision) {
-            if ($repository_id == 'customRoots') {
-                $file_id_list = $revision;
-                foreach ($file_id_list as $file_id) {
-                    if (!$db->select_first_row('uploaded_files', 'file', array('id' => $file_id)))
-                        exit_with_error('InvalidUploadedFile', array('file' => $file_id));
-                    array_push($commit_set, array('root_file' => $file_id));
-                }
-                continue;
-            }
             if (!is_numeric($repository_id))
                 exit_with_error('InvalidRepository', array('repository' => $repository_id));
             $commit = $db->select_first_row('commits', 'commit',
                 array('repository' => intval($repository_id), 'revision' => $revision));
             if (!$commit)
                 exit_with_error('RevisionNotFound', array('repository' => $repository_id, 'revision' => $revision));
-            array_push($commit_set, array('commit' => $commit['commit_id']));
+            array_push($commit_set, $commit['commit_id']);
             array_push($repository_list, $repository_id);
         }
 
@@ -173,7 +127,7 @@ function ensure_commit_sets($db, $triggerable_id, $commit_sets_info) {
             if (!$commit)
                 exit_with_error('RevisionNotFound', array('repository' => $repository_name, 'revision' => $revision));
             array_set_default($commit_sets, $i, array('set' => array()));
-            array_push($commit_sets[$i]['set'], array('commit' => $commit['commit_id']));
+            array_push($commit_sets[$i]['set'], $commit['commit_id']);
         }
     }
 
index ae1b607087b079fa32cd34d53c70c08bc8132fc1..bb65db28e90f6aa99b2585c02e3208560f4ca582 100644 (file)
@@ -10,7 +10,7 @@ define('MEGABYTES', 1024 * 1024);
 function main()
 {
     if (array_get($_SERVER, 'CONTENT_LENGTH') && empty($_POST) && empty($_FILES))
-        exit_with_error('FileSizeLimitExceeded');
+        exit_with_error('FileSizeLimitExceeded2');
 
     if (!verify_token(array_get($_POST, 'token')))
         exit_with_error('InvalidToken');
@@ -22,9 +22,6 @@ function main()
     if (!$input_file)
         exit_with_error('NoFileSpecified');
 
-    if ($input_file['error'] == UPLOAD_ERR_INI_SIZE || $input_file['error'] == UPLOAD_ERR_FORM_SIZE)
-        exit_with_error('FileSizeLimitExceeded');
-
     if ($input_file['error'] != UPLOAD_ERR_OK)
         exit_with_error('FailedToUploadFile', array('name' => $input_file['name'], 'error' => $input_file['error']));
 
index ca848254dde352617a91992416ff463a91917904..20a5d4f5c1e00f428c3214acc201e9a8458f6ea7 100644 (file)
@@ -65,7 +65,6 @@ Run tools/bundle-v3-scripts to speed up the load time for production.`);
         <script src="models/build-request.js"></script>
         <script src="models/commit-set.js"></script>
         <script src="models/triggerable.js"></script>
-        <script src="models/uploaded-file.js"></script>
         <script src="models/manifest.js"></script>
 
         <script src="components/base.js"></script>
@@ -92,8 +91,6 @@ Run tools/bundle-v3-scripts to speed up the load time for production.`);
         <script src="components/mutable-list-view.js"></script>
         <script src="components/analysis-task-bug-list.js"></script>
         <script src="components/ratio-bar-graph.js"></script>
-        <script src="components/custom-analysis-task-configurator.js"></script>
-        <script src="components/instant-file-uploader.js"></script>
 
         <script src="pages/page.js"></script>
         <script src="pages/page-router.js"></script>
index 2923a106ddb3d3dafe1cc88aedf28e4c0fc5d5bf..a50e96b9e0c1d53ebdaf2144e4a801cf3d3ea418 100644 (file)
@@ -7,10 +7,10 @@ class AnalysisTask extends LabeledObject {
         this._author = object.author;
         this._createdAt = object.createdAt;
 
-        console.assert(!object.platform || object.platform instanceof Platform);
+        console.assert(object.platform instanceof Platform);
         this._platform = object.platform;
 
-        console.assert(!object.metric || object.metric instanceof Metric);
+        console.assert(object.metric instanceof Metric);
         this._metric = object.metric;
 
         this._startMeasurementId = object.startRun;
@@ -29,11 +29,7 @@ class AnalysisTask extends LabeledObject {
 
     static findByPlatformAndMetric(platformId, metricId)
     {
-        return this.all().filter((task) => {
-            const platform = task._platform;
-            const metric = task._metric;
-            return platform && metric && platform.id() == platformId && metric.id() == metricId;
-        });
+        return this.all().filter(function (task) { return task._platform.id() == platformId && task._metric.id() == metricId; });
     }
 
     updateSingleton(object)
@@ -59,8 +55,7 @@ class AnalysisTask extends LabeledObject {
         this._finishedBuildRequestCount = +object.finishedBuildRequestCount;
     }
 
-    isCustom() { return !this._platform; }
-    hasResults() { return !!this._finishedBuildRequestCount; }
+    hasResults() { return this._finishedBuildRequestCount; }
     hasPendingRequests() { return this._finishedBuildRequestCount < this._buildRequestCount; }
     requestLabel() { return `${this._finishedBuildRequestCount} of ${this._buildRequestCount}`; }
 
@@ -206,8 +201,6 @@ class AnalysisTask extends LabeledObject {
                 }
             }
             for (var otherTask of AnalysisTask.all()) {
-                if (task.isCustom())
-                    continue;
                 if (task.endTime() < otherTask.startTime()
                     || otherTask.endTime() < task.startTime()
                     || task.metric() != otherTask.metric())
@@ -264,6 +257,9 @@ class AnalysisTask extends LabeledObject {
         for (var rawData of data.analysisTasks) {
             rawData.platform = Platform.findById(rawData.platform);
             rawData.metric = Metric.findById(rawData.metric);
+            if (!rawData.platform || !rawData.metric)
+                continue;
+
             rawData.bugs = taskToBug[rawData.id];
             rawData.causes = resolveCommits(rawData.causes);
             rawData.fixes = resolveCommits(rawData.fixes);
index 31b8c655af66f8e3b82bb95ccf378c221499ba6f..299012d3757ff1540fcbd81d5b307d9d9274bfa5 100644 (file)
@@ -127,9 +127,6 @@ class BuildRequest extends DataModelObject {
             commit.repository = Repository.findById(commit.repository);
         }
 
-        for (let uploadedFile of data['uploadedFiles'])
-            UploadedFile.ensureSingleton(uploadedFile.id, uploadedFile);
-
         const commitSets = data['commitSets'].map((row) => {
             row.commits = row.commits.map((commitId) => commitIdMap[commitId]);
             return CommitSet.ensureSingleton(row.id, row);
index bbcf7afeb86e8871c91f9f2b36f3e0692b56ad07..5624af54be6e8dc8b8f55ad6b96772d5268ebeb5 100644 (file)
@@ -68,20 +68,6 @@ class CommitLog extends DataModelObject {
         return {repository: repository, label: label, url: repository.urlForRevisionRange(from, to)};
     }
 
-    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) => {
-            const commits = data['commits'];
-            if (!commits || !commits.length)
-                return null;
-            const rawData = commits[0];
-            rawData.repository = repository;
-            return CommitLog.ensureSingleton(rawData.id, rawData);
-        });
-    }
-
     static fetchBetweenRevisions(repository, precedingRevision, lastRevision)
     {
         // FIXME: The cache should be smarter about fetching a range within an already fetched range, etc...
index af79fff04e7c1027d0c18c2bc9aa0c90268d7e38..c6ca9ddd75b27c44f3b67838831faea527136b1b 100644 (file)
@@ -8,7 +8,6 @@ class CommitSet extends DataModelObject {
         this._repositories = [];
         this._repositoryToCommitMap = {};
         this._latestCommitTime = null;
-        this._customRoots = [];
 
         if (!object)
             return;
@@ -19,14 +18,9 @@ class CommitSet extends DataModelObject {
             this._repositoryToCommitMap[repositoryId] = CommitLog.ensureSingleton(row.id, row);
             this._repositories.push(row.repository);
         }
-        for (let fileId of object.customRoots) {
-            const uploadedFile = UploadedFile.findById(fileId);
-            this._customRoots.push(uploadedFile);
-        }
     }
 
     repositories() { return this._repositories; }
-    customRoots() { return this._customRoots; }
     commitForRepository(repository) { return this._repositoryToCommitMap[repository.id()]; }
 
     revisionForRepository(repository)
@@ -55,18 +49,6 @@ class CommitSet extends DataModelObject {
             if (this._repositoryToCommitMap[repositoryId] != other._repositoryToCommitMap[repositoryId])
                 return false;
         }
-        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;
-        }
         return true;
     }
 
@@ -124,7 +106,6 @@ class CustomCommitSet {
     constructor()
     {
         this._revisionListByRepository = new Map;
-        this._customRoots = [];
     }
 
     setRevisionForRepository(repository, revision)
@@ -133,29 +114,9 @@ class CustomCommitSet {
         this._revisionListByRepository.set(repository, revision);
     }
 
-    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);
-    }
-
     repositories() { return Array.from(this._revisionListByRepository.keys()); }
     revisionForRepository(repository) { return this._revisionListByRepository.get(repository); }
-    customRoots() { return this._customRoots; }
 
-    addCustomRoot(uploadedFile)
-    {
-        console.assert(uploadedFile instanceof UploadedFile);
-        this._customRoots.push(uploadedFile);
-    }
 }
 
 if (typeof module != 'undefined') {
index 973f7219e53e9d7915f772e8f7c914bbfa5065d6..f8436dabc709ba0b6952e9f57801e8f7ca2184b9 100644 (file)
@@ -57,9 +57,6 @@ class Manifest {
             });
         });
 
-        if (typeof(UploadedFile) != 'undefined')
-            UploadedFile.fileUploadSizeLimit = rawResponse.fileUploadSizeLimit || 0;
-
         Instrumentation.endMeasuringTime('Manifest', '_didFetchManifest');
 
         return {
index a97745ad0cc671d40390c6264bc3f1701b76005d..9dc43c17e8d6da791cca6b701cf88063c0858c90 100644 (file)
@@ -119,14 +119,6 @@ class Metric extends LabeledObject {
         formatter.divisor = divisor;
         return formatter;
     };
-
-    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$/, '');
-    }
 }
 
 if (typeof module != 'undefined')
index c5f60918487fd433559fcd072c8943a7ce8e83b1..2ca2649439b0835b946248f058b8d01a88e27a40 100644 (file)
@@ -178,47 +178,26 @@ class TestGroup extends LabeledObject {
         });
     }
 
-    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) => {
-            return AnalysisTask.fetchById(data['taskId']);
-        }).then((task) => {
-            return this._fetchTestGroupsForTask(task.id()).then(() => task);
-        });
-    }
-
     static createAndRefetchTestGroups(task, name, repetitionCount, commitSets)
     {
         console.assert(commitSets.length == 2);
-        const revisionSets = this._revisionSetsFromCommitSets(commitSets);
-        return PrivilegedAPI.sendRequest('create-test-group', {
-            task: task.id(),
-            name: name,
-            repetitionCount: repetitionCount,
-            revisionSets: revisionSets,
-        }).then((data) => this._fetchTestGroupsForTask(task.id()));
-    }
 
-    static _revisionSetsFromCommitSets(commitSets)
-    {
-        return commitSets.map((commitSet) => {
+        const revisionSets = commitSets.map((commitSet) => {
             console.assert(commitSet instanceof CustomCommitSet || commitSet instanceof CommitSet);
             const revisionSet = {};
             for (let repository of commitSet.repositories())
                 revisionSet[repository.id()] = commitSet.revisionForRepository(repository);
-            const customRoots = commitSet.customRoots();
-            if (customRoots && customRoots.length)
-                revisionSet['customRoots'] = customRoots.map((uploadedFile) => uploadedFile.id());
             return revisionSet;
         });
-    }
 
-    static _fetchTestGroupsForTask(taskId)
-    {
-        return this.cachedFetch('/api/test-groups', {task: taskId}, true).then((data) => this._createModelsFromFetchedTestGroups(data));
+        return PrivilegedAPI.sendRequest('create-test-group', {
+            task: task.id(),
+            name: name,
+            repetitionCount: repetitionCount,
+            revisionSets: revisionSets,
+        }).then((data) => {
+            return this.cachedFetch('/api/test-groups', {task: task.id()}, true).then((data) => this._createModelsFromFetchedTestGroups(data));
+        });
     }
 
     static fetchByTask(taskId)
index c6f81e282c16d09c2e421075b1f45682ea0354c3..75331e3c7ea6420be25b40dfe7d6b6ca2f1610c7 100644 (file)
@@ -37,19 +37,6 @@ class Triggerable extends LabeledObject {
         }
         return null;
     }
-
-    static triggerablePlatformsForTests(tests)
-    {
-        console.assert(tests instanceof Array);
-        if (!tests.length)
-            return [];
-        return this.sortByName(Platform.all().filter((platform) => {
-            return tests.every((test) => {
-                const triggerable = Triggerable.findByTestConfiguration(test, platform);
-                return triggerable && !triggerable.isDisabled();
-            });
-        }));
-    }
 }
 
 class TriggerableRepositoryGroup extends LabeledObject {
@@ -77,21 +64,6 @@ class TriggerableRepositoryGroup extends LabeledObject {
     description() { return this._description || this.name(); }
     acceptsCustomRoots() { return this._acceptsCustomRoots; }
     repositories() { return this._repositories; }
-
-    static sortByNamePreferringSmallerRepositories(groupList)
-    {
-        return groupList.sort((a, b) => {
-            if (a.repositories().length < b.repositories().length)
-                return -1;
-            else if (a.repositories().length > b.repositories().length)
-                return 1;
-            if (a.name() < b.name())
-                return -1;
-            else if (a.name() > b.name())
-                return 1;
-            return 0;
-        });
-    }
 }
 
 if (typeof module != 'undefined') {
index 1909ebaf71c2c24bac1646f4ca499b43e109f7f7..fd1c6934de796ac3ee78c7877b75b06a5d6d8e4d 100644 (file)
@@ -12,15 +12,8 @@ class UploadedFile extends DataModelObject {
         this.ensureNamedStaticMap('sha256')[object.sha256] = this;
     }
 
-    createdAt() { return this._createdAt; }
-    filename() { return this._filename; }
-    author() { return this._author; }
-    size() { return this._size; }
-
     static uploadFile(file, uploadProgressCallback = null)
     {
-        if (file.size > UploadedFile.fileUploadSizeLimit)
-            return Promise.reject('FileSizeLimitExceeded');
         return PrivilegedAPI.sendRequest('upload-file', {'newFile': file}, {useFormData: true, uploadProgressCallback}).then((rawData) => {
             return UploadedFile.ensureSingleton(rawData['uploadedFile'].id, rawData['uploadedFile']);
         });
@@ -28,8 +21,6 @@ class UploadedFile extends DataModelObject {
 
     static fetchUnloadedFileWithIdenticalHash(file)
     {
-        if (file.size > UploadedFile.fileUploadSizeLimit)
-            return Promise.reject('FileSizeLimitExceeded');
         return new Promise((resolve, reject) => {
             const reader = new FileReader();
             reader.onload = () => resolve(reader.result);
@@ -41,11 +32,9 @@ class UploadedFile extends DataModelObject {
             const map = this.namedStaticMap('sha256');
             if (map && sha256 in map)
                 return map[sha256];
-            return RemoteAPI.getJSON(`../api/uploaded-file?sha256=${sha256}`).then((rawData) => {
-                if (rawData['status'] == 'NotFound' || !rawData['uploadedFile'])
+            return RemoteAPI.getJSONWithStatus(`../api/uploaded-file?sha256=${sha256}`).then((rawData) => {
+                if (!rawData['uploadedFile'])
                     return null;
-                if (rawData['status'] != 'OK')
-                    return Promise.reject(rawData['status']);
                 return UploadedFile.ensureSingleton(rawData['uploadedFile'].id, rawData['uploadedFile']);
             });
         });
@@ -63,8 +52,3 @@ class UploadedFile extends DataModelObject {
     }
 
 }
-
-UploadedFile.fileUploadSizeLimit = 0;
-
-if (typeof module != 'undefined')
-    module.exports.UploadedFile = UploadedFile;
index abad2995aaa6545c994eb200ec21829f351b1a57..9bfb5552d3c1aba7d1da0870fb777c39768b2abd 100644 (file)
@@ -123,9 +123,11 @@ class AnalysisCategoryPage extends PageWithHeading {
         Instrumentation.startMeasuringTime('AnalysisCategoryPage', 'reconstructTaskList');
 
         console.assert(this.router());
-        const currentCategory = this._categoryToolbar.currentCategory();
+        var currentCategory = this._categoryToolbar.currentCategory();
 
-        const tasks = AnalysisTask.all().filter((task) => task.category() == currentCategory).sort((a, b) => {
+        var tasks = AnalysisTask.all().filter(function (task) {
+            return task.category() == currentCategory;
+        }).sort(function (a, b) {
             if (a.hasPendingRequests() == b.hasPendingRequests())
                 return b.createdAt() - a.createdAt();
             else if (a.hasPendingRequests()) // a < b
@@ -135,25 +137,25 @@ class AnalysisCategoryPage extends PageWithHeading {
             return 0;
         });
 
-        const element = ComponentBase.createElement;
-        const link = ComponentBase.createLink;
-        const router = this.router();
+        var element = ComponentBase.createElement;
+        var link = ComponentBase.createLink;
+        var router = this.router();
         this.renderReplace(this.content().querySelector('tbody.analysis-tasks'),
-            tasks.map((task) => {
-                const status = AnalysisCategoryPage._computeStatus(task);
+            tasks.map(function (task) {
+                var status = AnalysisCategoryPage._computeStatus(task);
                 return element('tr', [
                     element('td', {class: 'status'},
                         element('span', {class: status.class}, status.label)),
                     element('td', link(task.label(), router.url(`analysis/task/${task.id()}`))),    
                     element('td', {class: 'bugs'},
-                        element('ul', task.bugs().map((bug) => {
-                            const url = bug.url();
-                            const title = bug.title();
+                        element('ul', task.bugs().map(function (bug) {
+                            var url = bug.url();
+                            var title = bug.title();
                             return element('li', url ? link(bug.label(), title, url, true) : title);
                         }))),
                     element('td', {class: 'author'}, task.author()),
-                    element('td', {class: 'platform'}, task.platform() ? task.platform().label() : null),
-                    element('td', task.metric() ? task.metric().fullName() : null),
+                    element('td', {class: 'platform'}, task.platform().label()),
+                    element('td', task.metric().fullName()),
                     ]);
             }));
 
index 209131970be6da83442528f004782436620ae9bd..8a5c84b47a60c332a4037fd528a6a674fb3948b4 100644 (file)
@@ -409,12 +409,6 @@ class AnalysisTaskPage extends PageWithHeading {
         console.assert(!this._task);
 
         this._task = task;
-        const bugList = this.part('bug-list');
-        this.part('bug-list').setTask(this._task);
-        this.enqueueToRender();
-
-        if (task.isCustom())
-            return task;
 
         const platform = task.platform();
         const metric = task.metric();
@@ -432,6 +426,11 @@ class AnalysisTaskPage extends PageWithHeading {
         chart.setOverviewDomain(domain[0], domain[1]);
         chart.setMainDomain(domain[0], domain[1]);
 
+        const bugList = this.part('bug-list');
+        this.part('bug-list').setTask(this._task);
+
+        this.enqueueToRender();
+
         return task;
     }
 
@@ -508,10 +507,10 @@ class AnalysisTaskPage extends PageWithHeading {
         this._renderCauseAndFixesLazily.evaluate(this._startPoint, this._task);
         this._renderRelatedTasksLazily.evaluate(this._task, this._relatedTasks);
 
-        this.content('chart-pane').style.display = this._task && !this._task.isCustom() ? null : 'none';
+        this.content('chart-pane').style.display = this._task ? null : 'none';
         this.part('chart-pane').setShowForm(!!this._triggerable);
 
-        this.content('results-pane').style.display = this._task && !this._task.isCustom() ? null : 'none';
+        this.content('results-pane').style.display = this._task ? null : 'none';
         this.part('results-pane').setShowForm(!!this._triggerable);
 
         Instrumentation.endMeasuringTime('AnalysisTaskPage', 'render');
@@ -520,7 +519,7 @@ class AnalysisTaskPage extends PageWithHeading {
     _renderTaskNameAndStatus(task, taskName, changeType)
     {
         this.part('analysis-task-name').setText(taskName);
-        if (task && !task.isCustom()) {
+        if (task) {
             const link = ComponentBase.createLink;
             const platform = task.platform();
             const metric = task.metric();
index 952a729e9ef5f081681fdccd5149cad6984994be..07e9ea25b3034bd620b4f7a5b2cee8ead3c44c20 100644 (file)
@@ -49,7 +49,7 @@ class ChartPaneStatusView extends ComponentBase {
                 element('td', 'Build'),
                 element('td', {colspan: 2}, [
                     url ? link(buildNumber, build.label(), url, true) : buildNumber,
-                    ` (${Metric.formatTime(build.buildTime())})`
+                    ` (${this._formatTime(build.buildTime())})`
                 ]),
             ]));
         }
@@ -72,6 +72,12 @@ class ChartPaneStatusView extends ComponentBase {
         this.renderReplace(this.content('build-revision'), tableContent);
     }
 
+    _formatTime(date)
+    {
+        console.assert(date instanceof Date);
+        return date.toISOString().replace('T', ' ').replace(/\.\d+Z$/, '');
+    }
+
     setCurrentRepository(repository)
     {
         this._currentRepository = repository;
index c791486651d276d9b02317bf2b3b161daee9a0af..2dcf1d9ee6dee438a243adbe1d86bfe6dbcece38 100644 (file)
@@ -19,7 +19,7 @@ function createTrendLineExecutableFromAveragingFunction(callback) {
     }
 }
 
-const ChartTrendLineTypes = [
+var ChartTrendLineTypes = [
     {
         id: 0,
         label: 'None',
@@ -196,15 +196,15 @@ class ChartPane extends ChartPaneBase {
 
     _analyzeRange(startPoint, endPoint)
     {
-        const router = this._chartsPage.router();
-        const newWindow = window.open(router.url('analysis/task/create', {inProgress: true}), '_blank');
+        var router = this._chartsPage.router();
+        var newWindow = window.open(router.url('analysis/task/create'), '_blank');
 
-        const analyzePopover = this.content().querySelector('.chart-pane-analyze-popover');
-        const name = analyzePopover.querySelector('input').value;
+        var analyzePopover = this.content().querySelector('.chart-pane-analyze-popover');
+        var name = analyzePopover.querySelector('input').value;
         AnalysisTask.create(name, startPoint.id, endPoint.id).then((data) => {
             newWindow.location.href = router.url('analysis/task/' + data['taskId']);
             this.fetchAnalysisTasks(true);
-        }, (error) => {
+        }, function (error) {
             newWindow.location.href = router.url('analysis/task/create', {error: error});
         });
     }
@@ -272,6 +272,7 @@ class ChartPane extends ChartPaneBase {
         if (hasSelectedPoints) {
             actions.push(this._makePopoverActionItem(analyzePopover, 'Analyze', false));
             analyzePopover.onsubmit = this.createEventHandler(() => {
+                console.log(selectedPoints.length());
                 this._analyzeRange(selectedPoints.firstPoint(), selectedPoints.lastPoint());
             });
         } else {
index a5f064d4cfc7587539e0d2167b5b8ec2cd11b019..8b802d240667a70824141440095fbc02c43d88c2 100644 (file)
@@ -3,8 +3,7 @@ class CreateAnalysisTaskPage extends PageWithHeading {
     constructor()
     {
         super('Create Analysis Task');
-        this._message = null;
-        this._renderMessageLazily = new LazilyEvaluatedFunction(this._renderMessage.bind(this));
+        this._errorMessage = null;
     }
 
     title() { return 'Creating a New Analysis Task'; }
@@ -14,110 +13,42 @@ class CreateAnalysisTaskPage extends PageWithHeading {
     {
         if (state.error instanceof Set)
             state.error = Array.from(state.error.values())[0];
-        this._message = state.error || (state.inProgress ? 'Creating the analysis task page...' : '');
-    }
-
-    didConstructShadowTree()
-    {
-        this.part('configurator').listenToAction('commitSetChange', () => this.enqueueToRender());
-        this.content('start-button').onclick = this.createEventHandler(() => this._createAnalysisTaskWithGroup());
-    }
-
-    _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) => {
-            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) => {
-            alert('Failed to create a new test group: ' + error);
-        });
+        this._errorMessage = state.error;
+        if (!isOpen)
+            this.enqueueToRender();
     }
 
     render()
     {
         super.render();
-        const configurator = this.part('configurator');
-        this._renderMessageLazily.evaluate(this._message, !!configurator.commitSets(), configurator.tests(), configurator.platform());
+        if (this._errorMessage)
+            this.content().querySelector('.message').textContent = this._errorMessage;
     }
 
-    _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) => test.name()).join(', ')} on ${platform.name()}`;
-        this.content('iteration-start-pane').style.display = !this._message && hasValidCommitSets ? null : 'none';
-      }
-
     static htmlTemplate()
     {
         return `
-            <p id="message"></p>
-            <div id="new-task">
-                <input id="task-name" type="text" placeholder="Name this task" required>
-                <custom-analysis-task-configurator id="configurator"></custom-analysis-task-configurator>
-                <div id="iteration-start-pane">
-                    <input id="test-group-name" placeholder="Name this test group" required>
-                    <label><select id="iteration-count">
-                        <option>1</option>
-                        <option>2</option>
-                        <option>3</option>
-                        <option selected>4</option>
-                        <option>5</option>
-                        <option>6</option>
-                    </select> iterations per configuration</label>
-                    <button id="start-button">Start</button>
-                </div>
-            </div>`;
+            <div class="create-analysis-task-container">
+                <p class="message">Creating the analysis task page...</p>
+            </div>
+`;
     }
 
     static cssTemplate()
     {
         return `
-            #message {
-                text-align: center;
-            }
-
-            #new-task > * {
-                display: block;
-                margin: 1rem;
+            .create-analysis-task-container {
+                display: flex;
             }
 
-            #new-task input {
-                width: 30%;
-                min-width: 10rem;
-                font-size: 1rem;
-                font-weight: inherit;
+            .create-analysis-task-container > * {
+                margin: 1rem auto;
+                display: inline-block;
             }
 
-            #start-button {
-                display: block;
-                margin-top: 0.5rem;
-                font-size: 1.2rem;
-                font-weight: inherit;
+            .create-analysis-task input {
+                font-size: inherit;
             }
 `;
     }
index 9d1691c8d67e623215999ecec39639f0de0c1e15..bc0333344d3959130384887b51872d5fb03286c5 100644 (file)
@@ -52,7 +52,6 @@ class PageRouter {
             destinationPage.open(parsed.state);
         } else
             destinationPage.updateFromSerializedState(parsed.state, false);
-        destinationPage.enqueueToRender();
 
         return true;
     }
index f8fd4e12130b887567f8d53a2114b3a38a6726d1..d32fd558c33393eb59c1b452e0cf9c5a84497ac5 100644 (file)
@@ -23,7 +23,7 @@ describe('/api/build-requests', function () {
             assert.deepEqual(content['buildRequests'], []);
             assert.deepEqual(content['commitSets'], []);
             assert.deepEqual(content['commits'], []);
-            assert.deepEqual(Object.keys(content).sort(), ['buildRequests', 'commitSets', 'commits', 'status', 'uploadedFiles']);
+            assert.deepEqual(Object.keys(content).sort(), ['buildRequests', 'commitSets', 'commits', 'status']);
         });
     });
 
@@ -31,7 +31,7 @@ describe('/api/build-requests', function () {
         return MockData.addMockData(TestServer.database()).then(() => {
             return TestServer.remoteAPI().getJSONWithStatus('/api/build-requests/build-webkit');
         }).then((content) => {
-            assert.deepEqual(Object.keys(content).sort(), ['buildRequests', 'commitSets', 'commits', 'status', 'uploadedFiles']);
+            assert.deepEqual(Object.keys(content).sort(), ['buildRequests', 'commitSets', 'commits', 'status']);
 
             assert.equal(content['commitSets'].length, 2);
             assert.equal(content['commitSets'][0].id, 401);
@@ -85,7 +85,7 @@ describe('/api/build-requests', function () {
         return MockData.addMockData(TestServer.database()).then(() => {
             return TestServer.remoteAPI().getJSONWithStatus('/api/build-requests/build-webkit?useLegacyIdResolution=true');
         }).then((content) => {
-            assert.deepEqual(Object.keys(content).sort(), ['buildRequests', 'commitSets', 'commits', 'status', 'uploadedFiles']);
+            assert.deepEqual(Object.keys(content).sort(), ['buildRequests', 'commitSets', 'commits', 'status']);
 
             assert.equal(content['commitSets'].length, 2);
             assert.equal(content['commitSets'][0].id, 401);
@@ -217,11 +217,11 @@ describe('/api/build-requests', function () {
 
             let firstWebKitCommit = firstCommitSet.commitForRepository(webkit);
             assert.equal(firstWebKitCommit.revision(), '191622');
-            assert.equal(+firstWebKitCommit.time(), +new Date('2015-10-27T11:36:56.88Z'));
+            assert.equal(+firstWebKitCommit.time(), 1445945816878);
 
             let secondWebKitCommit = secondCommitSet.commitForRepository(webkit);
             assert.equal(secondWebKitCommit.revision(), '192736');
-            assert.equal(+secondWebKitCommit.time(), +new Date('2015-11-22T20:48:45.65Z'));
+            assert.equal(+secondWebKitCommit.time(), 1448225325650);
         });
     });
 
@@ -396,50 +396,4 @@ describe('/api/build-requests', function () {
             assert.strictEqual(buildRequests[7].order(), 3);
         });
     });
-
-    it('should place build requests created by user before automatically created ones', () => {
-        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(() => Manifest.fetch()).then(() => {
-            return BuildRequest.fetchForTriggerable('build-webkit');
-        }).then((buildRequests) => {
-            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(() => {
-                return db.insert('commit_set_relationships', {set: set0.id(), root_file: 1});
-            });
-        }).then(() => {
-            CommitSet.clearStaticMap();
-            BuildRequest.clearStaticMap();
-            return BuildRequest.fetchForTriggerable('build-webkit');
-        }).then((buildRequests) => {
-            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(), []);
-        });
-    });
-
 });
index 6b047f032be75c0a7a3fe11e23426939044ae751..9b9c93580693a6c97e4729b0ebf8ad91b8b5871c 100644 (file)
@@ -2,7 +2,6 @@
 
 const assert = require('assert');
 
-const MockData = require('./resources/mock-data.js');
 const TestServer = require('./resources/test-server.js');
 const addSlaveForReport = require('./resources/common-operations.js').addSlaveForReport;
 const prepareServerTest = require('./resources/common-operations.js').prepareServerTest;
@@ -214,7 +213,7 @@ describe("/api/commits/", function () {
             });
         });
 
-        it("should return the latest commit", () => {
+        it("should return the oldest commit", () => {
             const remote = TestServer.remoteAPI();
             return addSlaveForReport(subversionCommits).then(() => {
                 return remote.postJSONWithStatus('/api/report-commits/', subversionCommits);
@@ -239,50 +238,6 @@ describe("/api/commits/", function () {
                 assert.equal(result['commits'][0]['revision'], systemVersionCommits['commits'][0]['revision']);
             });
         });
-
-        it("should return the latest commit for a given platform", () => {
-            const mockDataCommitReports = {
-                "slaveName": "someSlave",
-                "slavePassword": "somePassword",
-                "commits": [
-                    {
-                        "repository": "WebKit",
-                        "revision": "191622",
-                        "time": "2015-10-27T11:36:56.88Z",
-                        "author": {"account": "calvaris@igalia.com"},
-                        "message": "a message",
-                    },
-                    {
-                        "repository": "WebKit",
-                        "revision": "192736",
-                        "time": "2015-11-22T20:48:45.65Z",
-                        "author": {"account": "aestes@apple.com"},
-                        "message": "some message",
-                    },
-                    {
-                        "repository": "WebKit",
-                        "revision": "192903",
-                        "time": "2015-12-01T21:14:46.99Z",
-                        "author": {"account": "darin@apple.com"},
-                        "message": "another message",
-                    }
-                ]
-            }
-            const remote = TestServer.remoteAPI();
-            return MockData.addMockData(TestServer.database()).then(() => {
-                return addSlaveForReport(mockDataCommitReports);
-            }).then(() => {
-                return remote.postJSONWithStatus('/api/report-commits/', mockDataCommitReports);
-            }).then(() => {
-                return remote.getJSON('/api/commits/WebKit/latest?platform=' + MockData.somePlatformId());
-            }).then((result) => {
-                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'));
-            });
-        });
     });
 
     describe('/api/commits/<repository>/last-reported', () => {
index afb82c139ef3bdd94c63dbe216a969ed46cdfd6e..a22eaf69507487b4d30fcf6ef20de4de51e09807 100644 (file)
@@ -1,10 +1,9 @@
 'use strict';
 
-const assert = require('assert');
+let assert = require('assert');
 
-const MockData = require('./resources/mock-data.js');
-const TestServer = require('./resources/test-server.js');
-const TemporaryFile = require('./resources/temporary-file.js').TemporaryFile;
+let MockData = require('./resources/mock-data.js');
+let TestServer = require('./resources/test-server.js');
 const addSlaveForReport = require('./resources/common-operations.js').addSlaveForReport;
 const prepareServerTest = require('./resources/common-operations.js').prepareServerTest;
 
@@ -117,7 +116,6 @@ function addTriggerableAndCreateTask(name)
 
 describe('/privileged-api/create-test-group', function () {
     prepareServerTest(this);
-    TemporaryFile.inject();
 
     it('should return "InvalidName" on an empty request', () => {
         return PrivilegedAPI.sendRequest('create-test-group', {}).then((content) => {
@@ -264,18 +262,6 @@ describe('/privileged-api/create-test-group', function () {
         });
     });
 
-    it('should return "InvalidUploadedFile" when revision sets contains an invalid file ID', () => {
-        return addTriggerableAndCreateTask('some task').then((taskId) => {
-            const webkit = Repository.all().find((repository) => 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) => {
-                assert(false, 'should never be reached');
-            }, (error) => {
-                assert.equal(error, 'InvalidUploadedFile');
-            });
-        });
-    });
-
     it('should return "InvalidRepository" when a revision set uses a repository name instead of a repository id', () => {
         return addTriggerableAndCreateTask('some task').then((taskId) => {
             return PrivilegedAPI.sendRequest('create-test-group', {name: 'test', task: taskId, revisionSets: [{'WebKit': '191622'}, {}]}).then((content) => {
@@ -447,81 +433,4 @@ describe('/privileged-api/create-test-group', function () {
         });
     });
 
-    it('should create a test group with a custom root', () => {
-        return addTriggerableAndCreateTask('some task').then((taskId) => {
-            let insertedGroupId;
-            const webkit = Repository.all().filter((repository) => repository.name() == 'WebKit')[0];
-            const macos = Repository.all().filter((repository) => repository.name() == 'macOS')[0];
-            let uploadedFile;
-            return TemporaryFile.makeTemporaryFile('some.dat', 'some content').then((stream) => {
-                return PrivilegedAPI.sendRequest('upload-file', {newFile: stream}, {useFormData: true});
-            }).then((response) => {
-                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) => {
-                    insertedGroupId = content['testGroupId'];
-                    return TestGroup.fetchByTask(taskId);
-                });
-            }).then((testGroups) => {
-                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', () => {
-        let insertedGroupId;
-        let webkit;
-        return addTriggerableAndCreateTask('some task').then(() => {
-            webkit = Repository.all().filter((repository) => 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) => {
-            insertedGroupId = result['testGroupId'];
-            return Promise.all([AnalysisTask.fetchById(result['taskId']), TestGroup.fetchByTask(result['taskId'])]);
-        }).then((result) => {
-            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');
-        });
-    });
-
 });
index dd03b21c2f176536bc55236edc755f858c892bfd..91bb39630a6cef3dafe010f73658201e42f07632 100644 (file)
@@ -37,28 +37,19 @@ MockData = {
             db.insert('triggerable_repositories', {repository: this.macosRepositoryId(), group: 2001}),
             db.insert('triggerable_repositories', {repository: this.webkitRepositoryId(), group: 2001}),
             db.insert('commits', {id: 87832, repository: this.macosRepositoryId(), revision: '10.11 15A284'}),
-            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}),
+            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()}),
             db.insert('platforms', {id: MockData.somePlatformId(), name: 'some platform'}),
             db.insert('tests', {id: MockData.someTestId(), name: 'some test'}),
-            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}),
+            db.insert('test_metrics', {id: 300, test: 200, name: 'some metric'}),
+            db.insert('test_configurations', {id: 301, metric: 300, platform: 65, type: 'current'}),
             db.insert('commit_sets', {id: 401}),
             db.insert('commit_set_relationships', {set: 401, commit: 87832}),
             db.insert('commit_set_relationships', {set: 401, commit: 93116}),
             db.insert('commit_sets', {id: 402}),
             db.insert('commit_set_relationships', {set: 402, commit: 87832}),
             db.insert('commit_set_relationships', {set: 402, commit: 96336}),
-            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'}),
+            db.insert('analysis_tasks', {id: 500, platform: 65, metric: 300, name: 'some task'}),
             db.insert('analysis_test_groups', {id: 600, task: 500, name: 'some test group'}),
             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}),
             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}),
index af6aa368ef50bb87831767f6ab75631c281de0c7..9d20258d68854c7b04d1871f0ea8bed4a9338970 100644 (file)
@@ -1,12 +1,10 @@
 'use strict';
 
-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;
-
-global.FormData = require('form-data');
+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;
 
 class NodeRemoteAPI extends CommonRemoteAPI {
     constructor(server)
index b20fecffbdaec929cf54937aca893671e74728ce..415ea017df8ba3db926edcb7005bd879f46f634b 100644 (file)
@@ -15,6 +15,7 @@ function sampleAnalysisTask()
                 'bugs': [],
                 'buildRequestCount': '14',
                 'finishedBuildRequestCount': '6',
+                'category': 'identified',
                 'causes': [
                     '105975'
                 ],
@@ -23,10 +24,10 @@ function sampleAnalysisTask()
                 'endRunTime': 1454515020303,
                 'fixes': [],
                 'id': '1082',
-                'metric': MockModels.someMetric.id(),
+                'metric': '2884',
                 'name': 'Potential 1.2% regression between 2016-02-02 20:20 and 02-03 15:57',
                 'needed': null,
-                'platform': MockModels.somePlatform.id(),
+                'platform': '65',
                 'result': 'regression',
                 'segmentationStrategy': '1',
                 'startRun': '37117949',
@@ -52,38 +53,6 @@ function sampleAnalysisTask()
     };
 }
 
-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'
-    };
-}
-
 function measurementCluster()
 {
     return {
@@ -151,43 +120,6 @@ describe('AnalysisTask', () => {
     MockModels.inject();
     let requests = MockRemoteAPI.inject();
 
-    function loadAnalysisTasks(rawData)
-    {
-        AnalysisTask._constructAnalysisTasksFromRawData(rawData);
-        return Promise.resolve();
-    }
-
-    describe('findByPlatformAndMetric', () => {
-        it('should return an empty array when there are no analysis tasks', () => {
-            assert.deepEqual(AnalysisTask.findByPlatformAndMetric(MockModels.somePlatform, MockModels.someMetric), []);
-        });
-
-        it('should return an array containing the matching non-custom analysis tasks', () => {
-            return loadAnalysisTasks(sampleAnalysisTask()).then(() => {
-                return loadAnalysisTasks(sampleCustomAnalysisTask());
-            }).then(() => {
-                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');
-            });
-        });
-    });
-
     describe('fetchAll', () => {
         it('should request all analysis tasks', () => {
             let callCount = 0;
index b0f409d8f403a3f12e2923c776f994ae06a3b52b..f716e9eb8e24ff83dc36dd31572dd34330afd6f9 100644 (file)
@@ -23,12 +23,10 @@ function sampleBuildRequestData()
         }],
         "commitSets": [{
             "id": "4255",
-            "commits": ["87832", "93116"],
-            "customRoots": [],
+            "commits": ["87832", "93116"]
         }, {
             "id": "4256",
-            "commits": ["87832", "96336"],
-            "customRoots": [],
+            "commits": ["87832", "96336"]
         }],
         "commits": [{
             "id": "87832",
@@ -51,7 +49,6 @@ function sampleBuildRequestData()
             "revision": "192736",
             "time": 1448225325650
         }],
-        "uploadedFiles": [],
         "status": "OK"
     };
 }
index c47fbdaef6283317f6a4ad2e7ff8b6be762f625c..f2a561b375c552af9d187b2437c7b1072eff4db8 100644 (file)
@@ -192,7 +192,7 @@ function createSampleBuildRequest(platform, test)
     assert(platform instanceof Platform);
     assert(test instanceof Test);
 
-    let commitSet = CommitSet.ensureSingleton('4197', {customRoots: [], commits: [
+    let commitSet = CommitSet.ensureSingleton('4197', {commits: [
         {'id': '111127', 'time': 1456955807334, 'repository': MockModels.webkit, 'revision': '197463'},
         {'id': '111237', 'time': 1456931874000, 'repository': MockModels.sharedRepository, 'revision': '80229'},
         {'id': '88930', 'time': 0, 'repository': MockModels.ios, 'revision': '13A452'},
index 4b6fd066dc7757639306514e9348f61c81647a1e..6c667deef570c4ad88f68077e6d1d1dec2f41a30 100644 (file)
@@ -15,8 +15,9 @@ function sampleTestGroup() {
             "createdAt": 1458688514000,
             "hidden": false,
             "buildRequests": ["16985", "16986", "16987", "16988", "16989", "16990", "16991", "16992"],
-            "commitSets": ["4255", "4256"],
-        }],
+            "commitSets": ["4255", "4256", "4255", "4256", "4255", "4256", "4255", "4256"]
+        }
+        ],
         "buildRequests": [{
             "id": "16985",
             "triggerable": "3",
@@ -66,16 +67,16 @@ function sampleTestGroup() {
             "url": null,
             "build": null,
             "createdAt": 1458688514000
-        }],
+        }
+        ],
         "commitSets": [{
             "id": "4255",
-            "commits": ["87832", "93116"],
-            "customRoots": [],
+            "commits": ["87832", "93116"]
         }, {
             "id": "4256",
-            "commits": ["87832", "96336"],
-            "customRoots": [],
-        }],
+            "commits": ["87832", "96336"]
+        }
+        ],
         "commits": [{
             "id": "87832",
             "repository": "9",
@@ -96,8 +97,8 @@ function sampleTestGroup() {
             "repository": "11",
             "revision": "192736",
             "time": 1448225325650
-        }],
-        "uploadedFiles": [],
+        }
+        ],
         "status": "OK"
     };
 }
diff --git a/public/v3/components/custom-analysis-task-configurator.js b/public/v3/components/custom-analysis-task-configurator.js
deleted file mode 100644 (file)
index 7a57568..0000000
+++ /dev/null
@@ -1,545 +0,0 @@
-class CustomAnalysisTaskConfigurator extends ComponentBase {
-
-    constructor()
-    {
-        super('custom-analysis-task-configurator');
-
-        this._selectedTests = [];
-        this._triggerablePlatforms = [];
-        this._selectedPlatform = null;
-        this._configurationNames = ['Baseline', 'Comparison'];
-        this._showComparison = false;
-        this._commitSetMap = {};
-        this._specifiedRevisions = {'Baseline': new Map, 'Comparison': new Map};
-        this._fetchedRevisions = {'Baseline': new Map, 'Comparison': new Map};
-        this._repositoryGroupByConfiguration = {'Baseline': null, 'Comparison': null};
-        this._updateTriggerableLazily = new LazilyEvaluatedFunction(this._updateTriggerable.bind(this));
-
-        this._renderTriggerableTestsLazily = new LazilyEvaluatedFunction(this._renderTriggerableTests.bind(this));
-        this._renderTriggerablePlatformsLazily = new LazilyEvaluatedFunction(this._renderTriggerablePlatforms.bind(this));
-        this._renderRepositoryPanesLazily = new LazilyEvaluatedFunction(this._renderRepositoryPanes.bind(this));
-
-        this._fileUploaders = {};
-    }
-
-    tests() { return this._selectedTests; }
-    platform() { return this._selectedPlatform; }
-    commitSets()
-    {
-        const map = this._commitSetMap;
-        if (!map['Baseline'] || !map['Comparison'])
-            return null;
-        return [map['Baseline'], map['Comparison']];
-    }
-
-    didConstructShadowTree()
-    {
-        this.content('specify-comparison-button').onclick = this.createEventHandler(() => this._configureComparison());
-
-        const baselineRootsUploader = new InstantFileUploader;
-        baselineRootsUploader.listenToAction('uploadedFile', (uploadedFile) => {
-            comparisonRootsUploader.addUploadedFile(uploadedFile);
-            this._updateCommitSetMap();
-        });
-        baselineRootsUploader.listenToAction('removedFile', () => this._updateCommitSetMap());
-        this._fileUploaders['Baseline'] = baselineRootsUploader;
-
-        const comparisonRootsUploader = new InstantFileUploader;
-        comparisonRootsUploader.listenToAction('uploadedFile', () => this._updateCommitSetMap());
-        comparisonRootsUploader.listenToAction('removedFile', () => this._updateCommitSetMap());
-        this._fileUploaders['Comparison'] = comparisonRootsUploader;
-    }
-
-    _configureComparison()
-    {
-        this._showComparison = true;
-        this._repositoryGroupByConfiguration['Comparison'] = this._repositoryGroupByConfiguration['Baseline'];
-
-        const specifiedBaselineRevisions = this._specifiedRevisions['Baseline'];
-        const specifiedComparisonRevisions = new Map;
-        for (let key of specifiedBaselineRevisions.keys())
-            specifiedComparisonRevisions.set(key, specifiedBaselineRevisions.get(key));
-        this._specifiedRevisions['Comparison'] = specifiedComparisonRevisions;
-
-        this.enqueueToRender();
-    }
-
-    render()
-    {
-        super.render();
-
-        this._renderTriggerableTestsLazily.evaluate();
-        this._renderTriggerablePlatformsLazily.evaluate(this._selectedTests, this._triggerablePlatforms);
-
-        const [triggerable, error] = this._updateTriggerableLazily.evaluate(this._selectedTests, this._selectedPlatform);
-
-        this._renderRepositoryPanesLazily.evaluate(triggerable, error, this._selectedPlatform, this._repositoryGroupByConfiguration, this._showComparison);
-    }
-
-    _renderTriggerableTests()
-    {
-        const enabledTriggerables = Triggerable.all().filter((triggerable) => !triggerable.isDisabled());
-
-        let tests = Test.topLevelTests().filter((test) => test.metrics().length && enabledTriggerables.some((triggerable) => triggerable.acceptsTest(test)));
-        this.renderReplace(this.content('test-list'), this._buildCheckboxList('test', tests, (selectedTests) => {
-            this._selectedTests = selectedTests;
-
-            this._triggerablePlatforms = Triggerable.triggerablePlatformsForTests(this._selectedTests);
-            if (this._selectedTests.length && !this._triggerablePlatforms.includes(this._selectedPlatform))
-                this._selectedPlatform = null;
-        }));
-    }
-
-    _renderTriggerablePlatforms(selectedTests, triggerablePlatforms)
-    {
-        if (!selectedTests.length) {
-            this.content('platform-pane').style.display = 'none';
-            return;
-        }
-        this.content('platform-pane').style.display = null;
-
-        this.renderReplace(this.content('platform-list'), this._buildCheckboxList('platform', triggerablePlatforms, (selectedPlatforms) => {
-            this._selectedPlatform = selectedPlatforms.length ? selectedPlatforms[0] : null;
-
-            const [triggerable, error] = this._updateTriggerableLazily.evaluate(this._selectedTests, this._selectedPlatform);
-            this._updateRepositoryGroups(triggerable);
-            this._updateCommitSetMap();
-
-            this.enqueueToRender();
-        }));
-    }
-
-    _buildCheckboxList(name, objects, callback)
-    {
-        const listItems = [];
-        let selectedListItems = [];
-        const element = ComponentBase.createElement;
-        return objects.map((object) => {
-            const checkbox = element('input', {type: 'radio', name: name, onchange: () => {
-                selectedListItems.forEach((item) => item.label.classList.remove('selected'));
-                selectedListItems = listItems.filter((item) => item.checkbox.checked);
-                selectedListItems.forEach((item) => item.label.classList.add('selected'));
-
-                callback(selectedListItems.map((item) => item.object));
-                this.enqueueToRender();
-            }});
-            const label = element('label', [checkbox, object.label()]);
-            listItems.push({checkbox, label, object});
-            return element('li', label);
-        })
-    }
-
-    _updateTriggerable(tests, platform)
-    {
-        let triggerable = null;
-        let error = null;
-        if (tests.length && platform) {
-            triggerable = Triggerable.findByTestConfiguration(tests[0], platform);
-            let matchingTests = new Set;
-            let mismatchingTests = new Set;
-            for (let test of tests) {
-                if (Triggerable.findByTestConfiguration(test, platform) == triggerable)
-                    matchingTests.add(test);
-                else
-                    mismatchingTests.add(test);
-            }
-            if (matchingTests.size < tests.length) {
-                const matchingTestNames = [...matchingTests].map((test) => test.fullName()).sort().join('", "');
-                const mismathingTestNames = [...mismatchingTests].map((test) => test.fullName()).sort().join('", "');
-                error = `Tests "${matchingTestNames}" and "${mismathingTestNames}" cannot be scheduled
-                    simultenosuly on "${platform.name()}". Please select one of them at a time.`;
-            }
-        }
-
-        return [triggerable, error];
-    }
-
-    _updateRepositoryGroups(triggerable)
-    {
-        const repositoryGroups = triggerable ? TriggerableRepositoryGroup.sortByNamePreferringSmallerRepositories(triggerable.repositoryGroups()) : [];
-        for (let name in this._repositoryGroupByConfiguration) {
-            const currentGroup = this._repositoryGroupByConfiguration[name];
-            let matchingGroup = null;
-            if (currentGroup) {
-                if (repositoryGroups.includes(currentGroup))
-                    matchingGroup = currentGroup;
-                else
-                    matchingGroup = repositoryGroups.find((group) => group.name() == currentGroup.name());
-            }
-            if (!matchingGroup && repositoryGroups.length)
-                matchingGroup = repositoryGroups[0];
-            this._repositoryGroupByConfiguration[name] = matchingGroup;
-        }
-    }
-
-    _updateCommitSetMap()
-    {
-        const newBaseline = this._computeCommitSet('Baseline');
-        let newComparison = this._computeCommitSet('Comparison');
-        if (newBaseline && newComparison && newBaseline.equals(newComparison))
-            newComparison = null;
-
-        const currentBaseline = this._commitSetMap['Baseline'];
-        const currentComparison = this._commitSetMap['Baseline'];
-        if (newBaseline == currentBaseline && newComparison == currentComparison)
-            return; // Both of them are null.
-
-        if (newBaseline && currentBaseline && newBaseline.equals(currentBaseline)
-            && newComparison && currentComparison && newComparison.equals(currentComparison))
-            return;
-
-        this._commitSetMap = {'Baseline': newBaseline, 'Comparison': newComparison};
-
-        this.dispatchAction('commitSetChange');
-        this.enqueueToRender();
-    }
-
-    _computeCommitSet(configurationName)
-    {
-        const repositoryGroup = this._repositoryGroupByConfiguration[configurationName];
-        if (!repositoryGroup)
-            return null;
-
-        const fileUploader = this._fileUploaders[configurationName];
-        if (!fileUploader || fileUploader.hasFileToUpload())
-            return null;
-
-        const commitSet = new CustomCommitSet;
-        for (let repository of repositoryGroup.repositories()) {
-            let revision = this._specifiedRevisions[configurationName].get(repository);
-            if (!revision)
-                revision = this._fetchedRevisions[configurationName].get(repository);
-            if (!revision)
-                return null;
-            commitSet.setRevisionForRepository(repository, revision);
-        }
-
-        for (let uploadedFile of fileUploader.uploadedFiles())
-            commitSet.addCustomRoot(uploadedFile);
-
-        return commitSet;
-    }
-
-    _renderRepositoryPanes(triggerable, error, platform, repositoryGroupByConfiguration, showComparison)
-    {
-        this.content('repository-configuration-error-pane').style.display = error ? null : 'none';
-        this.content('error').textContent = error;
-
-        this.content('baseline-configuration-pane').style.display = triggerable ? null : 'none';
-        this.content('specify-comparison-pane').style.display = triggerable && !showComparison ? null : 'none';
-        this.content('comparison-configuration-pane').style.display = triggerable && showComparison ? null : 'none';
-
-        if (!triggerable)
-            return;
-
-        const repositoryGroups = TriggerableRepositoryGroup.sortByNamePreferringSmallerRepositories(triggerable.repositoryGroups());
-
-        const repositorySet = new Set;
-        for (let group of repositoryGroups) {
-            for (let repository of group.repositories())
-                repositorySet.add(repository);
-        }
-
-        const repositories = Repository.sortByNamePreferringOnesWithURL([...repositorySet]);
-        const requiredRepositories = repositories.filter((repository) => {
-            return repositoryGroups.every((group) => group.repositories().includes(repository));
-        });
-        const alwaysAcceptsCustomRoots = repositoryGroups.every((group) => group.acceptsCustomRoots());
-
-        console.log(repositoryGroups, alwaysAcceptsCustomRoots);
-
-        this._renderBaselineRevisionTable(platform, repositoryGroups, requiredRepositories, repositoryGroupByConfiguration, alwaysAcceptsCustomRoots);
-
-        if (showComparison)
-            this._renderComparisonRevisionTable(platform, repositoryGroups, requiredRepositories, repositoryGroupByConfiguration, alwaysAcceptsCustomRoots);
-    }
-
-    _renderBaselineRevisionTable(platform, repositoryGroups, requiredRepositories, repositoryGroupByConfiguration, alwaysAcceptsCustomRoots)
-    {
-        let currentGroup = repositoryGroupByConfiguration['Baseline'];
-        const optionalRepositoryList = this._optionalRepositoryList(currentGroup, requiredRepositories);
-        this.renderReplace(this.content('baseline-revision-table'),
-            this._buildRevisionTable('Baseline', repositoryGroups, currentGroup, platform, requiredRepositories, optionalRepositoryList, alwaysAcceptsCustomRoots));
-    }
-
-    _renderComparisonRevisionTable(platform, repositoryGroups, requiredRepositories, repositoryGroupByConfiguration, alwaysAcceptsCustomRoots)
-    {
-        let currentGroup = repositoryGroupByConfiguration['Comparison'];
-        const optionalRepositoryList = this._optionalRepositoryList(currentGroup, requiredRepositories);
-        this.renderReplace(this.content('comparison-revision-table'),
-            this._buildRevisionTable('Comparison', repositoryGroups, currentGroup, platform, requiredRepositories, optionalRepositoryList, alwaysAcceptsCustomRoots));
-    }
-
-    _optionalRepositoryList(currentGroup, requiredRepositories)
-    {
-        if (!currentGroup)
-            return [];
-        return Repository.sortByNamePreferringOnesWithURL(currentGroup.repositories().filter((repository) => !requiredRepositories.includes(repository)));
-    }
-
-    _buildRevisionTable(configurationName, repositoryGroups, currentGroup, platform, requiredRepositories, optionalRepositoryList, alwaysAcceptsCustomRoots)
-    {
-        const element = ComponentBase.createElement;
-        const link = ComponentBase.createLink;
-
-        const customRootsTBody = element('tbody', [
-            element('tr', [
-                element('th', 'Roots'),
-                element('td', this._fileUploaders[configurationName]),
-            ]),
-        ]);
-
-        return [
-            element('tbody',
-                requiredRepositories.map((repository) => {
-                    return element('tr', [
-                        element('th', repository.name()),
-                        element('td', this._buildRevisionInput(configurationName, repository, platform))
-                    ]);
-                })),
-            alwaysAcceptsCustomRoots ? customRootsTBody : [],
-            element('tbody', [
-                element('tr', {'class': 'group-row'},
-                    element('td', {colspan: 2}, this._buildRepositoryGroupList(repositoryGroups, currentGroup, configurationName))),
-            ]),
-            !alwaysAcceptsCustomRoots && currentGroup && currentGroup.acceptsCustomRoots() ? customRootsTBody : [],
-            element('tbody',
-                optionalRepositoryList.map((repository) => {
-                    return element('tr',[
-                        element('th', repository.name()),
-                        element('td', this._buildRevisionInput(configurationName, repository, platform))
-                    ]);
-                })
-            )];
-    }
-
-    _buildRepositoryGroupList(repositoryGroups, currentGroup, configurationName)
-    {
-        const element = ComponentBase.createElement;
-        return repositoryGroups.map((group) => {
-            const input = element('input', {
-                type: 'radio',
-                name: 'repositoryGroup-for-' + configurationName.toLowerCase(),
-                checked: currentGroup == group,
-                onchange: () => this._selectRepositoryGroup(configurationName, group)
-            });
-            return [element('label', [input, group.description()])];
-        });
-    }
-
-    _selectRepositoryGroup(configurationName, group)
-    {
-        const source = this._repositoryGroupByConfiguration;
-        const clone = {};
-        for (let key in source)
-            clone[key] = source[key];
-        clone[configurationName] = group;
-        this._repositoryGroupByConfiguration = clone;
-        this._updateCommitSetMap();
-        this.enqueueToRender();
-    }
-
-    _buildRevisionInput(configurationName, repository, platform)
-    {
-        const revision = this._specifiedRevisions[configurationName].get(repository) || '';
-        const element = ComponentBase.createElement;
-        const input = element('input', {value: revision, oninput: () => {
-            unmodifiedInput = null;
-            this._specifiedRevisions[configurationName].set(repository, input.value);
-            this._updateCommitSetMap();
-        }});
-        let unmodifiedInput = input;
-
-        if (!revision) {
-            CommitLog.fetchLatestCommitForPlatform(repository, platform).then((commit) => {
-                if (commit && unmodifiedInput) {
-                    unmodifiedInput.value = commit.revision();
-                    this._fetchedRevisions[configurationName].set(repository, commit.revision());
-                    this._updateCommitSetMap();
-                }
-            });
-        }
-
-        return input;
-    }
-
-    static htmlTemplate()
-    {
-        return `
-            <section id="test-pane" class="pane">
-                <h2>1. Select a Test</h2>
-                <ul id="test-list" class="config-list"></ul>
-            </section>
-            <section id="platform-pane" class="pane">
-                <h2>2. Select a Platform</h2>
-                <ul id="platform-list" class="config-list"></ul>
-            </section>
-            <section id="repository-configuration-error-pane" class="pane">
-                <h2>Incompatible tests</h2>
-                <p id="error"></p>
-            </section>
-            <section id="baseline-configuration-pane" class="pane">
-                <h2>3. Configure Baseline</h2>
-                <table id="baseline-revision-table" class="revision-table"></table>
-            </section>
-            <section id="specify-comparison-pane" class="pane">
-                <button id="specify-comparison-button">Configure to Compare</button>
-            </section>
-            <section id="comparison-configuration-pane" class="pane">
-                <h2>4. Configure Comparison</h2>
-                <table id="comparison-revision-table" class="revision-table"></table>
-            </section>`;
-    }
-
-    static cssTemplate()
-    {
-        return `
-            :host {
-                display: flex !important;
-                flex-direction: row !important;
-            }
-            .pane {
-                margin-right: 1rem;
-                padding: 0;
-            }
-            .pane h2 {
-                padding: 0;
-                margin: 0;
-                margin-bottom: 0.5rem;
-                font-size: 1.2rem;
-                font-weight: inherit;
-                text-align: center;
-                white-space: nowrap;
-            }
-
-            .config-list {
-                height: 20rem;
-                overflow: scroll;
-                display: block;
-                margin: 0;
-                padding: 0;
-                list-style: none;
-                font-size: inherit;
-                font-weight: inherit;
-                border: none;
-                border-top: solid 1px #ddd;
-                border-bottom: solid 1px #ddd;
-                white-space: nowrap;
-            }
-
-            #platform-list:empty:before {
-                content: "No matching platform";
-                display: block;
-                margin: 1rem 0.5rem;
-                text-align: center;
-            }
-
-            .config-list label {
-                display: block;
-                padding: 0.1rem 0.2rem;
-            }
-
-            .config-list label:hover,
-            .config-list a:hover {
-                background: rgba(204, 153, 51, 0.1);
-            }
-
-            .config-list label.selected,
-            .config-list a.selected {
-                background: #eee;
-            }
-
-            .config-list a {
-                display: block;
-                padding: 0.1rem 0.2rem;
-                text-decoration: none;
-                color: inherit;
-            }
-
-            #repository-configuration-pane {
-                position: relative;
-            }
-
-            #repository-configuration-pane > button  {
-                margin-left: 19.5rem;
-            }
-
-            .revision-table {
-                border: none;
-                border-collapse: collapse;
-                font-size: 1rem;
-            }
-
-            .revision-table thead {
-                font-size: 1.2rem;
-            }
-
-            .revision-table tbody:empty {
-                display: none;
-            }
-
-            .revision-table tbody tr:first-child td,
-            .revision-table tbody tr:first-child th {
-                border-top: solid 1px #ddd;
-                padding-top: 0.5rem;
-            }
-
-            .revision-table tbody tr:last-child td,
-            .revision-table tbody tr:last-child th {
-                padding-bottom: 0.5rem;
-            }
-
-            .revision-table td,
-            .revision-table th {
-                width: 15rem;
-                height: 1.8rem;
-                padding: 0 0.2rem;
-                border: none;
-                font-weight: inherit;
-            }
-
-            .revision-table thead th {
-                text-align: center;
-            }
-
-            .revision-table th close-button {
-                vertical-align: bottom;
-            }
-
-            .revision-table td:first-child,
-            .revision-table th:first-child {
-                width: 6rem;
-            }
-
-            .revision-table tr.group-row td {
-                padding-left: 5rem;
-            }
-
-            label {
-                white-space: nowrap;
-                display: block;
-            }
-
-            input:not([type=radio]) {
-                width: calc(100% - 0.6rem);
-                padding: 0.1rem 0.2rem;
-                font-size: 0.9rem;
-                font-weight: inherit;
-            }
-
-            #specify-comparison-pane button {
-                margin-top: 1.5rem;
-                font-size: 1.1rem;
-                font-weight: inherit;
-            }
-
-            #start-pane button {
-                margin-top: 1.5rem;
-                font-size: 1.2rem;
-                font-weight: inherit;
-            }
-`;
-    }
-}
-
-ComponentBase.defineElement('custom-analysis-task-configurator', CustomAnalysisTaskConfigurator);
diff --git a/public/v3/components/instant-file-uploader.js b/public/v3/components/instant-file-uploader.js
deleted file mode 100644 (file)
index 64688dc..0000000
+++ /dev/null
@@ -1,232 +0,0 @@
-class InstantFileUploader extends ComponentBase {
-    constructor()
-    {
-        super('instant-file-uploader');
-        this._uploadedFiles = [];
-        this._preuploadFiles = [];
-        this._uploadProgress = new WeakMap;
-        this._fileSizeFormatter = Metric.makeFormatter('B', 3);
-
-        this._renderUploadedFilesLazily = new LazilyEvaluatedFunction(this._renderUploadedFiles.bind(this));
-        this._renderPreuploadFilesLazily = new LazilyEvaluatedFunction(this._renderPreuploadFiles.bind(this));
-    }
-
-    hasFileToUpload() { return !!this._preuploadFiles.length; }
-    uploadedFiles() { return this._uploadedFiles; }
-
-    addUploadedFile(uploadedFile)
-    {
-        console.assert(uploadedFile instanceof UploadedFile);
-        if (this._uploadedFiles.includes(uploadedFile))
-            return;
-        this._uploadedFiles.push(uploadedFile);
-        this.enqueueToRender();
-    }
-
-    didConstructShadowTree()
-    {
-        const input = this.content('file-input');
-        input.onchange = () => this._didFileInputChange(input);
-    }
-
-    render()
-    {
-        this._renderUploadedFilesLazily.evaluate(...this._uploadedFiles);
-        const uploadStatusElements = this._renderPreuploadFilesLazily.evaluate(...this._preuploadFiles);
-        this._updateUploadStatus(uploadStatusElements);
-    }
-
-    _renderUploadedFiles(...uploadedFiles)
-    {
-        const element = ComponentBase.createElement;
-        this.renderReplace(this.content('uploaded-files'), uploadedFiles.map((uploadedFile) => {
-            const authorInfo = uploadedFile.author() ? ' by ' + uploadedFile.author() : '';
-            const createdAt = Metric.formatTime(uploadedFile.createdAt());
-            const deleteButton = new CloseButton;
-            deleteButton.listenToAction('activate', () => this._removeUploadedFile(uploadedFile));
-            return element('li', [
-                deleteButton,
-                element('code', {class: 'filename'}, uploadedFile.filename()),
-                ' ',
-                element('small', {class: 'filesize'}, '(' + this._fileSizeFormatter(uploadedFile.size()) + ')'),
-                element('small', {class: 'meta'}, `Uploaded${authorInfo} on ${createdAt}`),
-            ]);
-        }));
-    }
-
-    _renderPreuploadFiles(...preuploadFiles)
-    {
-        const element = ComponentBase.createElement;
-        const uploadStatusElements = [];
-        this.renderReplace(this.content('preupload-files'), preuploadFiles.map((file) => {
-            const progressBar = element('progress');
-            const meta = element('small', {class: 'meta'}, progressBar);
-            uploadStatusElements.push({file, meta, progressBar});
-
-            return element('li', [
-                element('code', file.name),
-                ' ',
-                element('small', {class: 'filesize'}, '(' + this._fileSizeFormatter(file.size) + ')'),
-                meta,
-            ]);
-        }));
-        return uploadStatusElements;
-    }
-
-    _updateUploadStatus(uploadStatusElements)
-    {
-        for (let entry of uploadStatusElements) {
-            const progress = this._uploadProgress.get(entry.file);
-            const progressBar = entry.progressBar;
-            if (!progress) {
-                progressBar.removeAttribute('max');
-                progressBar.removeAttribute('value');
-                return;
-            }
-            if (progress.error) {
-                entry.meta.classList.add('hasError');
-                entry.meta.textContent = this._formatUploadError(progress.error);
-            } else {
-                progressBar.max = progress.total;
-                progressBar.value = progress.loaded;
-            }
-        }
-    }
-
-    _formatUploadError(error)
-    {
-        switch (error) {
-        case 'NotSupported':
-            return 'Failed: File uploading is disabled';
-        case 'FileSizeLimitExceeded':
-            return 'Failed: The uploaded file was too big';
-        case 'FileSizeQuotaExceeded':
-            return 'Failed: Exceeded file upload quota';
-        }
-        return 'Failed to upload the file';
-    }
-
-    _didFileInputChange(input)
-    {
-        if (!input.files.length)
-            return;
-        const limit = UploadedFile.fileUploadSizeLimit;
-        for (let file of input.files) {
-            if (file.size > limit) {
-                alert(`The specified file "${file.name}" is too big (${this._fileSizeFormatter(file.size)}). It must be smaller than ${this._fileSizeFormatter(limit)}`);
-                input.value = null;
-                return;
-            }
-            UploadedFile.fetchUnloadedFileWithIdenticalHash(file).then((uploadedFile) => {
-                if (uploadedFile) {
-                    this._didUploadFile(file, uploadedFile);
-                    return;
-                }
-
-                UploadedFile.uploadFile(file, (progress) => {
-                    this._uploadProgress.set(file, progress);
-                    this.enqueueToRender();
-                }).then((uploadedFile) => {
-                    this._didUploadFile(file, uploadedFile);
-                }, (error) => {
-                    this._uploadProgress.set(file, {error: error === 0 ? 'UnknownError' : error});
-                    this.enqueueToRender();
-                });
-            });
-        }
-        this._preuploadFiles = Array.from(input.files);
-        input.value = null;
-
-        this.enqueueToRender();
-    }
-
-    _removeUploadedFile(uploadedFile)
-    {
-        // FIXME: Send a request to delete the file.
-        console.assert(uploadedFile instanceof UploadedFile);
-        const index = this._uploadedFiles.indexOf(uploadedFile);
-        if (index < 0)
-            return;
-        this._uploadedFiles.splice(index, 1);
-        this.dispatchAction('removedFile', uploadedFile);
-        this.enqueueToRender();
-    }
-
-    _didUploadFile(file, uploadedFile)
-    {
-        console.assert(file instanceof File);
-        const index = this._preuploadFiles.indexOf(file);
-        if (index >= 0)
-            this._preuploadFiles.splice(index, 1);
-        this._uploadedFiles.push(uploadedFile);
-        this.dispatchAction('uploadedFile', uploadedFile);
-        this.enqueueToRender();
-    }
-
-    static htmlTemplate()
-    {
-        return `<ul id="uploaded-files"></ul>
-            <ul id="preupload-files"></ul>
-            <input id="file-input" type="file" multiple="false">`;
-    }
-
-    static cssTemplate()
-    {
-        return `
-            ul:empty {
-                display: none;
-            }
-
-            ul, li {
-                margin: 0;
-                padding: 0;
-                list-style: none;
-            }
-
-            li {
-                position: relative;
-                margin-bottom: 0.25rem;
-                padding-left: 1.5rem;
-                padding-bottom: 0.25rem;
-                border-bottom: solid 1px #eee;
-            }
-
-            li:last-child {
-                border-bottom: none;
-            }
-
-            li > close-button {
-                position: absolute;
-                left: 0;
-                top: 50%;
-                margin-top: -0.5rem;
-            }
-
-            li > progress {
-                display: block;
-            }
-
-            code {
-                font-size: 1.1rem;
-                font-weight: inherit;
-            }
-
-            small {
-                font-size: 0.8rem;
-                font-weight: inherit;
-                color: #666;
-            }
-
-            small.meta {
-                display: block;
-            }
-
-            .hasError {
-                color: #c60;
-                font-weight: normal;
-            }
-        `;
-    }
-}
-
-ComponentBase.defineElement('instant-file-uploader', InstantFileUploader);
\ No newline at end of file