WebKit Bugzilla
Attachment 338972 Details for
Bug 184958
: Extend create-analysis-task API to be able to create with confirming test group.
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-184958-20180426222813.patch (text/plain), 52.58 KB, created by
dewei_zhu
on 2018-04-26 22:28:14 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
dewei_zhu
Created:
2018-04-26 22:28:14 PDT
Size:
52.58 KB
patch
obsolete
>Subversion Revision: 231084 >diff --git a/Websites/perf.webkit.org/ChangeLog b/Websites/perf.webkit.org/ChangeLog >index 82e2b48140fa35074e826c0706cf056c55b9a5de..7cc77807cd0716dfd59567a1a5c5efbec7c2bca2 100644 >--- a/Websites/perf.webkit.org/ChangeLog >+++ b/Websites/perf.webkit.org/ChangeLog >@@ -1,3 +1,49 @@ >+2018-04-26 Dewei Zhu <dewei_zhu@apple.com> >+ >+ Extend create-analysis-test API to be able to create with confirming test group. >+ https://bugs.webkit.org/show_bug.cgi?id=184958 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Extend create-analysis-test API to be able to create an analysis task with confirming test group. >+ Update create analysis task UI in chart pane to adapt this new API. >+ Refactored '/privileged-api/create-test-group' API to share some creating test group logic with '/privileged-api/create-analysis-task' API. >+ Moved the shared logic to commit-sets-helpers.php. >+ >+ * public/api/analysis-tasks.php: Use 'require_once' instead of 'require'. >+ * public/include/commit-sets-helpers.php: Added. >+ (create_test_group_and_build_requests): A helper function that creates test group and build requests for a analysis >+ task. In long term, this should be a class to avoid passing long argument list around. >+ (insert_commit_sets_and_construct_configuration_list): Based on commit sets returns build and test configurations. >+ (insert_build_request_for_configuration): Insert build requests based on configuration. >+ (commit_sets_from_revision_sets): Returns commit sets from given revision set list. >+ * public/privileged-api/create-analysis-task.php: Added the ability to create analysis task with confirming test >+ groups when repetition count is specified. >+ * public/privileged-api/create-test-group.php: Moved shared function to commit-sets-helpers.php. >+ * public/v3/models/analysis-task.js: >+ (AnalysisTask.create): Instead of accepting run ids, it now accepts points and test group name and confirming iterations. >+ It will conditionally add test group information into parameter when confirming iterations is a positive number. >+ (AnalysisTask): >+ * public/v3/models/commit-set.js: >+ (CommitSet.revisionSetsFromCommitSets): Move 'TestGroup._revisionSetsFromCommitSets' since CommitSet class is more >+ appropriate place and it will be shared by both TestGroup and AnalysisTask >+ (CommitSet): >+ * public/v3/models/test-group.js: >+ (TestGroup.createWithTask): Adapt 'CommitSet.revisionSetsFromCommitSets'. >+ (TestGroup.createWithCustomConfiguration): Adapt 'CommitSet.revisionSetsFromCommitSets'. >+ (TestGroup.createAndRefetchTestGroups): Adapt 'CommitSet.revisionSetsFromCommitSets'. >+ (TestGroup._revisionSetsFromCommitSets): Deleted and moved to 'CommitSet.revisionSetsFromCommitSets'. >+ * public/v3/pages/chart-pane.js: >+ (ChartPane.prototype.didConstructShadowTree): Added the logic to disable options when checkbox for creating confirming >+ test group is unchecked. >+ (ChartPane.prototype._analyzeRange): Conditionally create confirming test group from UI. >+ (ChartPane.cssTemplate): >+ * server-tests/privileged-api-create-analysis-task-tests.js: Added unit tests. Added a unit test for 'NodePrivilegedAPI'. >+ * unit-tests/analysis-task-tests.js: Added unit tests. >+ * unit-tests/commit-set-tests.js: Added unit test for 'CommitSet.revisionSetsFromCommitSets'. >+ * unit-tests/resources/mock-remote-api.js: Reset csrf token when BrowserPrivilegedAPI is used. >+ (MockRemoteAPI.inject): >+ > 2018-04-23 Dewei Zhu <dewei_zhu@apple.com> > > Tool scripts should not use PrivilegedAPI from 'public/v3/privileged-api.js'. >diff --git a/Websites/perf.webkit.org/public/api/analysis-tasks.php b/Websites/perf.webkit.org/public/api/analysis-tasks.php >index 352f72391ec3c647b93d9585f8f804bc615c69a1..160cff4821c09fae2ef4f9f05bf5e5e131c01ff5 100644 >--- a/Websites/perf.webkit.org/public/api/analysis-tasks.php >+++ b/Websites/perf.webkit.org/public/api/analysis-tasks.php >@@ -1,7 +1,7 @@ > <?php > >-require('../include/json-header.php'); >-require('../include/commit-log-fetcher.php'); >+require_once('../include/json-header.php'); >+require_once('../include/commit-log-fetcher.php'); > > function main($path) { > $db = new Database; >diff --git a/Websites/perf.webkit.org/public/include/commit-sets-helpers.php b/Websites/perf.webkit.org/public/include/commit-sets-helpers.php >new file mode 100644 >index 0000000000000000000000000000000000000000..a6b93947c6fe70a808a62c929def36f4286cd1d2 >--- /dev/null >+++ b/Websites/perf.webkit.org/public/include/commit-sets-helpers.php >@@ -0,0 +1,159 @@ >+<?php >+require_once('repository-group-finder.php'); >+require_once('commit-log-fetcher.php'); >+ >+# FIXME: Should create a helper class for below 3 helper functions to avoid passing long argument list. >+function create_test_group_and_build_requests($db, $commit_sets, $task_id, $name, $author, $triggerable_id, $platform_id, $test_id, $repetition_count) { >+ >+ list ($build_configuration_list, $test_configuration_list) = insert_commit_sets_and_construct_configuration_list($db, $commit_sets); >+ >+ $group_id = $db->insert_row('analysis_test_groups', 'testgroup', >+ array('task' => $task_id, 'name' => $name, 'author' => $author)); >+ >+ $build_count = count($build_configuration_list); >+ $order = -$build_count; >+ foreach($build_configuration_list as $build_configuration) >+ insert_build_request_for_configuration($db, $build_configuration, $order++, $triggerable_id, $platform_id, NULL, $group_id); >+ >+ for ($i = 0; $i < $repetition_count; $i++) { >+ foreach($test_configuration_list as $test_configuration) >+ insert_build_request_for_configuration($db, $test_configuration, $order++, $triggerable_id, $platform_id, $test_id, $group_id); >+ } >+ return $group_id; >+} >+ >+function insert_commit_sets_and_construct_configuration_list($db, $commit_sets) >+{ >+ $repository_group_with_builds = array(); >+ $test_configuration_list = array(); >+ $build_configuration_list = array(); >+ >+ foreach ($commit_sets as $commit_list) { >+ $commit_set_id = $db->insert_row('commit_sets', 'commitset', array()); >+ $need_to_build = FALSE; >+ foreach ($commit_list['set'] as $commit_row) { >+ $commit_row['set'] = $commit_set_id; >+ $requires_build = $commit_row['requires_build']; >+ assert(is_bool($requires_build)); >+ $need_to_build = $need_to_build || $requires_build; >+ $db->insert_row('commit_set_items', 'commitset', $commit_row, 'commit'); >+ } >+ $repository_group = $commit_list['repository_group']; >+ if ($need_to_build) >+ $repository_group_with_builds[$repository_group] = TRUE; >+ array_push($test_configuration_list, array('commit_set' => $commit_set_id, 'repository_group' => $repository_group)); >+ } >+ >+ foreach ($test_configuration_list as &$config) { >+ if (array_get($repository_group_with_builds, $config['repository_group'])) >+ array_push($build_configuration_list, $config); >+ } >+ return array($build_configuration_list, $test_configuration_list); >+} >+ >+function insert_build_request_for_configuration($db, $configuration, $order, $triggerable_id, $platform_id, $test_id, $group_id) >+{ >+ $db->insert_row('build_requests', 'request', array( >+ 'triggerable' => $triggerable_id, >+ 'repository_group' => $configuration['repository_group'], >+ 'platform' => $platform_id, >+ 'test' => $test_id, >+ 'group' => $group_id, >+ 'order' => $order, >+ 'commit_set' => $configuration['commit_set'])); >+} >+ >+function commit_sets_from_revision_sets($db, $triggerable_id, $revision_set_list) >+{ >+ if (count($revision_set_list) < 2) >+ exit_with_error('InvalidRevisionSets', array('revisionSets' => $revision_set_list)); >+ >+ $finder = new RepositoryGroupFinder($db, $triggerable_id); >+ $commit_set_list = array(); >+ $repository_owner_list = array(); >+ $repositories_require_build = array(); >+ $commit_set_items_by_repository = array(); >+ foreach ($revision_set_list as $revision_set) { >+ if (!count($revision_set)) >+ exit_with_error('InvalidRevisionSets', array('revisionSets' => $revision_set_list)); >+ >+ $commit_set = array(); >+ $repository_list = array(); >+ $repository_with_patch = array(); >+ foreach ($revision_set as $repository_id => $data) { >+ if ($repository_id == 'customRoots') { >+ $file_id_list = $data; >+ foreach ($file_id_list as $file_id) { >+ if (!is_numeric($file_id) || !$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, 'patch_file' => NULL, 'requires_build' => FALSE, 'commit_owner' => NULL)); >+ } >+ continue; >+ } >+ if (!is_numeric($repository_id)) >+ exit_with_error('InvalidRepository', array('repository' => $repository_id)); >+ >+ if (!is_array($data)) >+ exit_with_error('InvalidRepositoryData', array('repository' => $repository_id, 'data' => $data)); >+ >+ $revision = array_get($data, 'revision'); >+ if (!$revision) >+ exit_with_error('InvalidRevision', array('repository' => $repository_id, 'data' => $data)); >+ $commit_id = CommitLogFetcher::find_commit_id_by_revision($db, $repository_id, $revision); >+ if ($commit_id < 0) >+ exit_with_error('AmbiguousRevision', array('repository' => $repository_id, 'revision' => $revision)); >+ if (!$commit_id) >+ exit_with_error('RevisionNotFound', array('repository' => $repository_id, 'revision' => $revision)); >+ >+ $owner_revision = array_get($data, 'ownerRevision'); >+ $patch_file_id = array_get($data, 'patch'); >+ if ($patch_file_id) { >+ if (!is_numeric($patch_file_id) || !$db->select_first_row('uploaded_files', 'file', array('id' => $patch_file_id))) >+ exit_with_error('InvalidPatchFile', array('patch' => $patch_file_id)); >+ array_push($repository_with_patch, $repository_id); >+ $repositories_require_build[$repository_id] = TRUE; >+ } >+ >+ $repository = NULL; >+ $owner_commit_id = NULL; >+ if ($owner_revision) { >+ $repository = $db->select_first_row('repositories', 'repository', array('id' => intval($repository_id))); >+ if (!$repository) >+ exit_with_error('RepositoryNotFound', array('repository' => $repository_id)); >+ $owner_commit = $db->select_first_row('commits', 'commit', array('repository' => $repository['repository_owner'], 'revision' => $owner_revision)); >+ if (!$owner_commit) >+ exit_with_error('InvalidOwnerRevision', array('repository' => $repository['repository_owner'], 'revision' => $owner_revision)); >+ if (!$db->select_first_row('commit_ownerships', 'commit', array('owned' => $commit_id, 'owner' => $owner_commit['commit_id']))) >+ exit_with_error('InvalidCommitOwnership', array('commitOwner' => $owner_commit['commit_id'], 'commitOwned' => $commit_id)); >+ $repositories_require_build[$repository_id] = TRUE; >+ $owner_commit_id = $owner_commit['commit_id']; >+ } >+ >+ array_push($commit_set, array('commit' => $commit_id, 'patch_file' => $patch_file_id, 'requires_build' => FALSE, 'commit_owner' => $owner_commit_id)); >+ >+ array_ensure_item_has_array($commit_set_items_by_repository, $repository_id); >+ $commit_set_items_by_repository[$repository_id][] = &$commit_set[count($commit_set) - 1]; >+ >+ if ($owner_commit_id) >+ continue; >+ array_push($repository_list, $repository_id); >+ } >+ $repository_group_id = $finder->find_by_repositories($repository_list); >+ if (!$repository_group_id) >+ exit_with_error('NoMatchingRepositoryGroup', array('repositories' => $repository_list)); >+ >+ foreach ($repository_with_patch as $repository_id) { >+ if (!$finder->accepts_patch($repository_group_id, $repository_id)) >+ exit_with_error('PatchNotAccepted', array('repository' => $repository_id, 'repositoryGroup' => $repository_group_id)); >+ } >+ >+ array_push($commit_set_list, array('repository_group' => $repository_group_id, 'set' => $commit_set)); >+ } >+ >+ foreach (array_keys($repositories_require_build) as $repository_id) { >+ foreach($commit_set_items_by_repository[$repository_id] as &$commit_set_item) >+ $commit_set_item['requires_build'] = TRUE; >+ } >+ return $commit_set_list; >+} >+?> >\ No newline at end of file >diff --git a/Websites/perf.webkit.org/public/privileged-api/create-analysis-task.php b/Websites/perf.webkit.org/public/privileged-api/create-analysis-task.php >index 408507a6c6cffe4f8c28f3bfae363ecd8b0c16ca..55080b95f0b85fed8edacb28049bb2f48e363158 100644 >--- a/Websites/perf.webkit.org/public/privileged-api/create-analysis-task.php >+++ b/Websites/perf.webkit.org/public/privileged-api/create-analysis-task.php >@@ -1,6 +1,7 @@ > <?php > > require_once('../include/json-header.php'); >+require_once('../include/commit-sets-helpers.php'); > > function main() { > $db = connect(); >@@ -8,6 +9,9 @@ function main() { > > $author = remote_user_name($data); > $name = array_get($data, 'name'); >+ $repetition_count = array_get($data, 'repetitionCount'); >+ $test_group_name = array_get($data, 'testGroupName'); >+ $revision_set_list = array_get($data, 'revisionSets'); > > $segmentation_name = array_get($data, 'segmentationStrategy'); > $test_range_name = array_get($data, 'testRangeStrategy'); >@@ -66,6 +70,19 @@ function main() { > 'end_run_time' => $end_run_time, > 'segmentation' => $segmentation_id, > 'test_range' => $test_range_id)); >+ >+ if ($repetition_count) { >+ $triggerable = find_triggerable_for_task($db, $task_id); >+ if (!$triggerable || !$triggerable['id']) >+ exit_with_error('TriggerableNotFoundForTask', array('task' => $task_id, 'platform' => $config['config_platform'])); >+ if ($triggerable['platform'] != $config['config_platform']) >+ exit_with_error('InconsistentPlatform', array('configPlatform' => $config['config_platform'], 'taskPlatform' => $triggerable['platform'])); >+ $triggerable_id = $triggerable['id']; >+ $test_id = $triggerable['test']; >+ $commit_sets = commit_sets_from_revision_sets($db, $triggerable_id, $revision_set_list); >+ create_test_group_and_build_requests($db, $commit_sets, $task_id, $test_group_name, $author, $triggerable_id, $config['config_platform'], $test_id, $repetition_count); >+ } >+ > $db->commit_transaction(); > > exit_with_success(array('taskId' => $task_id)); >diff --git a/Websites/perf.webkit.org/public/privileged-api/create-test-group.php b/Websites/perf.webkit.org/public/privileged-api/create-test-group.php >index fa55039796924c556017cd5f089a832db9a0a9c0..56b47558f80d3fed8da29c932aad86d7965d8958 100644 >--- a/Websites/perf.webkit.org/public/privileged-api/create-test-group.php >+++ b/Websites/perf.webkit.org/public/privileged-api/create-test-group.php >@@ -1,8 +1,7 @@ > <?php > > require_once('../include/json-header.php'); >-require_once('../include/commit-log-fetcher.php'); >-require_once('../include/repository-group-finder.php'); >+require_once('../include/commit-sets-helpers.php'); > > function main() > { >@@ -86,167 +85,13 @@ function main() > if ($task_name) > $task_id = $db->insert_row('analysis_tasks', 'task', array('name' => $task_name, 'author' => $author)); > >- $configuration_list = array(); >- $repository_group_with_builds = array(); >- foreach ($commit_sets as $commit_list) { >- $commit_set_id = $db->insert_row('commit_sets', 'commitset', array()); >- $need_to_build = FALSE; >- foreach ($commit_list['set'] as $commit_row) { >- $commit_row['set'] = $commit_set_id; >- $requires_build = $commit_row['requires_build']; >- assert(is_bool($requires_build)); >- $need_to_build = $need_to_build || $requires_build; >- $db->insert_row('commit_set_items', 'commitset', $commit_row, 'commit'); >- } >- $repository_group = $commit_list['repository_group']; >- if ($need_to_build) >- $repository_group_with_builds[$repository_group] = TRUE; >- array_push($configuration_list, array('commit_set' => $commit_set_id, 'repository_group' => $repository_group)); >- } >- >- $build_count = 0; >- foreach ($configuration_list as &$config_item) { >- if (array_get($repository_group_with_builds, $config_item['repository_group'])) { >- $config_item['need_to_build'] = TRUE; >- $build_count++; >- } >- } >- >- $group_id = $db->insert_row('analysis_test_groups', 'testgroup', >- array('task' => $task_id, 'name' => $name, 'author' => $author)); >- >- if ($build_count) { >- $order = -$build_count; >- foreach ($configuration_list as $config) { >- if (!array_get($config, 'need_to_build')) >- continue; >- assert($order < 0); >- $db->insert_row('build_requests', 'request', array( >- 'triggerable' => $triggerable_id, >- 'repository_group' => $config['repository_group'], >- 'platform' => $platform_id, >- 'test' => NULL, >- 'group' => $group_id, >- 'order' => $order, >- 'commit_set' => $config['commit_set'])); >- $order++; >- } >- } >- >- $order = 0; >- for ($i = 0; $i < $repetition_count; $i++) { >- foreach ($configuration_list as $config) { >- $db->insert_row('build_requests', 'request', array( >- 'triggerable' => $triggerable_id, >- 'repository_group' => $config['repository_group'], >- 'platform' => $platform_id, >- 'test' => $test_id, >- 'group' => $group_id, >- 'order' => $order, >- 'commit_set' => $config['commit_set'])); >- $order++; >- } >- } >+ $group_id = create_test_group_and_build_requests($db, $commit_sets, $task_id, $name, $author, $triggerable_id, $platform_id, $test_id, $repetition_count); > > $db->commit_transaction(); > > exit_with_success(array('taskId' => $task_id, 'testGroupId' => $group_id)); > } > >-function commit_sets_from_revision_sets($db, $triggerable_id, $revision_set_list) >-{ >- if (count($revision_set_list) < 2) >- exit_with_error('InvalidRevisionSets', array('revisionSets' => $revision_set_list)); >- >- $finder = new RepositoryGroupFinder($db, $triggerable_id); >- $commit_set_list = array(); >- $repository_owner_list = array(); >- $repositories_require_build = array(); >- $commit_set_items_by_repository = array(); >- foreach ($revision_set_list as $revision_set) { >- if (!count($revision_set)) >- exit_with_error('InvalidRevisionSets', array('revisionSets' => $revision_set_list)); >- >- $commit_set = array(); >- $repository_list = array(); >- $repository_with_patch = array(); >- foreach ($revision_set as $repository_id => $data) { >- if ($repository_id == 'customRoots') { >- $file_id_list = $data; >- foreach ($file_id_list as $file_id) { >- if (!is_numeric($file_id) || !$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, 'patch_file' => NULL, 'requires_build' => FALSE, 'commit_owner' => NULL)); >- } >- continue; >- } >- if (!is_numeric($repository_id)) >- exit_with_error('InvalidRepository', array('repository' => $repository_id)); >- >- if (!is_array($data)) >- exit_with_error('InvalidRepositoryData', array('repository' => $repository_id, 'data' => $data)); >- >- $revision = array_get($data, 'revision'); >- if (!$revision) >- exit_with_error('InvalidRevision', array('repository' => $repository_id, 'data' => $data)); >- $commit_id = CommitLogFetcher::find_commit_id_by_revision($db, $repository_id, $revision); >- if ($commit_id < 0) >- exit_with_error('AmbiguousRevision', array('repository' => $repository_id, 'revision' => $revision)); >- if (!$commit_id) >- exit_with_error('RevisionNotFound', array('repository' => $repository_id, 'revision' => $revision)); >- >- $owner_revision = array_get($data, 'ownerRevision'); >- $patch_file_id = array_get($data, 'patch'); >- if ($patch_file_id) { >- if (!is_numeric($patch_file_id) || !$db->select_first_row('uploaded_files', 'file', array('id' => $patch_file_id))) >- exit_with_error('InvalidPatchFile', array('patch' => $patch_file_id)); >- array_push($repository_with_patch, $repository_id); >- $repositories_require_build[$repository_id] = TRUE; >- } >- >- $repository = NULL; >- $owner_commit_id = NULL; >- if ($owner_revision) { >- $repository = $db->select_first_row('repositories', 'repository', array('id' => intval($repository_id))); >- if (!$repository) >- exit_with_error('RepositoryNotFound', array('repository' => $repository_id)); >- $owner_commit = $db->select_first_row('commits', 'commit', array('repository' => $repository['repository_owner'], 'revision' => $owner_revision)); >- if (!$owner_commit) >- exit_with_error('InvalidOwnerRevision', array('repository' => $repository['repository_owner'], 'revision' => $owner_revision)); >- if (!$db->select_first_row('commit_ownerships', 'commit', array('owned' => $commit_id, 'owner' => $owner_commit['commit_id']))) >- exit_with_error('InvalidCommitOwnership', array('commitOwner' => $owner_commit['commit_id'], 'commitOwned' => $commit_id)); >- $repositories_require_build[$repository_id] = TRUE; >- $owner_commit_id = $owner_commit['commit_id']; >- } >- >- array_push($commit_set, array('commit' => $commit_id, 'patch_file' => $patch_file_id, 'requires_build' => FALSE, 'commit_owner' => $owner_commit_id)); >- >- array_ensure_item_has_array($commit_set_items_by_repository, $repository_id); >- $commit_set_items_by_repository[$repository_id][] = &$commit_set[count($commit_set) - 1]; >- >- if ($owner_commit_id) >- continue; >- array_push($repository_list, $repository_id); >- } >- $repository_group_id = $finder->find_by_repositories($repository_list); >- if (!$repository_group_id) >- exit_with_error('NoMatchingRepositoryGroup', array('repositories' => $repository_list)); >- >- foreach ($repository_with_patch as $repository_id) { >- if (!$finder->accepts_patch($repository_group_id, $repository_id)) >- exit_with_error('PatchNotAccepted', array('repository' => $repository_id, 'repositoryGroup' => $repository_group_id)); >- } >- >- array_push($commit_set_list, array('repository_group' => $repository_group_id, 'set' => $commit_set)); >- } >- >- foreach (array_keys($repositories_require_build) as $repository_id) { >- foreach($commit_set_items_by_repository[$repository_id] as &$commit_set_item) >- $commit_set_item['requires_build'] = TRUE; >- } >- return $commit_set_list; >-} >- > function ensure_commit_sets($db, $triggerable_id, $commit_sets_info) { > $repository_name_to_id = array(); > foreach ($db->select_rows('repositories', 'repository', array('owner' => NULL)) as $row) >diff --git a/Websites/perf.webkit.org/public/v3/models/analysis-task.js b/Websites/perf.webkit.org/public/v3/models/analysis-task.js >index 0179be179fa03d18bed408558dac27feb409a6ff..41b25f99940082a89421ed09cc09f3dd7de1b4c5 100644 >--- a/Websites/perf.webkit.org/public/v3/models/analysis-task.js >+++ b/Websites/perf.webkit.org/public/v3/models/analysis-task.js >@@ -303,13 +303,16 @@ class AnalysisTask extends LabeledObject { > return results; > } > >- static create(name, startRunId, endRunId) >+ static create(name, startPoint, endPoint, testGroupName, repetitionCount) > { >- return PrivilegedAPI.sendRequest('create-analysis-task', { >- name: name, >- startRun: startRunId, >- endRun: endRunId, >- }); >+ const parameters = {name, startRun: startPoint.id, endRun: endPoint.id}; >+ if (repetitionCount) { >+ console.assert(testGroupName); >+ parameters['revisionSets'] = CommitSet.revisionSetsFromCommitSets([startPoint.commitSet(), endPoint.commitSet()]); >+ parameters['repetitionCount'] = repetitionCount; >+ parameters['testGroupName'] = testGroupName; >+ } >+ return PrivilegedAPI.sendRequest('create-analysis-task', parameters); > } > } > >diff --git a/Websites/perf.webkit.org/public/v3/models/commit-set.js b/Websites/perf.webkit.org/public/v3/models/commit-set.js >index 8112d56d22cdff808b99e7a9239871d722f143cd..29a98256d0f3132f063a701a7c52b11c02af6966 100644 >--- a/Websites/perf.webkit.org/public/v3/models/commit-set.js >+++ b/Websites/perf.webkit.org/public/v3/models/commit-set.js >@@ -242,6 +242,26 @@ class CommitSet extends DataModelObject { > > return nameParts.join(' '); > } >+ >+ static revisionSetsFromCommitSets(commitSets) >+ { >+ return commitSets.map((commitSet) => { >+ console.assert(commitSet instanceof CustomCommitSet || commitSet instanceof CommitSet); >+ const revisionSet = {}; >+ for (let repository of commitSet.repositories()) { >+ const patchFile = commitSet.patchForRepository(repository); >+ revisionSet[repository.id()] = { >+ revision: commitSet.revisionForRepository(repository), >+ ownerRevision: commitSet.ownerRevisionForRepository(repository), >+ patch: patchFile ? patchFile.id() : null, >+ }; >+ } >+ const customRoots = commitSet.customRoots(); >+ if (customRoots && customRoots.length) >+ revisionSet['customRoots'] = customRoots.map((uploadedFile) => uploadedFile.id()); >+ return revisionSet; >+ }); >+ } > } > > class MeasurementCommitSet extends CommitSet { >diff --git a/Websites/perf.webkit.org/public/v3/models/test-group.js b/Websites/perf.webkit.org/public/v3/models/test-group.js >index e821670adf1540e3ce3b5c1c645977566aec0a0d..e09f142fcdd5d5928deba28e37b6c9c1a35fa8c3 100644 >--- a/Websites/perf.webkit.org/public/v3/models/test-group.js >+++ b/Websites/perf.webkit.org/public/v3/models/test-group.js >@@ -188,7 +188,7 @@ class TestGroup extends LabeledObject { > static createWithTask(taskName, platform, test, groupName, repetitionCount, commitSets) > { > console.assert(commitSets.length == 2); >- const revisionSets = this._revisionSetsFromCommitSets(commitSets); >+ const revisionSets = CommitSet.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']); >@@ -200,7 +200,7 @@ class TestGroup extends LabeledObject { > static createWithCustomConfiguration(task, platform, test, groupName, repetitionCount, commitSets) > { > console.assert(commitSets.length == 2); >- const revisionSets = this._revisionSetsFromCommitSets(commitSets); >+ const revisionSets = CommitSet.revisionSetsFromCommitSets(commitSets); > const params = {task: task.id(), name: groupName, platform: platform.id(), test: test.id(), repetitionCount, revisionSets}; > return PrivilegedAPI.sendRequest('create-test-group', params).then((data) => { > return this.fetchForTask(data['taskId'], true); >@@ -210,7 +210,7 @@ class TestGroup extends LabeledObject { > static createAndRefetchTestGroups(task, name, repetitionCount, commitSets) > { > console.assert(commitSets.length == 2); >- const revisionSets = this._revisionSetsFromCommitSets(commitSets); >+ const revisionSets = CommitSet.revisionSetsFromCommitSets(commitSets); > return PrivilegedAPI.sendRequest('create-test-group', { > task: task.id(), > name: name, >@@ -219,26 +219,6 @@ class TestGroup extends LabeledObject { > }).then((data) => this.fetchForTask(data['taskId'], true)); > } > >- static _revisionSetsFromCommitSets(commitSets) >- { >- return commitSets.map((commitSet) => { >- console.assert(commitSet instanceof CustomCommitSet || commitSet instanceof CommitSet); >- const revisionSet = {}; >- for (let repository of commitSet.repositories()) { >- const patchFile = commitSet.patchForRepository(repository); >- revisionSet[repository.id()] = { >- revision: commitSet.revisionForRepository(repository), >- ownerRevision: commitSet.ownerRevisionForRepository(repository), >- patch: patchFile ? patchFile.id() : null, >- }; >- } >- const customRoots = commitSet.customRoots(); >- if (customRoots && customRoots.length) >- revisionSet['customRoots'] = customRoots.map((uploadedFile) => uploadedFile.id()); >- return revisionSet; >- }); >- } >- > static findAllByTask(taskId) > { > return TestGroup.all().filter((testGroup) => testGroup._taskId == taskId); >diff --git a/Websites/perf.webkit.org/public/v3/pages/chart-pane.js b/Websites/perf.webkit.org/public/v3/pages/chart-pane.js >index f32bdec80f467dfa6322b3a0f3e563c932a8cabd..cfde8f3f50a245d08ce33910464017b3a4846dbb 100644 >--- a/Websites/perf.webkit.org/public/v3/pages/chart-pane.js >+++ b/Websites/perf.webkit.org/public/v3/pages/chart-pane.js >@@ -116,7 +116,10 @@ class ChartPane extends ChartPaneBase { > { > this.part('close').listenToAction('activate', () => { > this._chartsPage.closePane(this); >- }) >+ }); >+ const createWithConfirmingTestGroupCheckbox = this.content('create-with-confirming-test-group'); >+ const repetitionCount = this.content('confirm-repetition'); >+ createWithConfirmingTestGroupCheckbox.onchange = () => repetitionCount.disabled = !createWithConfirmingTestGroupCheckbox.checked; > } > > serializeState() >@@ -232,8 +235,10 @@ class ChartPane extends ChartPaneBase { > const newWindow = window.open(router.url('analysis/task/create', {inProgress: true}), '_blank'); > > const analyzePopover = this.content().querySelector('.chart-pane-analyze-popover'); >- const name = analyzePopover.querySelector('input').value; >- AnalysisTask.create(name, startPoint.id, endPoint.id).then((data) => { >+ const name = analyzePopover.querySelector('input[type=text]').value; >+ const createWithConfirmingTestGroup = analyzePopover.querySelector('input[type=checkbox]').checked; >+ const repetitionCount = analyzePopover.querySelector('select').value; >+ AnalysisTask.create(name, startPoint, endPoint, 'Confirm', createWithConfirmingTestGroup ? repetitionCount : 0).then((data) => { > newWindow.location.href = router.url('analysis/task/' + data['taskId']); > this.fetchAnalysisTasks(true); > }, (error) => { >@@ -560,6 +565,23 @@ class ChartPane extends ChartPaneBase { > <form class="chart-pane-analyze-popover popover" style="display:none"> > <input type="text" required> > <button>Create</button> >+ <li> >+ <label><input type="checkbox" id="create-with-confirming-test-group" checked></label> >+ <label>Confirm with</label> >+ <select id="confirm-repetition"> >+ <option>1</option> >+ <option>2</option> >+ <option>3</option> >+ <option selected>4</option> >+ <option>5</option> >+ <option>6</option> >+ <option>7</option> >+ <option>8</option> >+ <option>9</option> >+ <option>10</option> >+ </select> >+ <label>iterations</label> >+ </li> > </form> > <ul class="chart-pane-filtering-options popover" style="display:none"> > <li><label><input type="checkbox" class="enable-sampling">Sampling</label></li> >@@ -619,7 +641,7 @@ class ChartPane extends ChartPaneBase { > padding: 0 0; > } > >- .chart-pane-actions ul { >+ .chart-pane-actions ul, form { > display: block; > padding: 0; > margin: 0 0.5rem; >@@ -710,6 +732,11 @@ class ChartPane extends ChartPaneBase { > outline: none; > border: solid 1px #ccc; > } >+ .chart-pane-actions .popover input[type=number] { >+ width: 2rem; >+ outline: none; >+ border: solid 1px #ccc; >+ } > `; > } > } >diff --git a/Websites/perf.webkit.org/server-tests/privileged-api-create-analysis-task-tests.js b/Websites/perf.webkit.org/server-tests/privileged-api-create-analysis-task-tests.js >index eb60d7b3a9781fb9a2713f830db185a27d29cd52..f5102140debd22510e9f98d4ba1911fa7fb2cd64 100644 >--- a/Websites/perf.webkit.org/server-tests/privileged-api-create-analysis-task-tests.js >+++ b/Websites/perf.webkit.org/server-tests/privileged-api-create-analysis-task-tests.js >@@ -105,7 +105,7 @@ const anotherReportWithRevisionNoTimestamp = [{ > }, > }}]; > >-describe('/privileged-api/create-analysis-task', function () { >+describe('/privileged-api/create-analysis-task with browser privileged api', function () { > prepareServerTest(this); > > it('should return "MissingName" on an empty request', () => { >@@ -334,4 +334,205 @@ describe('/privileged-api/create-analysis-task', function () { > }); > }); > >+ >+ it('should failed with "TriggerableNotFoundForTask" when there is no matching triggerable', async () => { >+ const db = TestServer.database(); >+ await addBuilderForReport(reportWithRevision[0]); >+ await TestServer.remoteAPI().postJSON('/api/report/', reportWithRevision); >+ await TestServer.remoteAPI().postJSON('/api/report/', anotherReportWithRevision); >+ await Manifest.fetch(); >+ >+ const test1 = Test.findByPath(['Suite', 'test1']); >+ const somePlatform = Platform.findByName('some platform'); >+ const configRow = await db.selectFirstRow('test_configurations', {metric: test1.metrics()[0].id(), platform: somePlatform.id()}); >+ const testRuns = await db.selectRows('test_runs', {config: configRow['id']}); >+ assert.equal(testRuns.length, 2); >+ >+ const webkitRepositoryRow = await db.selectFirstRow('repositories', {name: 'WebKit'}); >+ const webkitId = webkitRepositoryRow.id; >+ >+ const oneRevisionSet = {[webkitId]: {revision: '191622'}}; >+ const anotherRevisionSet = {[webkitId]: {revision: '191623'}}; >+ >+ let raiseException = false; >+ >+ try { >+ await PrivilegedAPI.sendRequest('create-analysis-task', {name: 'confirm', repetitionCount: 1, >+ revisionSets: [oneRevisionSet, anotherRevisionSet], >+ startRun: testRuns[0]['id'], endRun: testRuns[1]['id']}); >+ } catch (error) { >+ assert.equal(error, 'TriggerableNotFoundForTask'); >+ raiseException = true; >+ } >+ assert.ok(raiseException); >+ }); >+ >+ it('should create an analysis task with no test group when repetition count is 0', async () => { >+ const db = TestServer.database(); >+ await addBuilderForReport(reportWithRevision[0]); >+ await TestServer.remoteAPI().postJSON('/api/report/', reportWithRevision); >+ await TestServer.remoteAPI().postJSON('/api/report/', anotherReportWithRevision); >+ await Manifest.fetch(); >+ >+ const test1 = Test.findByPath(['Suite', 'test1']); >+ const platform = Platform.findByName('some platform'); >+ const configRow = await db.selectFirstRow('test_configurations', {metric: test1.metrics()[0].id(), platform: platform.id()}); >+ const testRuns = await db.selectRows('test_runs', {config: configRow['id']}); >+ assert.equal(testRuns.length, 2); >+ >+ const webkitRepositoryRow = await db.selectFirstRow('repositories', {name: 'WebKit'}); >+ const webkitId = webkitRepositoryRow.id; >+ >+ const oneRevisionSet = {[webkitId]: {revision: '191622'}}; >+ const anotherRevisionSet = {[webkitId]: {revision: '191623'}}; >+ >+ const content = await PrivilegedAPI.sendRequest('create-analysis-task', {name: 'confirm', repetitionCount: 0, >+ revisionSets: [oneRevisionSet, anotherRevisionSet], >+ startRun: testRuns[0]['id'], endRun: testRuns[1]['id']}); >+ >+ TestServer.cleanDataDirectory(); >+ await Manifest.fetch(); >+ >+ const task = await AnalysisTask.fetchById(content['taskId']); >+ assert.equal(task.name(), 'confirm'); >+ assert(!task.hasResults()); >+ assert(!task.hasPendingRequests()); >+ assert.deepEqual(task.bugs(), []); >+ assert.deepEqual(task.causes(), []); >+ assert.deepEqual(task.fixes(), []); >+ assert.equal(task.changeType(), null); >+ assert.equal(task.platform().label(), 'some platform'); >+ assert.equal(task.metric().test().label(), 'test1'); >+ >+ const testGroups = await TestGroup.fetchForTask(task.id()); >+ assert.equal(testGroups.length, 0); >+ }); >+ >+ it('should create an analysis task with test group when commit set list and a positive repetition count is specified', async () => { >+ const webkitId = 1; >+ const platformId = 1; >+ const test1Id = 2; >+ const triggerableId = 1234; >+ >+ const db = TestServer.database(); >+ await db.insert('tests', {id: 1, name: 'Suite'}); >+ await db.insert('tests', {id: test1Id, name: 'test1', parent: 1}); >+ await db.insert('repositories', {id: webkitId, name: 'WebKit'}); >+ await db.insert('platforms', {id: platformId, name: 'some platform'}); >+ await db.insert('build_triggerables', {id: 1234, name: 'test-triggerable'}); >+ await db.insert('triggerable_repository_groups', {id: 2345, name: 'webkit-only', triggerable: triggerableId}); >+ await db.insert('triggerable_repositories', {repository: webkitId, group: 2345}); >+ await db.insert('triggerable_configurations', {test: test1Id, platform: platformId, triggerable: triggerableId}); >+ await addBuilderForReport(reportWithRevision[0]); >+ >+ await TestServer.remoteAPI().postJSON('/api/report/', reportWithRevision); >+ await TestServer.remoteAPI().postJSON('/api/report/', anotherReportWithRevision); >+ await Manifest.fetch(); >+ >+ let test1 = Test.findById(test1Id); >+ let somePlatform = Platform.findById(platformId); >+ const configRow = await db.selectFirstRow('test_configurations', {metric: test1.metrics()[0].id(), platform: somePlatform.id()}); >+ const testRuns = await db.selectRows('test_runs', {config: configRow['id']}); >+ assert.equal(testRuns.length, 2); >+ >+ const oneRevisionSet = {[webkitId]: {revision: '191622'}}; >+ const anotherRevisionSet = {[webkitId]: {revision: '191623'}}; >+ >+ const content = await PrivilegedAPI.sendRequest('create-analysis-task', {name: 'confirm', repetitionCount: 1, >+ testGroupName: 'Confirm', revisionSets: [oneRevisionSet, anotherRevisionSet], >+ startRun: testRuns[0]['id'], endRun: testRuns[1]['id']}); >+ >+ const task = await AnalysisTask.fetchById(content['taskId']); >+ assert.equal(task.name(), 'confirm'); >+ assert(!task.hasResults()); >+ assert(task.hasPendingRequests()); >+ assert.deepEqual(task.bugs(), []); >+ assert.deepEqual(task.causes(), []); >+ assert.deepEqual(task.fixes(), []); >+ assert.equal(task.changeType(), null); >+ assert.equal(task.platform().label(), 'some platform'); >+ assert.equal(task.metric().test().label(), 'test1'); >+ >+ const testGroups = await TestGroup.fetchForTask(task.id()); >+ assert.equal(testGroups.length, 1); >+ const testGroup = testGroups[0]; >+ assert.equal(testGroup.name(), 'Confirm'); >+ const buildRequests = testGroup.buildRequests(); >+ assert.equal(buildRequests.length, 2); >+ >+ assert.equal(buildRequests[0].triggerable().id(), triggerableId); >+ assert.equal(buildRequests[0].triggerable().id(), triggerableId); >+ >+ assert.equal(buildRequests[0].testGroup(), testGroup); >+ assert.equal(buildRequests[1].testGroup(), testGroup); >+ >+ assert.equal(buildRequests[0].platform(), task.platform()); >+ assert.equal(buildRequests[1].platform(), task.platform()); >+ >+ assert.equal(buildRequests[0].analysisTaskId(), task.id()); >+ assert.equal(buildRequests[1].analysisTaskId(), task.id()); >+ >+ assert.equal(buildRequests[0].test(), test1); >+ assert.equal(buildRequests[1].test(), test1); >+ >+ assert.ok(!buildRequests[0].isBuild()); >+ assert.ok(!buildRequests[1].isBuild()); >+ assert.ok(buildRequests[0].isTest()); >+ assert.ok(buildRequests[1].isTest()); >+ >+ const firstCommitSet = buildRequests[0].commitSet(); >+ const secondCommitSet = buildRequests[1].commitSet(); >+ const webkitRepository = Repository.findById(webkitId); >+ assert.equal(firstCommitSet.commitForRepository(webkitRepository).revision(), '191622'); >+ assert.equal(secondCommitSet.commitForRepository(webkitRepository).revision(), '191623'); >+ }); >+}); >+ >+describe('/privileged-api/create-analysis-task with node privileged api', function () { >+ prepareServerTest(this, 'node'); >+ beforeEach(() => { >+ PrivilegedAPI.configure('test', 'password'); >+ }); >+ >+ it('should return "SlaveNotFound" when incorrect slave user and password combination is provided and no analysis task, test group or build request should be created', async () => { >+ PrivilegedAPI.configure('test', 'wrongpassword'); >+ const db = TestServer.database(); >+ await addBuilderForReport(reportWithRevision[0]); >+ await TestServer.remoteAPI().postJSON('/api/report/', reportWithRevision); >+ await TestServer.remoteAPI().postJSON('/api/report/', anotherReportWithRevision); >+ await Manifest.fetch(); >+ >+ const test1 = Test.findByPath(['Suite', 'test1']); >+ const somePlatform = Platform.findByName('some platform'); >+ const configRow = await db.selectFirstRow('test_configurations', {metric: test1.metrics()[0].id(), platform: somePlatform.id()}); >+ const testRuns = await db.selectRows('test_runs', {config: configRow['id']}); >+ assert.equal(testRuns.length, 2); >+ >+ const webkitRepositoryRow = await db.selectFirstRow('repositories', {name: 'WebKit'}); >+ const webkitId = webkitRepositoryRow.id; >+ >+ const oneRevisionSet = {[webkitId]: {revision: '191622'}}; >+ const anotherRevisionSet = {[webkitId]: {revision: '191623'}}; >+ >+ let raiseException = false; >+ >+ try { >+ await PrivilegedAPI.sendRequest('create-analysis-task', {name: 'confirm', repetitionCount: 1, >+ revisionSets: [oneRevisionSet, anotherRevisionSet], >+ startRun: testRuns[0]['id'], endRun: testRuns[1]['id']}); >+ } catch (error) { >+ assert.equal(error, 'SlaveNotFound'); >+ raiseException = true; >+ } >+ assert.ok(raiseException); >+ >+ const allAnalysisTasks = await db.selectRows('analysis_tasks'); >+ assert.ok(!allAnalysisTasks.length); >+ >+ const allTestGroups = await db.selectRows('analysis_test_groups'); >+ assert.ok(!allTestGroups.length); >+ >+ const allBuildRequests = await db.selectRows('build_requests'); >+ assert.ok(!allBuildRequests.length); >+ }); > }); >diff --git a/Websites/perf.webkit.org/unit-tests/analysis-task-tests.js b/Websites/perf.webkit.org/unit-tests/analysis-task-tests.js >index d696f68ff53aa422574f1ac264b5d955df6731c0..5d499ab3597f8155c257b49d1bae9b8a580f6515 100644 >--- a/Websites/perf.webkit.org/unit-tests/analysis-task-tests.js >+++ b/Websites/perf.webkit.org/unit-tests/analysis-task-tests.js >@@ -121,9 +121,15 @@ function measurementCluster() > > describe('AnalysisTask', () => { > MockModels.inject(); >- let requests = MockRemoteAPI.inject(); >+ function makeMockPoints(id, commitSet) { >+ return { >+ id, >+ commitSet: () => commitSet >+ } >+ } > > describe('fetchAll', () => { >+ const requests = MockRemoteAPI.inject(); > it('should request all analysis tasks', () => { > let callCount = 0; > AnalysisTask.fetchAll().then(() => { callCount++; }); >@@ -224,4 +230,89 @@ describe('AnalysisTask', () => { > }); > }); > }); >+ >+ >+ function mockStartAndEndPoints() { >+ const startPoint = makeMockPoints(1, new MeasurementCommitSet(1, [ >+ [1, MockModels.ios.id(), 'ios-revision-1', null, 0], >+ [3, MockModels.webkit.id(), 'webkit-revision-1', null, 0] >+ ])); >+ const endPoint = makeMockPoints(2, new MeasurementCommitSet(2, [ >+ [2, MockModels.ios.id(), 'ios-revision-2', null, 0], >+ [4, MockModels.webkit.id(), 'webkit-revision-2', null, 0] >+ ])); >+ return [startPoint, endPoint]; >+ } >+ >+ describe('create with browser privilege api', () => { >+ const requests = MockRemoteAPI.inject(); >+ >+ it('should create analysis task with confirming repetition count zero as default with browser privilege api', async () => { >+ const [startPoint, endPoint] = mockStartAndEndPoints(); >+ AnalysisTask.create('confirm', startPoint, endPoint); >+ assert.equal(requests.length, 1); >+ assert.equal(requests[0].url, '/privileged-api/generate-csrf-token'); >+ requests[0].resolve({ >+ token: 'abc', >+ expiration: Date.now() + 3600 * 1000, >+ }); >+ >+ await MockRemoteAPI.waitForRequest(); >+ assert.equal(requests[1].url, '/privileged-api/create-analysis-task'); >+ assert.equal(requests.length, 2); >+ assert.deepEqual(requests[1].data, {name: 'confirm', startRun: 1, endRun: 2, token: 'abc'}); >+ }); >+ >+ it('should create analysis task with confirming repetition count specified', async () => { >+ const [startPoint, endPoint] = mockStartAndEndPoints(); >+ AnalysisTask.create('confirm', startPoint, endPoint, 'Confirm', 4); >+ assert.equal(requests.length, 1); >+ assert.equal(requests[0].url, '/privileged-api/generate-csrf-token'); >+ requests[0].resolve({ >+ token: 'abc', >+ expiration: Date.now() + 3600 * 1000, >+ }); >+ >+ await MockRemoteAPI.waitForRequest(); >+ assert.equal(requests[1].url, '/privileged-api/create-analysis-task'); >+ assert.equal(requests.length, 2); >+ assert.deepEqual(requests[1].data, {name: 'confirm', repetitionCount: 4, >+ startRun: 1, endRun: 2, testGroupName: 'Confirm', token: 'abc', revisionSets: [ >+ {'11': {revision: 'webkit-revision-1', ownerRevision: null, patch: null}, >+ '22': {revision: 'ios-revision-1', ownerRevision: null, patch: null}}, >+ {'11': {revision: 'webkit-revision-2', ownerRevision: null, patch: null}, >+ '22': { revision: 'ios-revision-2', ownerRevision: null, patch: null}}]} >+ ); >+ }); >+ }); >+ >+ describe('create with node privilege api', () => { >+ const requests = MockRemoteAPI.inject(null, 'node'); >+ beforeEach(() => { >+ PrivilegedAPI.configure('worker', 'password'); >+ }); >+ >+ it('should create analysis task with confirming repetition count zero as default with browser privilege api', () => { >+ const [startPoint, endPoint] = mockStartAndEndPoints(); >+ AnalysisTask.create('confirm', startPoint, endPoint); >+ assert.equal(requests[0].url, '/privileged-api/create-analysis-task'); >+ assert.equal(requests.length, 1); >+ assert.deepEqual(requests[0].data, {name: 'confirm', startRun: 1, endRun: 2, slaveName: 'worker', slavePassword: 'password'}); >+ }); >+ >+ it('should create analysis task with confirming repetition count specified', () => { >+ const [startPoint, endPoint] = mockStartAndEndPoints(); >+ AnalysisTask.create('confirm', startPoint, endPoint, 'Confirm', 4); >+ assert.equal(requests[0].url, '/privileged-api/create-analysis-task'); >+ assert.equal(requests.length, 1); >+ assert.deepEqual(requests[0].data, {name: 'confirm', repetitionCount: 4, >+ startRun: 1, endRun: 2, slaveName: 'worker', slavePassword: 'password', >+ testGroupName: 'Confirm', revisionSets: [ >+ {'11': {revision: 'webkit-revision-1', ownerRevision: null, patch: null}, >+ '22': {revision: 'ios-revision-1', ownerRevision: null, patch: null}}, >+ {'11': {revision: 'webkit-revision-2', ownerRevision: null, patch: null}, >+ '22': { revision: 'ios-revision-2', ownerRevision: null, patch: null}}]} >+ ); >+ }); >+ }); > }); >diff --git a/Websites/perf.webkit.org/unit-tests/commit-set-tests.js b/Websites/perf.webkit.org/unit-tests/commit-set-tests.js >index 646deeda41acf413379416c392bf6071833cc392..a8f345fa8e034629cd5b8d01efcd2da057b40ee9 100644 >--- a/Websites/perf.webkit.org/unit-tests/commit-set-tests.js >+++ b/Websites/perf.webkit.org/unit-tests/commit-set-tests.js >@@ -387,6 +387,15 @@ describe('CommitSet', () => { > assert.equal(CommitSet.diff(oneCommitSet(), commitSetWithAnotherCommitPatchAndRoot()), 'WebKit: webkit-commit-0 with none - webkit-commit-1 with patch.dat Roots: none - root.dat, root.dat (2)'); > }); > }); >+ >+ describe('revisionSetsFromCommitSets', () => { >+ it('should create revision sets from commit sets', () => { >+ assert.deepEqual(CommitSet.revisionSetsFromCommitSets([oneCommitSet(), commitSetWithRoot(), commitSetWithTwoRoots()]), >+ [{'11': { revision: 'webkit-commit-0', ownerRevision: null, patch: null}}, >+ {'11': { revision: 'webkit-commit-0', ownerRevision: null, patch: null}, customRoots: [456]}, >+ {'11': { revision: 'webkit-commit-0', ownerRevision: null, patch: null}, customRoots: [456, 458]}]); >+ }); >+ }); > }); > > describe('IntermediateCommitSet', () => { >diff --git a/Websites/perf.webkit.org/unit-tests/resources/mock-remote-api.js b/Websites/perf.webkit.org/unit-tests/resources/mock-remote-api.js >index dc12782f939597b1d41e594c706e083ab6a94515..6bc10fb355605e5a1e7727f7d14212b5c4118b19 100644 >--- a/Websites/perf.webkit.org/unit-tests/resources/mock-remote-api.js >+++ b/Websites/perf.webkit.org/unit-tests/resources/mock-remote-api.js >@@ -65,7 +65,8 @@ var MockRemoteAPI = { > console.assert(privilegedAPIType === 'browser' || privilegedAPIType === 'node'); > let originalRemoteAPI = global.RemoteAPI; > let originalPrivilegedAPI = global.PrivilegedAPI; >- const PrivilegedAPI = privilegedAPIType === 'node' ? NodePrivilegedAPI: BrowserPrivilegedAPI; >+ const useNodePrivilegedAPI = privilegedAPIType === 'node'; >+ const PrivilegedAPI = useNodePrivilegedAPI ? NodePrivilegedAPI: BrowserPrivilegedAPI; > > beforeEach(() => { > MockRemoteAPI.reset(urlPrefix); >@@ -73,6 +74,8 @@ var MockRemoteAPI = { > global.RemoteAPI = MockRemoteAPI; > originalPrivilegedAPI = global.PrivilegedAPI; > global.PrivilegedAPI = PrivilegedAPI; >+ if (!useNodePrivilegedAPI) >+ PrivilegedAPI._token = null; > }); > > afterEach(() => {
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Flags:
rniwa
:
review+
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 184958
:
338713
|
338831
| 338972