Changeset 250465 in webkit


Ignore:
Timestamp:
Sep 27, 2019 3:45:12 PM (5 years ago)
Author:
Dewei Zhu
Message:

Provide build request status description information on dashboard.
https://bugs.webkit.org/show_bug.cgi?id=199810

Reviewed by Ryosuke Niwa.

Add build request status description to show detailed information for a build and show it in dashboard.
Update SQL for existing instance:

ALTER TABLE build_requests ADD COLUMN IF NOT EXISTS request_status_description varchar(1024) DEFAULT NULL;

  • ReadMe.md: Updated instructions for initializing a database to include running 'migrate-database.sql'.
  • init-database.sql: Added request_status_description column.
  • migrate-database.sql: A file stores migration SQL for existing instance.
  • public/api/build-requests.php: Added support for updating request_status_description.
  • public/include/build-requests-fetcher.php: Exposed statusDescription to API.
  • public/v3/components/test-group-revision-table.js: Added UI for showing build request status detail.

(TestGroupRevisionTable.prototype._renderTable):
(TestGroupRevisionTable.prototype._buildDescriptionCell):
(TestGroupRevisionTable.cssTemplate):

  • public/v3/components/warning-icon.js: Extended warning icon to be able to customize information on hover.

(WarningIcon):
(WarningIcon.prototype.render):

  • public/v3/components/button-base.js: Added a instance method to set button title.

(ButtonBase.prototype.setButtonTitle):

  • public/v3/models/build-request.js: Added 'statusDescription' field.

(BuildRequest):
(BuildRequest.prototype.updateSingleton):
(BuildRequest.prototype.statusDescription):

  • server-tests/api-build-requests-tests.js: Fixed unit tests.
  • server-tests/resources/mock-data.js:

(MockData.set mockTestSyncConfigWithSingleBuilder): Added 'status_description' in buildbot mock data.
(MockData.sampleBuildData):

  • server-tests/resources/test-server.js:

(TestServer.prototype.initDatabase): Added code to execute 'migrate-database.sql' on initialization.

  • server-tests/tools-sync-buildbot-integration-tests.js: Added unit tests.
  • tools/js/buildbot-syncer.js: Added 'statusDescription' field to 'BuildbotBuildEntry'.

(BuildbotBuildEntry.prototype.initialize):
(BuildbotBuildEntry.prototype.statusDescription):

  • tools/js/buildbot-triggerable.js:

(BuildbotTriggerable.prototype._pullBuildbotOnAllSyncers):

  • unit-tests/buildbot-syncer-tests.js: Added test code for BuildbotBuildEntry.statusDescription.
Location:
trunk/Websites/perf.webkit.org
Files:
1 added
15 edited

Legend:

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

    r248110 r250465  
     12019-07-30  Dewei Zhu  <dewei_zhu@apple.com>
     2
     3        Provide build request status description information on dashboard.
     4        https://bugs.webkit.org/show_bug.cgi?id=199810
     5
     6        Reviewed by Ryosuke Niwa.
     7
     8        Add build request status description to show detailed information for a build and show it in dashboard.
     9        Update SQL for existing instance:
     10            ALTER TABLE build_requests ADD COLUMN IF NOT EXISTS request_status_description varchar(1024) DEFAULT NULL;
     11
     12        * ReadMe.md: Updated instructions for initializing a database to include running 'migrate-database.sql'.
     13        * init-database.sql: Added request_status_description column.
     14        * migrate-database.sql: A file stores migration SQL for existing instance.
     15        * public/api/build-requests.php: Added support for updating request_status_description.
     16        * public/include/build-requests-fetcher.php: Exposed `statusDescription` to API.
     17        * public/v3/components/test-group-revision-table.js: Added UI for showing build request status detail.
     18        (TestGroupRevisionTable.prototype._renderTable):
     19        (TestGroupRevisionTable.prototype._buildDescriptionCell):
     20        (TestGroupRevisionTable.cssTemplate):
     21        * public/v3/components/warning-icon.js: Extended warning icon to be able to customize information on hover.
     22        (WarningIcon):
     23        (WarningIcon.prototype.render):
     24        * public/v3/components/button-base.js: Added a instance method to set button title.
     25        (ButtonBase.prototype.setButtonTitle):
     26        * public/v3/models/build-request.js: Added 'statusDescription' field.
     27        (BuildRequest):
     28        (BuildRequest.prototype.updateSingleton):
     29        (BuildRequest.prototype.statusDescription):
     30        * server-tests/api-build-requests-tests.js: Fixed unit tests.
     31        * server-tests/resources/mock-data.js:
     32        (MockData.set mockTestSyncConfigWithSingleBuilder): Added 'status_description' in buildbot mock data.
     33        (MockData.sampleBuildData):
     34        * server-tests/resources/test-server.js:
     35        (TestServer.prototype.initDatabase): Added code to execute 'migrate-database.sql' on initialization.
     36        * server-tests/tools-sync-buildbot-integration-tests.js: Added unit tests.
     37        * tools/js/buildbot-syncer.js: Added 'statusDescription' field to 'BuildbotBuildEntry'.
     38        (BuildbotBuildEntry.prototype.initialize):
     39        (BuildbotBuildEntry.prototype.statusDescription):
     40        * tools/js/buildbot-triggerable.js:
     41        (BuildbotTriggerable.prototype._pullBuildbotOnAllSyncers):
     42        * unit-tests/buildbot-syncer-tests.js: Added test code for BuildbotBuildEntry.statusDescription.
     43
    1442019-07-26  Dewei Zhu  <dewei_zhu@apple.com>
    245
  • trunk/Websites/perf.webkit.org/ReadMe.md

    r227133 r250465  
    6969Run `database/init-database.sql` in psql as `webkit-perf-db-user`:
    7070`/Applications/Server.app/Contents/ServerRoot/usr/bin/psql webkit-perf-db -h localhost --username webkit-perf-db-user -f init-database.sql`
     71
     72Then run:
     73`/Applications/Server.app/Contents/ServerRoot/usr/bin/psql webkit-perf-db -h localhost --username webkit-perf-db-user -f migrate-database.sql`
    7174
    7275### Making a Backup and Restoring
  • trunk/Websites/perf.webkit.org/public/api/build-requests.php

    r236861 r250465  
    4747        $status = $info['status'];
    4848        $url = array_get($info, 'url');
     49        $status_description = array_get($info, 'statusDescription');
    4950        $request_row = $db->select_first_row('build_requests', 'request', array('id' => $id));
    5051        if ($status == 'failedIfNotCompleted') {
     
    6162                    array($request_row['request_group'], $request_row['request_order']));
    6263            }
    63             $db->update_row('build_requests', 'request', array('id' => $id), array('status' => 'failed', 'url' => $url));
     64            $db->update_row('build_requests', 'request', array('id' => $id), array('status' => 'failed', 'url' => $url, 'status_description' => $status_description));
    6465        } else {
    6566            if (!in_array($status, array('pending', 'scheduled', 'running', 'failed', 'completed', 'canceled'))) {
     
    6768                exit_with_error('UnknownBuildRequestStatus', array('buildRequest' => $id, 'status' => $status));
    6869            }
    69             $db->update_row('build_requests', 'request', array('id' => $id), array('status' => $status, 'url' => $url));
    70             $test_group_id = $request_row['request_group'];
     70            $db->update_row('build_requests', 'request', array('id' => $id), array('status' => $status, 'url' => $url, 'status_description' => $status_description));
    7171            if ($status != 'failed')
    7272                continue;
  • trunk/Websites/perf.webkit.org/public/include/build-requests-fetcher.php

    r232612 r250465  
    9393                'build' => $row['request_build'],
    9494                'createdAt' => $row['request_created_at'] ? strtotime($row['request_created_at']) * 1000 : NULL,
     95                'statusDescription' => $row['request_status_description'],
    9596            ));
    9697        }
  • trunk/Websites/perf.webkit.org/public/v3/components/button-base.js

    r226259 r250465  
    1212        this._disabled = disabled;
    1313        this.enqueueToRender();
     14    }
     15
     16    setButtonTitle(title)
     17    {
     18        this.content('button').title = title;
     19        this.enqueToRender();
    1420    }
    1521
  • trunk/Websites/perf.webkit.org/public/v3/components/test-group-revision-table.js

    r219370 r250465  
    9090
    9191        const element = ComponentBase.createElement;
    92         const link = ComponentBase.createLink;
    9392        this.renderReplace(this.content('revision-table'), [
    9493            element('thead', [
     
    107106                    hasCustomRoots ? this._buildCustomRootsCell(entry) : [],
    108107                    element('td', entry.label),
    109                     element('td', request.statusUrl() ? link(request.statusLabel(), request.statusUrl()) : request.statusLabel()),
     108                    this._buildDescriptionCell(request),
    110109                    additionalRepositoryList.map((repository) => this._buildCommitCell(entry, repository)),
    111110                ]);
    112111            }))]);
     112    }
     113
     114    _buildDescriptionCell(request)
     115    {
     116        const link = ComponentBase.createLink;
     117        const element = ComponentBase.createElement;
     118        const showWarningIcon = request.hasFinished() && request.statusDescription();
     119        const cellContent = [];
     120        if (showWarningIcon)
     121            cellContent.push(element('div', {class: 'warning-icon-container'}, new WarningIcon(`Last status: ${request.statusDescription()}`)));
     122
     123        cellContent.push(request.statusUrl() ? link(request.statusLabel(), request.statusDescription(), request.statusUrl()) : request.statusLabel());
     124
     125        const hasInProgressReport = !request.hasFinished() && request.statusDescription();
     126        if (hasInProgressReport)
     127            cellContent.push(element('span', {class: 'status-description'}, `${request.statusDescription()}`));
     128
     129        return element('td', {class: 'description-cell'},  cellContent);
    113130    }
    114131
     
    223240                font-weight: inherit;
    224241            }
     242            .status-description {
     243                display: inline-block;
     244                max-width: 10rem;
     245                white-space: nowrap;
     246                text-overflow: ellipsis;
     247                overflow: hidden;
     248            }
     249            .status-description::before {
     250                content: ': ';
     251            }
     252            .description-cell {
     253                position: relative;
     254            }
     255            div.warning-icon-container {
     256                position: absolute;
     257                top: -0.2rem;
     258                left: 0;
     259            }
    225260            .roots {
    226261                max-width: 20rem;
  • trunk/Websites/perf.webkit.org/public/v3/components/warning-icon.js

    r210783 r250465  
    11
    22class WarningIcon extends ButtonBase {
    3     constructor()
     3    constructor(warningMessage)
    44    {
    55        super('warning-icon');
     6        this._warningMessage = warningMessage;
     7    }
     8
     9    render()
     10    {
     11        super.render();
     12        if (this._warningMessage)
     13            this.setButtonTitle(this._warningMessage);
    614    }
    715
  • trunk/Websites/perf.webkit.org/public/v3/models/build-request.js

    r236861 r250465  
    2727        this._createdAt = new Date(object.createdAt);
    2828        this._result = null;
     29        this._statusDescription = object.statusDescription;
    2930    }
    3031
     
    4344        this._statusUrl = object.url;
    4445        this._buildId = object.build;
     46        this._statusDescription = object.statusDescription;
    4547    }
    4648
     
    4951    testGroupId() { return this._testGroupId; }
    5052    testGroup() { return this._testGroup; }
     53    statusDescription() { return this._statusDescription; }
    5154    repositoryGroup() { return this._repositoryGroup; }
    5255    platform() { return this._platform; }
  • trunk/Websites/perf.webkit.org/server-tests/api-build-requests-tests.js

    r227777 r250465  
    5858            content['buildRequests'][2]['createdAt'] = 0;
    5959            content['buildRequests'][3]['createdAt'] = 0;
    60             assert.deepEqual(content['buildRequests'][0], {id: '704', task: '1080', triggerable: '1000', repositoryGroup: '2001', test: '200', platform: '65', testGroup: '900', order: '0', commitSet: '403', status: 'pending', url: null, build: null, createdAt: 0});
    61             assert.deepEqual(content['buildRequests'][1], {id: '705', task: '1080', triggerable: '1000', repositoryGroup: '2001', test: '200', platform: '65', testGroup: '900', order: '1', commitSet: '404', status: 'pending', url: null, build: null, createdAt: 0});
    62             assert.deepEqual(content['buildRequests'][2], {id: '706', task: '1080', triggerable: '1000', repositoryGroup: '2001', test: '200', platform: '65', testGroup: '900', order: '2', commitSet: '403', status: 'pending', url: null, build: null, createdAt: 0});
    63             assert.deepEqual(content['buildRequests'][3], {id: '707', task: '1080', triggerable: '1000', repositoryGroup: '2001', test: '200', platform: '65', testGroup: '900', order: '3', commitSet: '404', status: 'pending', url: null, build: null, createdAt: 0});
     60            assert.deepEqual(content['buildRequests'][0], {id: '704', task: '1080', triggerable: '1000', repositoryGroup: '2001', test: '200', platform: '65', testGroup: '900', order: '0', commitSet: '403', status: 'pending', statusDescription: null, url: null, build: null, createdAt: 0});
     61            assert.deepEqual(content['buildRequests'][1], {id: '705', task: '1080', triggerable: '1000', repositoryGroup: '2001', test: '200', platform: '65', testGroup: '900', order: '1', commitSet: '404', status: 'pending', statusDescription: null, url: null, build: null, createdAt: 0});
     62            assert.deepEqual(content['buildRequests'][2], {id: '706', task: '1080', triggerable: '1000', repositoryGroup: '2001', test: '200', platform: '65', testGroup: '900', order: '2', commitSet: '403', status: 'pending', statusDescription: null, url: null, build: null, createdAt: 0});
     63            assert.deepEqual(content['buildRequests'][3], {id: '707', task: '1080', triggerable: '1000', repositoryGroup: '2001', test: '200', platform: '65', testGroup: '900', order: '3', commitSet: '404', status: 'pending', statusDescription: null, url: null, build: null, createdAt: 0});
    6464       });
    6565    });
  • trunk/Websites/perf.webkit.org/server-tests/resources/mock-data.js

    r236861 r250465  
    305305            "submitted_at": options.buildTime || (new Date('2016-03-23T03:49:43Z') / 1000),
    306306            "waited_for": false,
     307            "state_string": options.statusDescription || null,
    307308            "properties": {
    308309                "build-request-id": [(options.buildRequestId || 702).toString(), "Force Build Form"],
     
    336337            "results": null,
    337338            "started_at": new Date('2017-12-19T23:11:49Z') / 1000,
    338             "state_string": "building",
     339            "state_string": options.statusDescription || null,
    339340            "workerid": 41,
    340341            "properties": {
  • trunk/Websites/perf.webkit.org/server-tests/resources/test-server.js

    r245545 r250465  
    141141        this._database = null;
    142142
    143         let initFilePath = Config.pathFromRoot('init-database.sql');
    144         this._executePgsqlCommand('psql', ['--username', this._databaseUser, '--file', initFilePath],
    145             {stdio: ['ignore', 'ignore', 'ignore']});
     143        const initFilePath = Config.pathFromRoot('init-database.sql');
     144        const migrateFilePath = Config.pathFromRoot('migrate-database.sql');
     145        for (const filePath of [initFilePath, migrateFilePath]) {
     146            this._executePgsqlCommand('psql', ['--username', this._databaseUser, '--file', filePath],
     147                {stdio: ['ignore', 'ignore', 'ignore']});
     148        }
    146149    }
    147150
  • trunk/Websites/perf.webkit.org/server-tests/tools-sync-buildbot-integration-tests.js

    r230960 r250465  
    179179}
    180180
    181 async function createTestGroupWihPatch()
     181async function createTestGroupWithPatch()
    182182{
    183183    const patchFile = await TemporaryFile.makeTemporaryFile('patch.dat', 'patch file');
     
    331331    });
    332332
     333    it('should keep updating build status', async () => {
     334        const requests = MockRemoteAPI.requests;
     335        let syncPromise;
     336        const triggerable = await createTriggerable();
     337        let testGroup = await createTestGroupWithPatch();
     338
     339        const taskId = testGroup.task().id();
     340        let webkit = Repository.findById(MockData.webkitRepositoryId());
     341        assert.equal(testGroup.buildRequests().length, 6);
     342
     343        let buildRequest = testGroup.buildRequests()[0];
     344        assert(buildRequest.isBuild());
     345        assert(!buildRequest.isTest());
     346        assert.equal(buildRequest.statusLabel(), 'Waiting');
     347        assert.equal(buildRequest.statusUrl(), null);
     348        assert.equal(buildRequest.statusDescription(), null);
     349        assert.equal(buildRequest.buildId(), null);
     350
     351        let commitSet = buildRequest.commitSet();
     352        assert.equal(commitSet.revisionForRepository(webkit), '191622');
     353        let webkitPatch = commitSet.patchForRepository(webkit);
     354        assert(webkitPatch instanceof UploadedFile);
     355        assert.equal(webkitPatch.filename(), 'patch.dat');
     356        assert.equal(commitSet.rootForRepository(webkit), null);
     357        assert.deepEqual(commitSet.allRootFiles(), []);
     358
     359        let otherBuildRequest = testGroup.buildRequests()[1];
     360        assert(otherBuildRequest.isBuild());
     361        assert(!otherBuildRequest.isTest());
     362        assert.equal(otherBuildRequest.statusLabel(), 'Waiting');
     363        assert.equal(otherBuildRequest.statusUrl(), null);
     364        assert.equal(otherBuildRequest.statusDescription(), null);
     365        assert.equal(otherBuildRequest.buildId(), null);
     366
     367        let otherCommitSet = otherBuildRequest.commitSet();
     368        assert.equal(otherCommitSet.revisionForRepository(webkit), '191622');
     369        assert.equal(otherCommitSet.patchForRepository(webkit), null);
     370        assert.equal(otherCommitSet.rootForRepository(webkit), null);
     371        assert.deepEqual(otherCommitSet.allRootFiles(), []);
     372
     373        syncPromise = triggerable.initSyncers().then(() => triggerable.syncOnce());
     374        assertAndResolveRequest(requests[0], 'GET', MockData.buildbotBuildersURL(), MockData.mockBuildbotBuilders());
     375        MockRemoteAPI.reset();
     376        await MockRemoteAPI.waitForRequest();
     377
     378        assert.equal(requests.length, 3);
     379        assertAndResolveRequest(requests[0], 'GET', MockData.pendingBuildsUrl('some tester'), {});
     380        assertAndResolveRequest(requests[1], 'GET', MockData.pendingBuildsUrl('some builder'), {});
     381        assertAndResolveRequest(requests[2], 'GET', MockData.pendingBuildsUrl('other builder'), {});
     382        await MockRemoteAPI.waitForRequest();
     383
     384        assert.equal(requests.length, 6);
     385        assertAndResolveRequest(requests[3], 'GET', MockData.recentBuildsUrl('some tester', 2), {});
     386        assertAndResolveRequest(requests[4], 'GET', MockData.recentBuildsUrl('some builder', 2), {});
     387        assertAndResolveRequest(requests[5], 'GET', MockData.recentBuildsUrl('other builder', 2), {});
     388        await MockRemoteAPI.waitForRequest();
     389
     390        assert.equal(requests.length, 7);
     391        assertAndResolveRequest(requests[6], 'POST', '/api/v2/forceschedulers/force-ab-builds', 'OK');
     392        assert.deepEqual(requests[6].data, {'id': '1', 'jsonrpc': '2.0', 'method': 'force', 'params':
     393                {'wk': '191622', 'wk-patch': RemoteAPI.url('/api/uploaded-file/1.dat'), 'checkbox': 'build-wk', 'build-wk': true, 'build-request-id': '1', 'forcescheduler': 'force-ab-builds'}});
     394        await MockRemoteAPI.waitForRequest();
     395
     396        assert.equal(requests.length, 10);
     397        assertAndResolveRequest(requests[7], 'GET', MockData.pendingBuildsUrl('some tester'), {});
     398        assertAndResolveRequest(requests[8], 'GET', MockData.pendingBuildsUrl('some builder'),
     399            MockData.pendingBuild({builderId: MockData.builderIDForName('some builder'), buildRequestId: 1}));
     400        assertAndResolveRequest(requests[9], 'GET', MockData.pendingBuildsUrl('other builder'), {});
     401        await MockRemoteAPI.waitForRequest();
     402
     403        assert.equal(requests.length, 13);
     404        assertAndResolveRequest(requests[10], 'GET', MockData.recentBuildsUrl('some tester', 2), {});
     405        assertAndResolveRequest(requests[11], 'GET', MockData.recentBuildsUrl('some builder', 2),
     406            MockData.runningBuild({builderId: MockData.builderIDForName('some builder'), buildRequestId: 1, statusDescription: 'Building WebKit'}));
     407        assertAndResolveRequest(requests[12], 'GET', MockData.recentBuildsUrl('other builder', 2), {});
     408        await syncPromise;
     409
     410        let testGroups = await TestGroup.fetchForTask(taskId, true);
     411
     412        assert.equal(testGroups.length, 1);
     413        testGroup = testGroups[0];
     414        webkit = Repository.findById(MockData.webkitRepositoryId());
     415        assert.equal(testGroup.buildRequests().length, 6);
     416
     417        buildRequest = testGroup.buildRequests()[0];
     418        assert(buildRequest.isBuild());
     419        assert(!buildRequest.isTest());
     420        assert.equal(buildRequest.statusLabel(), 'Running');
     421        assert.equal(buildRequest.statusUrl(), MockData.statusUrl('some builder', 124));
     422        assert.equal(buildRequest.statusDescription(), 'Building WebKit');
     423        assert.equal(buildRequest.buildId(), null);
     424
     425        commitSet = buildRequest.commitSet();
     426        assert.equal(commitSet.revisionForRepository(webkit), '191622');
     427        webkitPatch = commitSet.patchForRepository(webkit);
     428        assert(webkitPatch instanceof UploadedFile);
     429        assert.equal(webkitPatch.filename(), 'patch.dat');
     430        assert.equal(commitSet.rootForRepository(webkit), null);
     431        assert.deepEqual(commitSet.allRootFiles(), []);
     432
     433        otherBuildRequest = testGroup.buildRequests()[1];
     434        assert(otherBuildRequest.isBuild());
     435        assert(!otherBuildRequest.isTest());
     436        assert.equal(otherBuildRequest.statusLabel(), 'Waiting');
     437        assert.equal(otherBuildRequest.statusUrl(), null);
     438        assert.equal(otherBuildRequest.statusDescription(), null);
     439        assert.equal(otherBuildRequest.buildId(), null);
     440
     441        otherCommitSet = otherBuildRequest.commitSet();
     442        assert.equal(otherCommitSet.revisionForRepository(webkit), '191622');
     443        assert.equal(otherCommitSet.patchForRepository(webkit), null);
     444        assert.equal(otherCommitSet.rootForRepository(webkit), null);
     445        assert.deepEqual(otherCommitSet.allRootFiles(), []);
     446
     447        MockRemoteAPI.reset();
     448        syncPromise = triggerable.initSyncers().then(() => triggerable.syncOnce());
     449        assertAndResolveRequest(requests[0], 'GET', MockData.buildbotBuildersURL(), MockData.mockBuildbotBuilders());
     450        MockRemoteAPI.reset();
     451        await MockRemoteAPI.waitForRequest();
     452
     453        assert.equal(requests.length, 3);
     454        assertAndResolveRequest(requests[0], 'GET', MockData.pendingBuildsUrl('some tester'), {});
     455        assertAndResolveRequest(requests[1], 'GET', MockData.pendingBuildsUrl('some builder'), {});
     456        assertAndResolveRequest(requests[2], 'GET', MockData.pendingBuildsUrl('other builder'), {});
     457        await MockRemoteAPI.waitForRequest();
     458
     459        assert.equal(requests.length, 6);
     460        assertAndResolveRequest(requests[3], 'GET', MockData.recentBuildsUrl('some tester', 2), {});
     461        assertAndResolveRequest(requests[4], 'GET', MockData.recentBuildsUrl('some builder', 2),
     462            MockData.runningBuild({builderId: MockData.builderIDForName('some builder'), buildRequestId: 1, buildNumber: 124, state_string: 'Compiling WTF'}));
     463        assertAndResolveRequest(requests[5], 'GET', MockData.recentBuildsUrl('other builder', 2), {});
     464        await MockRemoteAPI.waitForRequest();
     465
     466        assert.equal(requests.length, 9);
     467        assertAndResolveRequest(requests[6], 'GET', MockData.pendingBuildsUrl('some tester'), {});
     468        assertAndResolveRequest(requests[7], 'GET', MockData.pendingBuildsUrl('some builder'), {});
     469        assertAndResolveRequest(requests[8], 'GET', MockData.pendingBuildsUrl('other builder'), {});
     470        await MockRemoteAPI.waitForRequest();
     471
     472        assert.equal(requests.length, 12);
     473        assertAndResolveRequest(requests[9], 'GET', MockData.recentBuildsUrl('some tester', 2), {});
     474        assertAndResolveRequest(requests[10], 'GET', MockData.recentBuildsUrl('some builder', 2), {
     475            'builds': [
     476                MockData.runningBuildData({builderId: MockData.builderIDForName('some builder'), buildRequestId: 1, state_string: 'Compiling WTF'})]
     477        });
     478        assertAndResolveRequest(requests[11], 'GET', MockData.recentBuildsUrl('other builder', 2), {});
     479        await syncPromise;
     480
     481        await TestGroup.fetchForTask(taskId, true);
     482
     483        assert.equal(testGroups.length, 1);
     484        testGroup = testGroups[0];
     485        webkit = Repository.findById(MockData.webkitRepositoryId());
     486        assert.equal(testGroup.buildRequests().length, 6);
     487
     488        buildRequest = testGroup.buildRequests()[0];
     489        assert(buildRequest.isBuild());
     490        assert(!buildRequest.isTest());
     491        assert.equal(buildRequest.statusLabel(), 'Running');
     492        assert.equal(buildRequest.statusUrl(), MockData.statusUrl('some builder', 124));
     493        assert.equal(buildRequest.statusDescription(), 'Compiling WTF');
     494        assert.equal(buildRequest.buildId(), null);
     495
     496        commitSet = buildRequest.commitSet();
     497        assert.equal(commitSet.revisionForRepository(webkit), '191622');
     498        webkitPatch = commitSet.patchForRepository(webkit);
     499        assert(webkitPatch instanceof UploadedFile);
     500        assert.equal(webkitPatch.filename(), 'patch.dat');
     501        assert.equal(commitSet.rootForRepository(webkit), null);
     502        assert.deepEqual(commitSet.allRootFiles(), []);
     503
     504        otherBuildRequest = testGroup.buildRequests()[1];
     505        assert(otherBuildRequest.isBuild());
     506        assert(!otherBuildRequest.isTest());
     507        assert.equal(otherBuildRequest.statusLabel(), 'Waiting');
     508        assert.equal(otherBuildRequest.statusUrl(), null);
     509        assert.equal(otherBuildRequest.statusDescription(), null);
     510        assert.equal(otherBuildRequest.buildId(), null);
     511
     512        otherCommitSet = otherBuildRequest.commitSet();
     513        assert.equal(otherCommitSet.revisionForRepository(webkit), '191622');
     514        assert.equal(otherCommitSet.patchForRepository(webkit), null);
     515        assert.equal(otherCommitSet.rootForRepository(webkit), null);
     516        assert.deepEqual(otherCommitSet.allRootFiles(), []);
     517
     518        await uploadRoot(buildRequest.id(), 123);
     519
     520        testGroups = await TestGroup.fetchForTask(taskId, true);
     521
     522        assert.equal(testGroups.length, 1);
     523        testGroup = testGroups[0];
     524        webkit = Repository.findById(MockData.webkitRepositoryId());
     525        assert.equal(testGroup.buildRequests().length, 6);
     526
     527        buildRequest = testGroup.buildRequests()[0];
     528        assert(buildRequest.isBuild());
     529        assert(!buildRequest.isTest());
     530        assert.equal(buildRequest.statusLabel(), 'Completed');
     531        assert.equal(buildRequest.statusUrl(), MockData.statusUrl('some builder', 124));
     532        assert.equal(buildRequest.statusDescription(), 'Compiling WTF');
     533        assert.notEqual(buildRequest.buildId(), null);
     534
     535        commitSet = buildRequest.commitSet();
     536        assert.equal(commitSet.revisionForRepository(webkit), '191622');
     537        webkitPatch = commitSet.patchForRepository(webkit);
     538        assert(webkitPatch instanceof UploadedFile);
     539        assert.equal(webkitPatch.filename(), 'patch.dat');
     540        let webkitRoot = commitSet.rootForRepository(webkit);
     541        assert(webkitRoot instanceof UploadedFile);
     542        assert.equal(webkitRoot.filename(), 'root123.dat');
     543        assert.deepEqual(commitSet.allRootFiles(), [webkitRoot]);
     544
     545        otherBuildRequest = testGroup.buildRequests()[1];
     546        assert(otherBuildRequest.isBuild());
     547        assert(!otherBuildRequest.isTest());
     548        assert.equal(otherBuildRequest.statusLabel(), 'Waiting');
     549        assert.equal(otherBuildRequest.statusUrl(), null);
     550        assert.equal(otherBuildRequest.statusDescription(), null);
     551        assert.equal(otherBuildRequest.buildId(), null);
     552
     553        otherCommitSet = otherBuildRequest.commitSet();
     554        assert.equal(otherCommitSet.revisionForRepository(webkit), '191622');
     555        assert.equal(otherCommitSet.patchForRepository(webkit), null);
     556        assert.equal(otherCommitSet.rootForRepository(webkit), null);
     557        assert.deepEqual(otherCommitSet.allRootFiles(), []);
     558
     559        MockRemoteAPI.reset();
     560        syncPromise = triggerable.initSyncers().then(() => triggerable.syncOnce());
     561        assertAndResolveRequest(requests[0], 'GET', MockData.buildbotBuildersURL(), MockData.mockBuildbotBuilders());
     562        MockRemoteAPI.reset();
     563        await MockRemoteAPI.waitForRequest();
     564
     565        assert.equal(requests.length, 3);
     566        assertAndResolveRequest(requests[0], 'GET', MockData.pendingBuildsUrl('some tester'), {});
     567        assertAndResolveRequest(requests[1], 'GET', MockData.pendingBuildsUrl('some builder'), {});
     568        assertAndResolveRequest(requests[2], 'GET', MockData.pendingBuildsUrl('other builder'), {});
     569        await MockRemoteAPI.waitForRequest();
     570
     571        assert.equal(requests.length, 6);
     572        assertAndResolveRequest(requests[3], 'GET', MockData.recentBuildsUrl('some tester', 2), {});
     573        assertAndResolveRequest(requests[4], 'GET', MockData.recentBuildsUrl('some builder', 2),
     574            MockData.finishedBuild({builderId: MockData.builderIDForName('some builder'), buildRequestId: 1, buildNumber: 124}));
     575        assertAndResolveRequest(requests[5], 'GET', MockData.recentBuildsUrl('other builder', 2), {});
     576        await MockRemoteAPI.waitForRequest();
     577
     578        assert.equal(requests.length, 7);
     579        assertAndResolveRequest(requests[6], 'POST', '/api/v2/forceschedulers/force-ab-builds', 'OK');
     580        assert.deepEqual(requests[6].data, {'id': '2', 'jsonrpc': '2.0', 'method': 'force', 'params':
     581                {'wk': '191622', 'build-request-id': '2', 'forcescheduler': 'force-ab-builds', 'checkbox': 'build-wk', 'build-wk': true}});
     582        await MockRemoteAPI.waitForRequest();
     583
     584        assert.equal(requests.length, 10);
     585        assertAndResolveRequest(requests[7], 'GET', MockData.pendingBuildsUrl('some tester'), {});
     586        assertAndResolveRequest(requests[8], 'GET', MockData.pendingBuildsUrl('some builder'), {});
     587        assertAndResolveRequest(requests[9], 'GET', MockData.pendingBuildsUrl('other builder'), {});
     588        await MockRemoteAPI.waitForRequest();
     589
     590        assert.equal(requests.length, 13);
     591        assertAndResolveRequest(requests[10], 'GET', MockData.recentBuildsUrl('some tester', 2), {});
     592        assertAndResolveRequest(requests[11], 'GET', MockData.recentBuildsUrl('some builder', 2), {
     593            'builds': [
     594                MockData.runningBuildData({builderId: MockData.builderIDForName('some builder'), buildRequestId: 2}),
     595                MockData.finishedBuildData({builderId: MockData.builderIDForName('some builder'), buildRequestId: 1, buildNumber: 124})]
     596        });
     597        assertAndResolveRequest(requests[12], 'GET', MockData.recentBuildsUrl('other builder', 2), {});
     598        await syncPromise;
     599
     600        await TestGroup.fetchForTask(taskId, true);
     601
     602        assert.equal(testGroups.length, 1);
     603        testGroup = testGroups[0];
     604        webkit = Repository.findById(MockData.webkitRepositoryId());
     605        assert.equal(testGroup.buildRequests().length, 6);
     606
     607        buildRequest = testGroup.buildRequests()[0];
     608        assert(buildRequest.isBuild());
     609        assert(!buildRequest.isTest());
     610        assert.equal(buildRequest.statusLabel(), 'Completed');
     611        assert.equal(buildRequest.statusUrl(), MockData.statusUrl('some builder', 124));
     612        assert.equal(buildRequest.statusDescription(), null);
     613        assert.notEqual(buildRequest.buildId(), null);
     614
     615        commitSet = buildRequest.commitSet();
     616        assert.equal(commitSet.revisionForRepository(webkit), '191622');
     617        webkitPatch = commitSet.patchForRepository(webkit);
     618        assert(webkitPatch instanceof UploadedFile);
     619        assert.equal(webkitPatch.filename(), 'patch.dat');
     620        webkitRoot = commitSet.rootForRepository(webkit);
     621        assert(webkitRoot instanceof UploadedFile);
     622        assert.equal(webkitRoot.filename(), 'root123.dat');
     623        assert.deepEqual(commitSet.allRootFiles(), [webkitRoot]);
     624
     625        otherBuildRequest = testGroup.buildRequests()[1];
     626        assert(otherBuildRequest.isBuild());
     627        assert(!otherBuildRequest.isTest());
     628        assert.equal(otherBuildRequest.statusLabel(), 'Running');
     629        assert.equal(otherBuildRequest.statusUrl(), MockData.statusUrl('some builder', 124));
     630        assert.equal(otherBuildRequest.statusDescription(), null);
     631        assert.equal(otherBuildRequest.buildId(), null);
     632
     633        otherCommitSet = otherBuildRequest.commitSet();
     634        assert.equal(otherCommitSet.revisionForRepository(webkit), '191622');
     635        assert.equal(otherCommitSet.patchForRepository(webkit), null);
     636        assert.equal(otherCommitSet.rootForRepository(webkit), null);
     637        assert.deepEqual(otherCommitSet.allRootFiles(), []);
     638        await uploadRoot(otherBuildRequest.id(), 124);
     639
     640        testGroups = await TestGroup.fetchForTask(taskId, true);
     641
     642        assert.equal(testGroups.length, 1);
     643        testGroup = testGroups[0];
     644        webkit = Repository.findById(MockData.webkitRepositoryId());
     645        assert.equal(testGroup.buildRequests().length, 6);
     646
     647        buildRequest = testGroup.buildRequests()[0];
     648        assert(buildRequest.isBuild());
     649        assert(!buildRequest.isTest());
     650        assert.equal(buildRequest.statusLabel(), 'Completed');
     651        assert.equal(buildRequest.statusUrl(), MockData.statusUrl('some builder', 124));
     652        assert.equal(buildRequest.statusDescription(), null);
     653        assert.notEqual(buildRequest.buildId(), null);
     654
     655        commitSet = buildRequest.commitSet();
     656        assert.equal(commitSet.revisionForRepository(webkit), '191622');
     657        webkitPatch = commitSet.patchForRepository(webkit);
     658        assert(webkitPatch instanceof UploadedFile);
     659        assert.equal(webkitPatch.filename(), 'patch.dat');
     660        webkitRoot = commitSet.rootForRepository(webkit);
     661        assert(webkitRoot instanceof UploadedFile);
     662        assert.equal(webkitRoot.filename(), 'root123.dat');
     663        assert.deepEqual(commitSet.allRootFiles(), [webkitRoot]);
     664
     665        otherBuildRequest = testGroup.buildRequests()[1];
     666        assert(otherBuildRequest.isBuild());
     667        assert(!otherBuildRequest.isTest());
     668        assert.equal(otherBuildRequest.statusLabel(), 'Completed');
     669        assert.equal(otherBuildRequest.statusUrl(), MockData.statusUrl('some builder', 124));
     670        assert.equal(otherBuildRequest.statusDescription(), null);
     671        assert.notEqual(otherBuildRequest.buildId(), null);
     672
     673        otherCommitSet = otherBuildRequest.commitSet();
     674        assert.equal(otherCommitSet.revisionForRepository(webkit), '191622');
     675        assert.equal(otherCommitSet.patchForRepository(webkit), null);
     676        const otherWebkitRoot = otherCommitSet.rootForRepository(webkit);
     677        assert(otherWebkitRoot instanceof UploadedFile);
     678        assert.equal(otherWebkitRoot.filename(), 'root124.dat');
     679        assert.deepEqual(otherCommitSet.allRootFiles(), [otherWebkitRoot]);
     680    });
     681
    333682    it('should schedule a build to build a patch', () => {
    334683        const requests = MockRemoteAPI.requests;
     
    338687        return createTriggerable().then((newTriggerable) => {
    339688            triggerable = newTriggerable;
    340             return createTestGroupWihPatch();
     689            return createTestGroupWithPatch();
    341690        }).then((testGroup) => {
    342691            taskId = testGroup.task().id();
     
    611960        return createTriggerable(configWithPlatformName).then((newTriggerable) => {
    612961            triggerable = newTriggerable;
    613             return createTestGroupWihPatch();
     962            return createTestGroupWithPatch();
    614963        }).then((testGroup) => {
    615964            taskId = testGroup.task().id();
     
    8851234        return createTriggerable().then((newTriggerable) => {
    8861235            triggerable = newTriggerable;
    887             return createTestGroupWihPatch();
     1236            return createTestGroupWithPatch();
    8881237        }).then((testGroup) => {
    8891238            taskId = testGroup.task().id();
     
    9881337        return createTriggerable().then((newTriggerable) => {
    9891338            triggerable = newTriggerable;
    990             return createTestGroupWihPatch();
     1339            return createTestGroupWithPatch();
    9911340        }).then((testGroup) => {
    9921341            taskId = testGroup.task().id();
     
    10771426        return createTriggerable().then((newTriggerable) => {
    10781427            triggerable = newTriggerable;
    1079             return createTestGroupWihPatch();
     1428            return createTestGroupWithPatch();
    10801429        }).then((testGroup) => {
    10811430            taskId = testGroup.task().id();
  • trunk/Websites/perf.webkit.org/tools/js/buildbot-syncer.js

    r245616 r250465  
    1616
    1717        this._syncer = syncer;
    18         this._buildbotBuildRequestId = rawData['buildrequestid']
     18        this._buildbotBuildRequestId = rawData['buildrequestid'];
    1919        this._hasFinished = rawData['complete'];
    2020        this._isPending = 'claimed' in rawData && !rawData['claimed'];
     
    2424        this._buildRequestId = rawData['properties'] && rawData['properties'][syncer._buildRequestPropertyName]
    2525            ? rawData['properties'][syncer._buildRequestPropertyName][0] : null;
     26        this._statusDescription = rawData['state_string'] && rawData['results'] !== 0 ? rawData['state_string'] : null;
    2627    }
    2728
     
    3435    isInProgress() { return this._isInProgress; }
    3536    hasFinished() { return this._hasFinished; }
     37    statusDescription() { return this._statusDescription; }
    3638    url() { return this.isPending() ? this._syncer.urlForPendingBuild(this._buildbotBuildRequestId) : this._syncer.urlForBuildNumber(this._buildNumber); }
    3739
  • trunk/Websites/perf.webkit.org/tools/js/buildbot-triggerable.js

    r230151 r250465  
    185185                    if (newStatus) {
    186186                        this._logger.log(`Updating the status of build request ${request.id()} from ${request.status()} to ${newStatus}`);
    187                         updates[entry.buildRequestId()] = {status: newStatus, url: entry.url()};
    188                     } else if (!request.statusUrl()) {
    189                         this._logger.log(`Setting the status URL of build request ${request.id()} to ${entry.url()}`);
    190                         updates[entry.buildRequestId()] = {status: request.status(), url: entry.url()};
     187                        updates[entry.buildRequestId()] = {status: newStatus, url: entry.url(), statusDescription: entry.statusDescription()};
     188                    } else if (!request.statusUrl() || request.statusDescription() != entry.statusDescription()) {
     189                        this._logger.log(`Updating build request ${request.id()} status URL to ${entry.url()} and status detail from ${request.statusDescription()} to ${entry.statusDescription()}`);
     190                        updates[entry.buildRequestId()] = {status: request.status(), url: entry.url(), statusDescription: entry.statusDescription()};
    191191                    }
    192192                }
  • trunk/Websites/perf.webkit.org/unit-tests/buildbot-syncer-tests.js

    r245616 r250465  
    284284}
    285285
    286 function sampleBuildData(workerName, isComplete, buildRequestId, buildNumber, builderId)
     286function sampleBuildData(workerName, isComplete, buildRequestId, buildNumber, builderId, state_string)
    287287{
    288288    return {
     
    296296        "results": null,
    297297        "started_at": 1513725109,
    298         "state_string": "building",
     298        state_string,
    299299        "workerid": 41,
    300300        "properties": {
     
    303303            "scheduler": ["ABTest-iPad-RunBenchmark-Tests-ForceScheduler", "Scheduler"],
    304304            "slavename": [workerName || "ABTest-iPad-0", "Worker (deprecated)"],
    305             "workername": [workerName || "ABTest-iPad-0", "Worker"]
     305            "workername": [workerName || "ABTest-iPad-0", "Worker"],
    306306        }
    307307    };
     
    310310function sampleInProgressBuildData(workerName)
    311311{
    312     return sampleBuildData(workerName, false);
     312    return sampleBuildData(workerName, false, null, null, null, 'building');
    313313}
    314314
     
    11181118            assert.ok(!entry.hasFinished());
    11191119            assert.equal(entry.url(), 'http://build.webkit.org/#/buildrequests/17');
     1120            assert.equal(entry.statusDescription(), null);
    11201121        });
    11211122
     
    11351136            assert.ok(!entry.hasFinished());
    11361137            assert.equal(entry.url(), 'http://build.webkit.org/#/builders/102/builds/614');
     1138            assert.equal(entry.statusDescription(), 'building');
    11371139        });
    11381140
     
    11521154            assert.ok(entry.hasFinished());
    11531155            assert.equal(entry.url(), 'http://build.webkit.org/#/builders/102/builds/1755');
     1156            assert.equal(entry.statusDescription(), null);
    11541157        });
    11551158
     
    11701173            assert.ok(!entry.hasFinished());
    11711174            assert.equal(entry.url(), 'http://build.webkit.org/#/builders/102/builds/614');
     1175            assert.equal(entry.statusDescription(), 'building');
    11721176
    11731177            entry = entries[1];
     
    11801184            assert.ok(entry.hasFinished());
    11811185            assert.equal(entry.url(), 'http://build.webkit.org/#/builders/102/builds/1755');
     1186            assert.equal(entry.statusDescription(), null);
    11821187        });
    11831188    });
Note: See TracChangeset for help on using the changeset viewer.