⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 231087 in webkit


Ignore:
Timestamp:
Apr 26, 2018, 11:22:00 PM (8 years ago)
Author:
Dewei Zhu
Message:

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 Ryosuke Niwa.

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):

Location:
trunk/Websites/perf.webkit.org
Files:
1 added
12 edited

Legend:

Unmodified
Added
Removed
  • trunk/Websites/perf.webkit.org/ChangeLog

    r230960 r231087  
     12018-04-26  Dewei Zhu  <dewei_zhu@apple.com>
     2
     3        Extend create-analysis-test API to be able to create with confirming test group.
     4        https://bugs.webkit.org/show_bug.cgi?id=184958
     5
     6        Reviewed by Ryosuke Niwa.
     7
     8        Extend create-analysis-test API to be able to create an analysis task with confirming test group.
     9        Update create analysis task UI in chart pane to adapt this new API.
     10        Refactored '/privileged-api/create-test-group' API to share some creating test group logic with '/privileged-api/create-analysis-task' API.
     11        Moved the shared logic to commit-sets-helpers.php.
     12
     13        * public/api/analysis-tasks.php: Use 'require_once' instead of 'require'.
     14        * public/include/commit-sets-helpers.php: Added.
     15        (create_test_group_and_build_requests): A helper function that creates test group and build requests for a analysis
     16        task. In long term, this should be a class to avoid passing long argument list around.
     17        (insert_commit_sets_and_construct_configuration_list): Based on commit sets returns build and test configurations.
     18        (insert_build_request_for_configuration): Insert build requests based on configuration.
     19        (commit_sets_from_revision_sets): Returns commit sets from given revision set list.
     20        * public/privileged-api/create-analysis-task.php: Added the ability to create analysis task with confirming test
     21        groups when repetition count is specified.
     22        * public/privileged-api/create-test-group.php: Moved shared function to commit-sets-helpers.php.
     23        * public/v3/models/analysis-task.js:
     24        (AnalysisTask.create): Instead of accepting run ids, it now accepts points and test group name and confirming iterations.
     25        It will conditionally add test group information into parameter when confirming iterations is a positive number.
     26        (AnalysisTask):
     27        * public/v3/models/commit-set.js:
     28        (CommitSet.revisionSetsFromCommitSets): Move 'TestGroup._revisionSetsFromCommitSets' since CommitSet class is more
     29        appropriate place and it will be shared by both TestGroup and AnalysisTask
     30        (CommitSet):
     31        * public/v3/models/test-group.js:
     32        (TestGroup.createWithTask): Adapt 'CommitSet.revisionSetsFromCommitSets'.
     33        (TestGroup.createWithCustomConfiguration): Adapt 'CommitSet.revisionSetsFromCommitSets'.
     34        (TestGroup.createAndRefetchTestGroups): Adapt 'CommitSet.revisionSetsFromCommitSets'.
     35        (TestGroup._revisionSetsFromCommitSets): Deleted and moved to 'CommitSet.revisionSetsFromCommitSets'.
     36        * public/v3/pages/chart-pane.js:
     37        (ChartPane.prototype.didConstructShadowTree): Added the logic to disable options when checkbox for creating confirming
     38        test group is unchecked.
     39        (ChartPane.prototype._analyzeRange): Conditionally create confirming test group from UI.
     40        (ChartPane.cssTemplate):
     41        * server-tests/privileged-api-create-analysis-task-tests.js: Added unit tests. Added a unit test for 'NodePrivilegedAPI'.
     42        * unit-tests/analysis-task-tests.js: Added unit tests.
     43        * unit-tests/commit-set-tests.js: Added unit test for 'CommitSet.revisionSetsFromCommitSets'.
     44        * unit-tests/resources/mock-remote-api.js: Reset csrf token when BrowserPrivilegedAPI is used.
     45        (MockRemoteAPI.inject):
     46
    1472018-04-23  Dewei Zhu  <dewei_zhu@apple.com>
    248
  • trunk/Websites/perf.webkit.org/public/api/analysis-tasks.php

    r203709 r231087  
    11<?php
    22
    3 require('../include/json-header.php');
    4 require('../include/commit-log-fetcher.php');
     3require_once('../include/json-header.php');
     4require_once('../include/commit-log-fetcher.php');
    55
    66function main($path) {
  • trunk/Websites/perf.webkit.org/public/privileged-api/create-analysis-task.php

    r229501 r231087  
    22
    33require_once('../include/json-header.php');
     4require_once('../include/commit-sets-helpers.php');
    45
    56function main() {
    … …  
    910    $author = remote_user_name($data);
    1011    $name = array_get($data, 'name');
     12    $repetition_count = array_get($data, 'repetitionCount');
     13    $test_group_name = array_get($data, 'testGroupName');
     14    $revision_set_list = array_get($data, 'revisionSets');
    1115
    1216    $segmentation_name = array_get($data, 'segmentationStrategy');
    … …  
    6771        'segmentation' => $segmentation_id,
    6872        'test_range' => $test_range_id));
     73
     74    if ($repetition_count) {
     75        $triggerable = find_triggerable_for_task($db, $task_id);
     76        if (!$triggerable || !$triggerable['id']) {
     77            $db->rollback_transaction();
     78            exit_with_error('TriggerableNotFoundForTask', array('task' => $task_id, 'platform' => $config['config_platform']));
     79        }
     80        if ($triggerable['platform'] != $config['config_platform']) {
     81            $db->rollback_transaction();
     82            exit_with_error('InconsistentPlatform', array('configPlatform' => $config['config_platform'], 'taskPlatform' => $triggerable['platform']));
     83        }
     84        $triggerable_id = $triggerable['id'];
     85        $test_id = $triggerable['test'];
     86        $commit_sets = commit_sets_from_revision_sets($db, $triggerable_id, $revision_set_list);
     87        create_test_group_and_build_requests($db, $commit_sets, $task_id, $test_group_name, $author, $triggerable_id, $config['config_platform'], $test_id, $repetition_count);
     88    }
     89
    6990    $db->commit_transaction();
    7091
  • trunk/Websites/perf.webkit.org/public/privileged-api/create-test-group.php

    r223946 r231087  
    22
    33require_once('../include/json-header.php');
    4 require_once('../include/commit-log-fetcher.php');
    5 require_once('../include/repository-group-finder.php');
     4require_once('../include/commit-sets-helpers.php');
    65
    76function main()
    … …  
    8786        $task_id = $db->insert_row('analysis_tasks', 'task', array('name' => $task_name, 'author' => $author));
    8887
    89     $configuration_list = array();
    90     $repository_group_with_builds = array();
    91     foreach ($commit_sets as $commit_list) {
    92         $commit_set_id = $db->insert_row('commit_sets', 'commitset', array());
    93         $need_to_build = FALSE;
    94         foreach ($commit_list['set'] as $commit_row) {
    95             $commit_row['set'] = $commit_set_id;
    96             $requires_build =  $commit_row['requires_build'];
    97             assert(is_bool($requires_build));
    98             $need_to_build = $need_to_build || $requires_build;
    99             $db->insert_row('commit_set_items', 'commitset', $commit_row, 'commit');
    100         }
    101         $repository_group = $commit_list['repository_group'];
    102         if ($need_to_build)
    103             $repository_group_with_builds[$repository_group] = TRUE;
    104         array_push($configuration_list, array('commit_set' => $commit_set_id, 'repository_group' => $repository_group));
    105     }
    106 
    107     $build_count = 0;
    108     foreach ($configuration_list as &$config_item) {
    109         if (array_get($repository_group_with_builds, $config_item['repository_group'])) {
    110             $config_item['need_to_build'] = TRUE;
    111             $build_count++;
    112         }
    113     }
    114 
    115     $group_id = $db->insert_row('analysis_test_groups', 'testgroup',
    116         array('task' => $task_id, 'name' => $name, 'author' => $author));
    117 
    118     if ($build_count) {
    119         $order = -$build_count;
    120         foreach ($configuration_list as $config) {
    121             if (!array_get($config, 'need_to_build'))
    122                 continue;
    123             assert($order < 0);
    124             $db->insert_row('build_requests', 'request', array(
    125                 'triggerable' => $triggerable_id,
    126                 'repository_group' => $config['repository_group'],
    127                 'platform' => $platform_id,
    128                 'test' => NULL,
    129                 'group' => $group_id,
    130                 'order' => $order,
    131                 'commit_set' => $config['commit_set']));
    132             $order++;
    133         }
    134     }
    135 
    136     $order = 0;
    137     for ($i = 0; $i < $repetition_count; $i++) {
    138         foreach ($configuration_list as $config) {
    139             $db->insert_row('build_requests', 'request', array(
    140                 'triggerable' => $triggerable_id,
    141                 'repository_group' => $config['repository_group'],
    142                 'platform' => $platform_id,
    143                 'test' => $test_id,
    144                 'group' => $group_id,
    145                 'order' => $order,
    146                 'commit_set' => $config['commit_set']));
    147             $order++;
    148         }
    149     }
     88    $group_id = create_test_group_and_build_requests($db, $commit_sets, $task_id, $name, $author, $triggerable_id, $platform_id, $test_id, $repetition_count);
    15089
    15190    $db->commit_transaction();
    15291
    15392    exit_with_success(array('taskId' => $task_id, 'testGroupId' => $group_id));
    154 }
    155 
    156 function commit_sets_from_revision_sets($db, $triggerable_id, $revision_set_list)
    157 {
    158     if (count($revision_set_list) < 2)
    159         exit_with_error('InvalidRevisionSets', array('revisionSets' => $revision_set_list));
    160 
    161     $finder = new RepositoryGroupFinder($db, $triggerable_id);
    162     $commit_set_list = array();
    163     $repository_owner_list = array();
    164     $repositories_require_build = array();
    165     $commit_set_items_by_repository = array();
    166     foreach ($revision_set_list as $revision_set) {
    167         if (!count($revision_set))
    168             exit_with_error('InvalidRevisionSets', array('revisionSets' => $revision_set_list));
    169 
    170         $commit_set = array();
    171         $repository_list = array();
    172         $repository_with_patch = array();
    173         foreach ($revision_set as $repository_id => $data) {
    174             if ($repository_id == 'customRoots') {
    175                 $file_id_list = $data;
    176                 foreach ($file_id_list as $file_id) {
    177                     if (!is_numeric($file_id) || !$db->select_first_row('uploaded_files', 'file', array('id' => $file_id)))
    178                         exit_with_error('InvalidUploadedFile', array('file' => $file_id));
    179                     array_push($commit_set, array('root_file' => $file_id, 'patch_file' => NULL, 'requires_build' => FALSE, 'commit_owner' => NULL));
    180                 }
    181                 continue;
    182             }
    183             if (!is_numeric($repository_id))
    184                 exit_with_error('InvalidRepository', array('repository' => $repository_id));
    185 
    186             if (!is_array($data))
    187                 exit_with_error('InvalidRepositoryData', array('repository' => $repository_id, 'data' => $data));
    188 
    189             $revision = array_get($data, 'revision');
    190             if (!$revision)
    191                 exit_with_error('InvalidRevision', array('repository' => $repository_id, 'data' => $data));
    192             $commit_id = CommitLogFetcher::find_commit_id_by_revision($db, $repository_id, $revision);
    193             if ($commit_id < 0)
    194                 exit_with_error('AmbiguousRevision', array('repository' => $repository_id, 'revision' => $revision));
    195             if (!$commit_id)
    196                 exit_with_error('RevisionNotFound', array('repository' => $repository_id, 'revision' => $revision));
    197 
    198             $owner_revision = array_get($data, 'ownerRevision');
    199             $patch_file_id = array_get($data, 'patch');
    200             if ($patch_file_id) {
    201                 if (!is_numeric($patch_file_id) || !$db->select_first_row('uploaded_files', 'file', array('id' => $patch_file_id)))
    202                     exit_with_error('InvalidPatchFile', array('patch' => $patch_file_id));
    203                 array_push($repository_with_patch, $repository_id);
    204                 $repositories_require_build[$repository_id] =  TRUE;
    205             }
    206 
    207             $repository = NULL;
    208             $owner_commit_id = NULL;
    209             if ($owner_revision) {
    210                 $repository = $db->select_first_row('repositories', 'repository', array('id' => intval($repository_id)));
    211                 if (!$repository)
    212                     exit_with_error('RepositoryNotFound', array('repository' => $repository_id));
    213                 $owner_commit = $db->select_first_row('commits', 'commit', array('repository' => $repository['repository_owner'], 'revision' => $owner_revision));
    214                 if (!$owner_commit)
    215                     exit_with_error('InvalidOwnerRevision', array('repository' => $repository['repository_owner'], 'revision' => $owner_revision));
    216                 if (!$db->select_first_row('commit_ownerships', 'commit', array('owned' => $commit_id, 'owner' => $owner_commit['commit_id'])))
    217                     exit_with_error('InvalidCommitOwnership', array('commitOwner' => $owner_commit['commit_id'], 'commitOwned' => $commit_id));
    218                 $repositories_require_build[$repository_id] =  TRUE;
    219                 $owner_commit_id = $owner_commit['commit_id'];
    220             }
    221 
    222             array_push($commit_set, array('commit' => $commit_id, 'patch_file' => $patch_file_id, 'requires_build' => FALSE, 'commit_owner' => $owner_commit_id));
    223 
    224             array_ensure_item_has_array($commit_set_items_by_repository, $repository_id);
    225             $commit_set_items_by_repository[$repository_id][] = &$commit_set[count($commit_set) - 1];
    226 
    227             if ($owner_commit_id)
    228                 continue;
    229             array_push($repository_list, $repository_id);
    230         }
    231         $repository_group_id = $finder->find_by_repositories($repository_list);
    232         if (!$repository_group_id)
    233             exit_with_error('NoMatchingRepositoryGroup', array('repositories' => $repository_list));
    234 
    235         foreach ($repository_with_patch as $repository_id) {
    236             if (!$finder->accepts_patch($repository_group_id, $repository_id))
    237                 exit_with_error('PatchNotAccepted', array('repository' => $repository_id, 'repositoryGroup' => $repository_group_id));
    238         }
    239 
    240         array_push($commit_set_list, array('repository_group' => $repository_group_id, 'set' => $commit_set));
    241     }
    242 
    243     foreach (array_keys($repositories_require_build) as $repository_id) {
    244         foreach($commit_set_items_by_repository[$repository_id] as &$commit_set_item)
    245             $commit_set_item['requires_build'] = TRUE;
    246     }
    247     return $commit_set_list;
    24893}
    24994
  • trunk/Websites/perf.webkit.org/public/v3/models/analysis-task.js

    r230821 r231087  
    304304    }
    305305
    306     static create(name, startRunId, endRunId)
    307     {
    308         return PrivilegedAPI.sendRequest('create-analysis-task', {
    309             name: name,
    310             startRun: startRunId,
    311             endRun: endRunId,
    312         });
     306    static create(name, startPoint, endPoint, testGroupName=null, repetitionCount=0)
     307    {
     308        const parameters = {name, startRun: startPoint.id, endRun: endPoint.id};
     309        if (testGroupName) {
     310            console.assert(repetitionCount);
     311            parameters['revisionSets'] = CommitSet.revisionSetsFromCommitSets([startPoint.commitSet(), endPoint.commitSet()]);
     312            parameters['repetitionCount'] = repetitionCount;
     313            parameters['testGroupName'] = testGroupName;
     314        }
     315        return PrivilegedAPI.sendRequest('create-analysis-task', parameters);
    313316    }
    314317}
  • trunk/Websites/perf.webkit.org/public/v3/models/commit-set.js

    r230821 r231087  
    243243        return nameParts.join(' ');
    244244    }
     245
     246    static revisionSetsFromCommitSets(commitSets)
     247    {
     248        return commitSets.map((commitSet) => {
     249            console.assert(commitSet instanceof CustomCommitSet || commitSet instanceof CommitSet);
     250            const revisionSet = {};
     251            for (let repository of commitSet.repositories()) {
     252                const patchFile = commitSet.patchForRepository(repository);
     253                revisionSet[repository.id()] = {
     254                    revision: commitSet.revisionForRepository(repository),
     255                    ownerRevision: commitSet.ownerRevisionForRepository(repository),
     256                    patch: patchFile ? patchFile.id() : null,
     257                };
     258            }
     259            const customRoots = commitSet.customRoots();
     260            if (customRoots && customRoots.length)
     261                revisionSet['customRoots'] = customRoots.map((uploadedFile) => uploadedFile.id());
     262            return revisionSet;
     263        });
     264    }
    245265}
    246266
  • trunk/Websites/perf.webkit.org/public/v3/models/test-group.js

    r230821 r231087  
    189189    {
    190190        console.assert(commitSets.length == 2);
    191         const revisionSets = this._revisionSetsFromCommitSets(commitSets);
     191        const revisionSets = CommitSet.revisionSetsFromCommitSets(commitSets);
    192192        const params = {taskName, name: groupName, platform: platform.id(), test: test.id(), repetitionCount, revisionSets};
    193193        return PrivilegedAPI.sendRequest('create-test-group', params).then((data) => {
    … …  
    201201    {
    202202        console.assert(commitSets.length == 2);
    203         const revisionSets = this._revisionSetsFromCommitSets(commitSets);
     203        const revisionSets = CommitSet.revisionSetsFromCommitSets(commitSets);
    204204        const params = {task: task.id(), name: groupName, platform: platform.id(), test: test.id(), repetitionCount, revisionSets};
    205205        return PrivilegedAPI.sendRequest('create-test-group', params).then((data) => {
    … …  
    211211    {
    212212        console.assert(commitSets.length == 2);
    213         const revisionSets = this._revisionSetsFromCommitSets(commitSets);
     213        const revisionSets = CommitSet.revisionSetsFromCommitSets(commitSets);
    214214        return PrivilegedAPI.sendRequest('create-test-group', {
    215215            task: task.id(),
    … …  
    220220    }
    221221
    222     static _revisionSetsFromCommitSets(commitSets)
    223     {
    224         return commitSets.map((commitSet) => {
    225             console.assert(commitSet instanceof CustomCommitSet || commitSet instanceof CommitSet);
    226             const revisionSet = {};
    227             for (let repository of commitSet.repositories()) {
    228                 const patchFile = commitSet.patchForRepository(repository);
    229                 revisionSet[repository.id()] = {
    230                     revision: commitSet.revisionForRepository(repository),
    231                     ownerRevision: commitSet.ownerRevisionForRepository(repository),
    232                     patch: patchFile ? patchFile.id() : null,
    233                 };
    234             }
    235             const customRoots = commitSet.customRoots();
    236             if (customRoots && customRoots.length)
    237                 revisionSet['customRoots'] = customRoots.map((uploadedFile) => uploadedFile.id());
    238             return revisionSet;
    239         });
    240     }
    241 
    242222    static findAllByTask(taskId)
    243223    {
  • trunk/Websites/perf.webkit.org/public/v3/pages/chart-pane.js

    r230295 r231087  
    117117        this.part('close').listenToAction('activate', () => {
    118118            this._chartsPage.closePane(this);
    119         })
     119        });
     120        const createWithTestGroupCheckbox = this.content('create-with-test-group');
     121        const repetitionCount = this.content('confirm-repetition');
     122        createWithTestGroupCheckbox.onchange = () => repetitionCount.disabled = !createWithTestGroupCheckbox.checked;
    120123    }
    121124
    … …  
    227230    }
    228231
    229     _analyzeRange(startPoint, endPoint)
     232    async _analyzeRange(startPoint, endPoint)
    230233    {
    231234        const router = this._chartsPage.router();
    232235        const newWindow = window.open(router.url('analysis/task/create', {inProgress: true}), '_blank');
    233236
    234         const analyzePopover = this.content().querySelector('.chart-pane-analyze-popover');
    235         const name = analyzePopover.querySelector('input').value;
    236         AnalysisTask.create(name, startPoint.id, endPoint.id).then((data) => {
     237        const name = this.content('task-name').value;
     238        const createWithTestGroup = this.content('create-with-test-group').checked;
     239        const repetitionCount = this.content('confirm-repetition').value;
     240
     241        try {
     242            const data = await (createWithTestGroup ?
     243                AnalysisTask.create(name, startPoint, endPoint, 'Confirm', repetitionCount) : AnalysisTask.create(name, startPoint, endPoint));
    237244            newWindow.location.href = router.url('analysis/task/' + data['taskId']);
    238245            this.fetchAnalysisTasks(true);
    239         }, (error) => {
     246        } catch(error) {
    240247            newWindow.location.href = router.url('analysis/task/create', {error: error});
    241         });
     248        }
    242249    }
    243250
    … …  
    559566                    <ul class="chart-pane-alternative-platforms popover" style="display:none"></ul>
    560567                    <form class="chart-pane-analyze-popover popover" style="display:none">
    561                         <input type="text" required>
     568                        <input type="text" id="task-name" required>
    562569                        <button>Create</button>
     570                        <li>
     571                            <label><input type="checkbox" id="create-with-test-group" checked></label>
     572                            <label>Confirm with</label>
     573                                <select id="confirm-repetition">
     574                                    <option>1</option>
     575                                    <option>2</option>
     576                                    <option>3</option>
     577                                    <option selected>4</option>
     578                                    <option>5</option>
     579                                    <option>6</option>
     580                                    <option>7</option>
     581                                    <option>8</option>
     582                                    <option>9</option>
     583                                    <option>10</option>
     584                                </select>
     585                            <label>iterations</label>
     586                        </li>
    563587                    </form>
    564588                    <ul class="chart-pane-filtering-options popover" style="display:none">
    … …  
    620644            }
    621645
    622             .chart-pane-actions ul {
     646            .chart-pane-actions ul, form {
    623647                display: block;
    624648                padding: 0;
  • trunk/Websites/perf.webkit.org/server-tests/privileged-api-create-analysis-task-tests.js

    r229501 r231087  
    106106    }}];
    107107
    108 describe('/privileged-api/create-analysis-task', function () {
     108describe('/privileged-api/create-analysis-task with browser privileged api', function () {
    109109    prepareServerTest(this);
    110110
    … …  
    335335    });
    336336
     337    it('should failed with "TriggerableNotFoundForTask" when there is no matching triggerable', async () => {
     338        const db = TestServer.database();
     339        await addBuilderForReport(reportWithRevision[0]);
     340        await TestServer.remoteAPI().postJSON('/api/report/', reportWithRevision);
     341        await TestServer.remoteAPI().postJSON('/api/report/', anotherReportWithRevision);
     342        await Manifest.fetch();
     343
     344        const test1 = Test.findByPath(['Suite', 'test1']);
     345        const somePlatform = Platform.findByName('some platform');
     346        const configRow = await db.selectFirstRow('test_configurations', {metric: test1.metrics()[0].id(), platform: somePlatform.id()});
     347        const testRuns = await db.selectRows('test_runs', {config: configRow['id']});
     348        assert.equal(testRuns.length, 2);
     349
     350        const webkitRepositoryRow = await db.selectFirstRow('repositories', {name: 'WebKit'});
     351        const webkitId = webkitRepositoryRow.id;
     352
     353        const oneRevisionSet = {[webkitId]: {revision: '191622'}};
     354        const anotherRevisionSet = {[webkitId]: {revision: '191623'}};
     355
     356        let raiseException = false;
     357
     358        try {
     359            await PrivilegedAPI.sendRequest('create-analysis-task', {name: 'confirm', repetitionCount: 1,
     360                revisionSets: [oneRevisionSet, anotherRevisionSet],
     361                startRun: testRuns[0]['id'], endRun: testRuns[1]['id']});
     362        } catch (error) {
     363            assert.equal(error, 'TriggerableNotFoundForTask');
     364            raiseException = true;
     365        }
     366        assert.ok(raiseException);
     367    });
     368
     369    it('should create an analysis task with no test group when repetition count is 0', async () => {
     370        const db = TestServer.database();
     371        await addBuilderForReport(reportWithRevision[0]);
     372        await TestServer.remoteAPI().postJSON('/api/report/', reportWithRevision);
     373        await TestServer.remoteAPI().postJSON('/api/report/', anotherReportWithRevision);
     374        await Manifest.fetch();
     375
     376        const test1 = Test.findByPath(['Suite', 'test1']);
     377        const platform = Platform.findByName('some platform');
     378        const configRow = await db.selectFirstRow('test_configurations', {metric: test1.metrics()[0].id(), platform: platform.id()});
     379        const testRuns = await db.selectRows('test_runs', {config: configRow['id']});
     380        assert.equal(testRuns.length, 2);
     381
     382        const webkitRepositoryRow = await db.selectFirstRow('repositories', {name: 'WebKit'});
     383        const webkitId = webkitRepositoryRow.id;
     384
     385        const oneRevisionSet = {[webkitId]: {revision: '191622'}};
     386        const anotherRevisionSet = {[webkitId]: {revision: '191623'}};
     387
     388        const content = await PrivilegedAPI.sendRequest('create-analysis-task', {name: 'confirm', repetitionCount: 0,
     389            revisionSets: [oneRevisionSet, anotherRevisionSet],
     390            startRun: testRuns[0]['id'], endRun: testRuns[1]['id']});
     391
     392        TestServer.cleanDataDirectory();
     393        await Manifest.fetch();
     394
     395        const task = await AnalysisTask.fetchById(content['taskId']);
     396        assert.equal(task.name(), 'confirm');
     397        assert(!task.hasResults());
     398        assert(!task.hasPendingRequests());
     399        assert.deepEqual(task.bugs(), []);
     400        assert.deepEqual(task.causes(), []);
     401        assert.deepEqual(task.fixes(), []);
     402        assert.equal(task.changeType(), null);
     403        assert.equal(task.platform().label(), 'some platform');
     404        assert.equal(task.metric().test().label(), 'test1');
     405
     406        const testGroups = await TestGroup.fetchForTask(task.id());
     407        assert.equal(testGroups.length, 0);
     408    });
     409
     410    it('should create an analysis task with test group when commit set list and a positive repetition count is specified', async () => {
     411        const webkitId = 1;
     412        const platformId = 1;
     413        const test1Id = 2;
     414        const triggerableId = 1234;
     415
     416        const db = TestServer.database();
     417        await db.insert('tests', {id: 1, name: 'Suite'});
     418        await db.insert('tests', {id: test1Id, name: 'test1', parent: 1});
     419        await db.insert('repositories', {id: webkitId, name: 'WebKit'});
     420        await db.insert('platforms', {id: platformId, name: 'some platform'});
     421        await db.insert('build_triggerables', {id: 1234, name: 'test-triggerable'});
     422        await db.insert('triggerable_repository_groups', {id: 2345, name: 'webkit-only', triggerable: triggerableId});
     423        await db.insert('triggerable_repositories', {repository: webkitId, group: 2345});
     424        await db.insert('triggerable_configurations', {test: test1Id, platform: platformId, triggerable: triggerableId});
     425        await addBuilderForReport(reportWithRevision[0]);
     426
     427        await TestServer.remoteAPI().postJSON('/api/report/', reportWithRevision);
     428        await TestServer.remoteAPI().postJSON('/api/report/', anotherReportWithRevision);
     429        await Manifest.fetch();
     430
     431        let test1 = Test.findById(test1Id);
     432        let somePlatform = Platform.findById(platformId);
     433        const configRow = await db.selectFirstRow('test_configurations', {metric: test1.metrics()[0].id(), platform: somePlatform.id()});
     434        const testRuns = await db.selectRows('test_runs', {config: configRow['id']});
     435        assert.equal(testRuns.length, 2);
     436
     437        const oneRevisionSet = {[webkitId]: {revision: '191622'}};
     438        const anotherRevisionSet = {[webkitId]: {revision: '191623'}};
     439
     440        const content = await PrivilegedAPI.sendRequest('create-analysis-task', {name: 'confirm', repetitionCount: 1,
     441            testGroupName: 'Confirm', revisionSets: [oneRevisionSet, anotherRevisionSet],
     442            startRun: testRuns[0]['id'], endRun: testRuns[1]['id']});
     443
     444        const task = await AnalysisTask.fetchById(content['taskId']);
     445        assert.equal(task.name(), 'confirm');
     446        assert(!task.hasResults());
     447        assert(task.hasPendingRequests());
     448        assert.deepEqual(task.bugs(), []);
     449        assert.deepEqual(task.causes(), []);
     450        assert.deepEqual(task.fixes(), []);
     451        assert.equal(task.changeType(), null);
     452        assert.equal(task.platform().label(), 'some platform');
     453        assert.equal(task.metric().test().label(), 'test1');
     454
     455        const testGroups = await TestGroup.fetchForTask(task.id());
     456        assert.equal(testGroups.length, 1);
     457        const testGroup = testGroups[0];
     458        assert.equal(testGroup.name(), 'Confirm');
     459        const buildRequests = testGroup.buildRequests();
     460        assert.equal(buildRequests.length, 2);
     461
     462        assert.equal(buildRequests[0].triggerable().id(), triggerableId);
     463        assert.equal(buildRequests[0].triggerable().id(), triggerableId);
     464
     465        assert.equal(buildRequests[0].testGroup(), testGroup);
     466        assert.equal(buildRequests[1].testGroup(), testGroup);
     467
     468        assert.equal(buildRequests[0].platform(), task.platform());
     469        assert.equal(buildRequests[1].platform(), task.platform());
     470
     471        assert.equal(buildRequests[0].analysisTaskId(), task.id());
     472        assert.equal(buildRequests[1].analysisTaskId(), task.id());
     473
     474        assert.equal(buildRequests[0].test(), test1);
     475        assert.equal(buildRequests[1].test(), test1);
     476
     477        assert.ok(!buildRequests[0].isBuild());
     478        assert.ok(!buildRequests[1].isBuild());
     479        assert.ok(buildRequests[0].isTest());
     480        assert.ok(buildRequests[1].isTest());
     481
     482        const firstCommitSet = buildRequests[0].commitSet();
     483        const secondCommitSet = buildRequests[1].commitSet();
     484        const webkitRepository = Repository.findById(webkitId);
     485        assert.equal(firstCommitSet.commitForRepository(webkitRepository).revision(), '191622');
     486        assert.equal(secondCommitSet.commitForRepository(webkitRepository).revision(), '191623');
     487    });
    337488});
     489
     490describe('/privileged-api/create-analysis-task with node privileged api', function () {
     491    prepareServerTest(this, 'node');
     492    beforeEach(() => {
     493        PrivilegedAPI.configure('test', 'password');
     494    });
     495
     496    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 () => {
     497        PrivilegedAPI.configure('test', 'wrongpassword');
     498        const db = TestServer.database();
     499        await addBuilderForReport(reportWithRevision[0]);
     500        await TestServer.remoteAPI().postJSON('/api/report/', reportWithRevision);
     501        await TestServer.remoteAPI().postJSON('/api/report/', anotherReportWithRevision);
     502        await Manifest.fetch();
     503
     504        const test1 = Test.findByPath(['Suite', 'test1']);
     505        const somePlatform = Platform.findByName('some platform');
     506        const configRow = await db.selectFirstRow('test_configurations', {metric: test1.metrics()[0].id(), platform: somePlatform.id()});
     507        const testRuns = await db.selectRows('test_runs', {config: configRow['id']});
     508        assert.equal(testRuns.length, 2);
     509
     510        const webkitRepositoryRow = await db.selectFirstRow('repositories', {name: 'WebKit'});
     511        const webkitId = webkitRepositoryRow.id;
     512
     513        const oneRevisionSet = {[webkitId]: {revision: '191622'}};
     514        const anotherRevisionSet = {[webkitId]: {revision: '191623'}};
     515
     516        let raiseException = false;
     517
     518        try {
     519            await PrivilegedAPI.sendRequest('create-analysis-task', {name: 'confirm', repetitionCount: 1,
     520                revisionSets: [oneRevisionSet, anotherRevisionSet],
     521                startRun: testRuns[0]['id'], endRun: testRuns[1]['id']});
     522        } catch (error) {
     523            assert.equal(error, 'SlaveNotFound');
     524            raiseException = true;
     525        }
     526        assert.ok(raiseException);
     527
     528        const allAnalysisTasks = await db.selectRows('analysis_tasks');
     529        assert.ok(!allAnalysisTasks.length);
     530
     531        const allTestGroups = await db.selectRows('analysis_test_groups');
     532        assert.ok(!allTestGroups.length);
     533
     534        const allBuildRequests = await db.selectRows('build_requests');
     535        assert.ok(!allBuildRequests.length);
     536    });
     537
     538    it('should create an analysis task with test group when commit set list and a positive repetition count is specified', async () => {
     539        const webkitId = 1;
     540        const platformId = 1;
     541        const test1Id = 2;
     542        const triggerableId = 1234;
     543
     544        const db = TestServer.database();
     545        await db.insert('tests', {id: 1, name: 'Suite'});
     546        await db.insert('tests', {id: test1Id, name: 'test1', parent: 1});
     547        await db.insert('repositories', {id: webkitId, name: 'WebKit'});
     548        await db.insert('platforms', {id: platformId, name: 'some platform'});
     549        await db.insert('build_triggerables', {id: 1234, name: 'test-triggerable'});
     550        await db.insert('triggerable_repository_groups', {id: 2345, name: 'webkit-only', triggerable: triggerableId});
     551        await db.insert('triggerable_repositories', {repository: webkitId, group: 2345});
     552        await db.insert('triggerable_configurations', {test: test1Id, platform: platformId, triggerable: triggerableId});
     553        await addBuilderForReport(reportWithRevision[0]);
     554
     555        await TestServer.remoteAPI().postJSON('/api/report/', reportWithRevision);
     556        await TestServer.remoteAPI().postJSON('/api/report/', anotherReportWithRevision);
     557        await Manifest.fetch();
     558
     559        let test1 = Test.findById(test1Id);
     560        let somePlatform = Platform.findById(platformId);
     561        const configRow = await db.selectFirstRow('test_configurations', {metric: test1.metrics()[0].id(), platform: somePlatform.id()});
     562        const testRuns = await db.selectRows('test_runs', {config: configRow['id']});
     563        assert.equal(testRuns.length, 2);
     564
     565        const oneRevisionSet = {[webkitId]: {revision: '191622'}};
     566        const anotherRevisionSet = {[webkitId]: {revision: '191623'}};
     567
     568        const content = await PrivilegedAPI.sendRequest('create-analysis-task', {name: 'confirm', repetitionCount: 1,
     569            testGroupName: 'Confirm', revisionSets: [oneRevisionSet, anotherRevisionSet],
     570            startRun: testRuns[0]['id'], endRun: testRuns[1]['id']});
     571
     572        const task = await AnalysisTask.fetchById(content['taskId']);
     573        assert.equal(task.name(), 'confirm');
     574        assert(!task.hasResults());
     575        assert(task.hasPendingRequests());
     576        assert.deepEqual(task.bugs(), []);
     577        assert.deepEqual(task.causes(), []);
     578        assert.deepEqual(task.fixes(), []);
     579        assert.equal(task.changeType(), null);
     580        assert.equal(task.platform().label(), 'some platform');
     581        assert.equal(task.metric().test().label(), 'test1');
     582
     583        const testGroups = await TestGroup.fetchForTask(task.id());
     584        assert.equal(testGroups.length, 1);
     585        const testGroup = testGroups[0];
     586        assert.equal(testGroup.name(), 'Confirm');
     587        const buildRequests = testGroup.buildRequests();
     588        assert.equal(buildRequests.length, 2);
     589
     590        assert.equal(buildRequests[0].triggerable().id(), triggerableId);
     591        assert.equal(buildRequests[0].triggerable().id(), triggerableId);
     592
     593        assert.equal(buildRequests[0].testGroup(), testGroup);
     594        assert.equal(buildRequests[1].testGroup(), testGroup);
     595
     596        assert.equal(buildRequests[0].platform(), task.platform());
     597        assert.equal(buildRequests[1].platform(), task.platform());
     598
     599        assert.equal(buildRequests[0].analysisTaskId(), task.id());
     600        assert.equal(buildRequests[1].analysisTaskId(), task.id());
     601
     602        assert.equal(buildRequests[0].test(), test1);
     603        assert.equal(buildRequests[1].test(), test1);
     604
     605        assert.ok(!buildRequests[0].isBuild());
     606        assert.ok(!buildRequests[1].isBuild());
     607        assert.ok(buildRequests[0].isTest());
     608        assert.ok(buildRequests[1].isTest());
     609
     610        const firstCommitSet = buildRequests[0].commitSet();
     611        const secondCommitSet = buildRequests[1].commitSet();
     612        const webkitRepository = Repository.findById(webkitId);
     613        assert.equal(firstCommitSet.commitForRepository(webkitRepository).revision(), '191622');
     614        assert.equal(secondCommitSet.commitForRepository(webkitRepository).revision(), '191623');
     615    });
     616});
  • trunk/Websites/perf.webkit.org/unit-tests/analysis-task-tests.js

    r230719 r231087  
    122122describe('AnalysisTask', () => {
    123123    MockModels.inject();
    124     let requests = MockRemoteAPI.inject();
     124    function makeMockPoints(id, commitSet) {
     125        return {
     126            id,
     127            commitSet: () => commitSet
     128        }
     129    }
    125130
    126131    describe('fetchAll', () => {
     132        const requests = MockRemoteAPI.inject();
    127133        it('should request all analysis tasks', () => {
    128134            let callCount = 0;
    … …  
    225231        });
    226232    });
     233
     234
     235    function mockStartAndEndPoints() {
     236        const startPoint = makeMockPoints(1, new MeasurementCommitSet(1, [
     237            [1, MockModels.ios.id(), 'ios-revision-1', null, 0],
     238            [3, MockModels.webkit.id(), 'webkit-revision-1', null, 0]
     239        ]));
     240        const endPoint = makeMockPoints(2, new MeasurementCommitSet(2, [
     241            [2, MockModels.ios.id(), 'ios-revision-2', null, 0],
     242            [4, MockModels.webkit.id(), 'webkit-revision-2', null, 0]
     243        ]));
     244        return [startPoint, endPoint];
     245    }
     246
     247    describe('create with browser privilege api', () => {
     248        const requests = MockRemoteAPI.inject();
     249
     250        it('should create analysis task with confirming repetition count zero as default with browser privilege api', async () => {
     251            const [startPoint, endPoint] = mockStartAndEndPoints();
     252            AnalysisTask.create('confirm', startPoint, endPoint);
     253            assert.equal(requests.length, 1);
     254            assert.equal(requests[0].url, '/privileged-api/generate-csrf-token');
     255            requests[0].resolve({
     256                token: 'abc',
     257                expiration: Date.now() + 3600 * 1000,
     258            });
     259
     260            await MockRemoteAPI.waitForRequest();
     261            assert.equal(requests[1].url, '/privileged-api/create-analysis-task');
     262            assert.equal(requests.length, 2);
     263            assert.deepEqual(requests[1].data, {name: 'confirm', startRun: 1, endRun: 2, token: 'abc'});
     264        });
     265
     266        it('should create analysis task with confirming repetition count specified', async () => {
     267            const [startPoint, endPoint] = mockStartAndEndPoints();
     268            AnalysisTask.create('confirm', startPoint, endPoint, 'Confirm', 4);
     269            assert.equal(requests.length, 1);
     270            assert.equal(requests[0].url, '/privileged-api/generate-csrf-token');
     271            requests[0].resolve({
     272                token: 'abc',
     273                expiration: Date.now() + 3600 * 1000,
     274            });
     275
     276            await MockRemoteAPI.waitForRequest();
     277            assert.equal(requests[1].url, '/privileged-api/create-analysis-task');
     278            assert.equal(requests.length, 2);
     279            assert.deepEqual(requests[1].data, {name: 'confirm', repetitionCount: 4,
     280                startRun: 1, endRun: 2, testGroupName: 'Confirm', token: 'abc', revisionSets: [
     281                    {'11': {revision: 'webkit-revision-1', ownerRevision: null, patch: null},
     282                        '22': {revision: 'ios-revision-1', ownerRevision: null, patch: null}},
     283                    {'11': {revision: 'webkit-revision-2', ownerRevision: null, patch: null},
     284                        '22': { revision: 'ios-revision-2', ownerRevision: null, patch: null}}]}
     285            );
     286        });
     287    });
     288
     289    describe('create with node privilege api', () => {
     290        const requests = MockRemoteAPI.inject(null, 'node');
     291        beforeEach(() => {
     292            PrivilegedAPI.configure('worker', 'password');
     293        });
     294
     295        it('should create analysis task with confirming repetition count zero as default with browser privilege api', () => {
     296            const [startPoint, endPoint] = mockStartAndEndPoints();
     297            AnalysisTask.create('confirm', startPoint, endPoint);
     298            assert.equal(requests[0].url, '/privileged-api/create-analysis-task');
     299            assert.equal(requests.length, 1);
     300            assert.deepEqual(requests[0].data, {name: 'confirm', startRun: 1, endRun: 2, slaveName: 'worker', slavePassword: 'password'});
     301        });
     302
     303        it('should create analysis task with confirming repetition count specified', () => {
     304            const [startPoint, endPoint] = mockStartAndEndPoints();
     305            AnalysisTask.create('confirm', startPoint, endPoint, 'Confirm', 4);
     306            assert.equal(requests[0].url, '/privileged-api/create-analysis-task');
     307            assert.equal(requests.length, 1);
     308            assert.deepEqual(requests[0].data, {name: 'confirm', repetitionCount: 4,
     309                startRun: 1, endRun: 2, slaveName: 'worker', slavePassword: 'password',
     310                testGroupName: 'Confirm', revisionSets: [
     311                    {'11': {revision: 'webkit-revision-1', ownerRevision: null, patch: null},
     312                        '22': {revision: 'ios-revision-1', ownerRevision: null, patch: null}},
     313                    {'11': {revision: 'webkit-revision-2', ownerRevision: null, patch: null},
     314                        '22': { revision: 'ios-revision-2', ownerRevision: null, patch: null}}]}
     315            );
     316        });
     317    });
    227318});
  • trunk/Websites/perf.webkit.org/unit-tests/commit-set-tests.js

    r230821 r231087  
    386386        it('should describe commit root and patch difference', () => {
    387387            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)');
     388        });
     389    });
     390
     391    describe('revisionSetsFromCommitSets', () => {
     392        it('should create revision sets from commit sets', () => {
     393            assert.deepEqual(CommitSet.revisionSetsFromCommitSets([oneCommitSet(), commitSetWithRoot(), commitSetWithTwoRoots()]),
     394                [{'11': { revision: 'webkit-commit-0', ownerRevision: null, patch: null}},
     395                    {'11': { revision: 'webkit-commit-0', ownerRevision: null, patch: null}, customRoots: [456]},
     396                    {'11': { revision: 'webkit-commit-0', ownerRevision: null, patch: null}, customRoots: [456, 458]}]);
    388397        });
    389398    });
  • trunk/Websites/perf.webkit.org/unit-tests/resources/mock-remote-api.js

    r230960 r231087  
    6666        let originalRemoteAPI = global.RemoteAPI;
    6767        let originalPrivilegedAPI = global.PrivilegedAPI;
    68         const PrivilegedAPI = privilegedAPIType === 'node' ? NodePrivilegedAPI: BrowserPrivilegedAPI;
     68        const useNodePrivilegedAPI = privilegedAPIType === 'node';
     69        const PrivilegedAPI = useNodePrivilegedAPI ? NodePrivilegedAPI: BrowserPrivilegedAPI;
    6970
    7071        beforeEach(() => {
    … …  
    7475            originalPrivilegedAPI = global.PrivilegedAPI;
    7576            global.PrivilegedAPI = PrivilegedAPI;
     77            if (!useNodePrivilegedAPI)
     78                PrivilegedAPI._token = null;
    7679        });
    7780
Note: See TracChangeset for help on using the changeset viewer.