Changeset 172891 in webkit


Ignore:
Timestamp:
Aug 23, 2014 6:22:00 PM (10 years ago)
Author:
ap@apple.com
Message:

build.webkit.org/dashboard: Make it possible to pull historic data from Buildbot
https://bugs.webkit.org/show_bug.cgi?id=136182

Reviewed by Timothy Hatcher.

  • BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/BuildbotIteration.js:

Make it possible to create a complete BuildbotIteration object with JSON, not only by
loading data from the network.

An iteration has three states:

  1. Just created, it only knows the revision, and whether it's already finished.

BuildbotIteration constructor used to create these.

  1. A complete JSON report loaded from buildbot. The new constructor form creates these.
  2. Data about tests is fetched.
  • BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/BuildbotQueue.js:

Make it possible to pull all data from a buildbot queue. This needs to be better
optimized eventually, as it's somewhat slow.

Location:
trunk/Tools
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/BuildbotIteration.js

    r169080 r172891  
    2424 */
    2525
    26 BuildbotIteration = function(queue, id, finished)
     26BuildbotIteration = function(queue, dataOrID, finished)
    2727{
    2828    BaseObject.call(this);
     
    3131
    3232    this.queue = queue;
    33     this.id = id;
     33
     34    if (typeof dataOrID === "object") {
     35        this._parseData(dataOrID);
     36        return;
     37    }
     38
     39    console.assert(typeof dataOrID === "number");
     40    this.id = dataOrID;
    3441
    3542    this.loaded = false;
     
    154161    },
    155162
    156     update: function()
    157     {
    158         if (this.loaded && this._finished)
    159             return;
    160 
    161         if (this.queue.buildbot.needsAuthentication && this.queue.buildbot.authenticationStatus === Buildbot.AuthenticationStatus.InvalidCredentials)
    162             return;
    163 
     163    _parseData: function(data)
     164    {
    164165        function collectTestResults(data, stepName)
    165166        {
     
    215216        }
    216217
     218        console.assert(!this.id || this.id === data.number);
     219        this.id = data.number;
     220
     221        // The property got_revision may have the following forms:
     222        //
     223        // ["got_revision",{"Internal":"1357","WebKitOpenSource":"2468"},"Source"]
     224        // OR
     225        // ["got_revision","2468_1357","Source"]
     226        // OR
     227        // ["got_revision","2468","Source"]
     228        //
     229        // When extracting the OpenSource revision from property got_revision we don't need to check whether the
     230        // value of got_revision is a dictionary (represents multiple codebases) or a string literal because we
     231        // assume that got_revision contains the OpenSource revision. However, it may not have the Internal
     232        // revision. Therefore, we only look at got_revision to extract the Internal revision when it's
     233        // a dictionary.
     234
     235        var openSourceRevisionProperty = data.properties.findFirst(function(property) { return property[0] === "got_revision" || property[0] === "revision" || property[0] === "opensource_got_revision"; });
     236        this.openSourceRevision = parseRevisionProperty(openSourceRevisionProperty, "WebKit");
     237
     238        var internalRevisionProperty = data.properties.findFirst(function(property) { return property[0] === "internal_got_revision" || isMultiCodebaseGotRevisionProperty(property); });
     239        this.internalRevision = parseRevisionProperty(internalRevisionProperty, "Internal");
     240
     241        this.branch = data.properties.findFirst(function(property) { return property[0] === "branch" })[1];
     242
     243        this.changes = [];
     244        var changes = data.sourceStamp.changes;
     245        for (var i = 0; i < changes.length; ++i)
     246            this.changes[i] = { revisionNumber: parseInt(changes[i].revision, 10) }
     247
     248        this.startTime = new Date(data.times[0] * 1000);
     249        this.endTime = new Date(data.times[1] * 1000);
     250
     251        var layoutTestResults = collectTestResults.call(this, data, "layout-test");
     252        this.layoutTestResults = layoutTestResults ? new BuildbotTestResults(this, layoutTestResults) : null;
     253
     254        var javascriptTestResults = collectTestResults.call(this, data, "jscore-test");
     255        this.javascriptTestResults = javascriptTestResults ? new BuildbotTestResults(this, javascriptTestResults) : null;
     256
     257        var apiTestResults = collectTestResults.call(this, data, "run-api-tests");
     258        this.apiTestResults = apiTestResults ? new BuildbotTestResults(this, apiTestResults) : null;
     259
     260        var platformAPITestResults = collectTestResults.call(this, data, "API tests");
     261        this.platformAPITestResults = platformAPITestResults ? new BuildbotTestResults(this, platformAPITestResults) : null;
     262
     263        var pythonTestResults = collectTestResults.call(this, data, "webkitpy-test");
     264        this.pythonTestResults = pythonTestResults ? new BuildbotTestResults(this, pythonTestResults) : null;
     265
     266        var perlTestResults = collectTestResults.call(this, data, "webkitperl-test");
     267        this.perlTestResults = perlTestResults ? new BuildbotTestResults(this, perlTestResults) : null;
     268
     269        var bindingTestResults = collectTestResults.call(this, data, "bindings-generation-tests");
     270        this.bindingTestResults = bindingTestResults ? new BuildbotTestResults(this, bindingTestResults) : null;
     271
     272        this.loaded = true;
     273
     274        this._firstFailedStep = data.steps.findFirst(function(step) { return step.results[0] === BuildbotIteration.FAILURE; });
     275
     276        console.assert(data.results === null || typeof data.results === "number");
     277        this._result = data.results;
     278
     279        this.text = data.text.join(" ");
     280
     281        if (!data.currentStep)
     282            this.finished = true;
     283
     284        // Update the sorting since it is based on the revisions we just loaded.
     285        this.queue.sortIterations();
     286    },
     287
     288    _updateWithData: function(data)
     289    {
     290        if (this.loaded && this._finished)
     291            return;
     292
     293        this._parseData(data);
     294        this.dispatchEventToListeners(BuildbotIteration.Event.Updated);
     295    },
     296
     297    update: function()
     298    {
     299        if (this.loaded && this._finished)
     300            return;
     301
     302        if (this.queue.buildbot.needsAuthentication && this.queue.buildbot.authenticationStatus === Buildbot.AuthenticationStatus.InvalidCredentials)
     303            return;
     304
    217305        JSON.load(this.queue.baseURL + "/builds/" + this.id, function(data) {
    218306            this.queue.buildbot.isAuthenticated = true;
     
    220308                return;
    221309
    222             // The property got_revision may have the following forms:
    223             //
    224             // ["got_revision",{"Internal":"1357","WebKitOpenSource":"2468"},"Source"]
    225             // OR
    226             // ["got_revision","2468_1357","Source"]
    227             // OR
    228             // ["got_revision","2468","Source"]
    229             //
    230             // When extracting the OpenSource revision from property got_revision we don't need to check whether the
    231             // value of got_revision is a dictionary (represents multiple codebases) or a string literal because we
    232             // assume that got_revision contains the OpenSource revision. However, it may not have the Internal
    233             // revision. Therefore, we only look at got_revision to extract the Internal revision when it's
    234             // a dictionary.
    235 
    236             var openSourceRevisionProperty = data.properties.findFirst(function(property) { return property[0] === "got_revision" || property[0] === "revision" || property[0] === "opensource_got_revision"; });
    237             this.openSourceRevision = parseRevisionProperty(openSourceRevisionProperty, "WebKit");
    238 
    239             var internalRevisionProperty = data.properties.findFirst(function(property) { return property[0] === "internal_got_revision" || isMultiCodebaseGotRevisionProperty(property); });
    240             this.internalRevision = parseRevisionProperty(internalRevisionProperty, "Internal");
    241 
    242             var layoutTestResults = collectTestResults.call(this, data, "layout-test");
    243             this.layoutTestResults = layoutTestResults ? new BuildbotTestResults(this, layoutTestResults) : null;
    244 
    245             var javascriptTestResults = collectTestResults.call(this, data, "jscore-test");
    246             this.javascriptTestResults = javascriptTestResults ? new BuildbotTestResults(this, javascriptTestResults) : null;
    247 
    248             var apiTestResults = collectTestResults.call(this, data, "run-api-tests");
    249             this.apiTestResults = apiTestResults ? new BuildbotTestResults(this, apiTestResults) : null;
    250 
    251             var platformAPITestResults = collectTestResults.call(this, data, "API tests");
    252             this.platformAPITestResults = platformAPITestResults ? new BuildbotTestResults(this, platformAPITestResults) : null;
    253 
    254             var pythonTestResults = collectTestResults.call(this, data, "webkitpy-test");
    255             this.pythonTestResults = pythonTestResults ? new BuildbotTestResults(this, pythonTestResults) : null;
    256 
    257             var perlTestResults = collectTestResults.call(this, data, "webkitperl-test");
    258             this.perlTestResults = perlTestResults ? new BuildbotTestResults(this, perlTestResults) : null;
    259 
    260             var bindingTestResults = collectTestResults.call(this, data, "bindings-generation-tests");
    261             this.bindingTestResults = bindingTestResults ? new BuildbotTestResults(this, bindingTestResults) : null;
    262 
    263             this.loaded = true;
    264 
    265             this._firstFailedStep = data.steps.findFirst(function(step) { return step.results[0] === BuildbotIteration.FAILURE; });
    266 
    267             console.assert(data.results === null || typeof data.results === "number");
    268             this._result = data.results;
    269 
    270             this.text = data.text.join(" ");
    271 
    272             if (!data.currentStep)
    273                 this.finished = true;
    274 
    275             // Update the sorting since it is based on the revisions we just loaded.
    276             this.queue.sortIterations();
    277 
    278             this.dispatchEventToListeners(BuildbotIteration.Event.Updated);
     310            this._updateWithData(data);
    279311        }.bind(this),
    280312        function(data) {
  • trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/BuildbotQueue.js

    r172097 r172891  
    6666    },
    6767
     68    get allIterationsURL()
     69    {
     70        // Getting too many builds results in a timeout error, 10000 is OK.
     71        return this.buildbot.baseURL + "json/builders/" + encodeURIComponent(this.id) + "/builds/_all/?max=10000";
     72    },
     73
    6874    get overviewURL()
    6975    {
     
    119125    },
    120126
    121     update: function()
     127    _load: function(url, callback)
    122128    {
    123129        if (this.buildbot.needsAuthentication && this.buildbot.authenticationStatus === Buildbot.AuthenticationStatus.InvalidCredentials)
    124130            return;
    125131
    126         JSON.load(this.baseURL, function(data) {
    127             this.buildbot.isAuthenticated = true;
     132        JSON.load(
     133            url,
     134            function(data) {
     135                this.buildbot.isAuthenticated = true;
     136                callback(data);
     137            }.bind(this),
     138            function(data) {
     139                if (this.buildbot.isAuthenticated) {
     140                    // FIXME (128006): Safari/WebKit should coalesce authentication requests with the same origin and authentication realm.
     141                    // In absence of the fix, Safari presents additional authentication dialogs regardless of whether an earlier authentication
     142                    // dialog was dismissed. As a way to ameliorate the user experience where a person authenticated successfully using an
     143                    // earlier authentication dialog and cancelled the authentication dialog associated with the load for this queue, we call
     144                    // ourself so that we can schedule another load, which should complete successfully now that we have credentials.
     145                    this._load(url, callback);
     146                    return;
     147                }
     148                if (data.errorType === JSON.LoadError && data.errorHTTPCode === 401) {
     149                    this.buildbot.isAuthenticated = false;
     150                    this.dispatchEventToListeners(BuildbotQueue.Event.UnauthorizedAccess, { });
     151                }
     152            }.bind(this),
     153            {withCredentials: this.buildbot.needsAuthentication}
     154        );
     155    },
     156
     157    update: function()
     158    {
     159        this._load(this.baseURL, function(data) {
    128160            if (!(data.cachedBuilds instanceof Array))
    129161                return;
     
    156188
    157189            this.dispatchEventToListeners(BuildbotQueue.Event.IterationsAdded, {addedIterations: newIterations});
    158         }.bind(this),
    159         function(data) {
    160             if (this.buildbot.isAuthenticated) {
    161                 // FIXME (128006): Safari/WebKit should coallesce authentication requests with the same origin and authentication realm.
    162                 // In absence of the fix, Safari presents additional authentication dialogs regardless of whether an earlier authentication
    163                 // dialog was dismissed. As a way to ameliorate the user experience where a person authenticated successfully using an
    164                 // earlier authentication dialog and cancelled the authentication dialog associated with the load for this queue, we call
    165                 // ourself so that we can schedule another load, which should complete successfully now that we have credentials.
    166                 this.update();
    167                 return;
     190        }.bind(this));
     191    },
     192
     193    loadAll: function(callback)
     194    {
     195        // FIXME: Don't load everything at once, do it incrementally as requested.
     196        this._load(this.allIterationsURL, function(data) {
     197            for (var idString in data) {
     198                console.assert(typeof idString === "string");
     199                iteration = new BuildbotIteration(this, data[idString]);
     200                this.iterations.push(iteration);
     201                this._knownIterations[iteration.id] = iteration;
    168202            }
    169             if (data.errorType === JSON.LoadError && data.errorHTTPCode === 401) {
    170                 this.buildbot.isAuthenticated = false;
    171                 this.dispatchEventToListeners(BuildbotQueue.Event.UnauthorizedAccess, { });
    172             }
    173         }.bind(this), {withCredentials: this.buildbot.needsAuthentication});
     203
     204            callback(this);
     205        }.bind(this));
    174206    },
    175207
  • trunk/Tools/ChangeLog

    r172883 r172891  
     12014-08-23  Alexey Proskuryakov  <ap@apple.com>
     2
     3        build.webkit.org/dashboard: Make it possible to pull historic data from Buildbot
     4        https://bugs.webkit.org/show_bug.cgi?id=136182
     5
     6        Reviewed by Timothy Hatcher.
     7
     8        * BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/BuildbotIteration.js:
     9        Make it possible to create a complete BuildbotIteration object with JSON, not only by
     10        loading data from the network.
     11
     12        An iteration has three states:
     13        1. Just created, it only knows the revision, and whether it's already finished.
     14        BuildbotIteration constructor used to create these.
     15        2. A complete JSON report loaded from buildbot. The new constructor form creates these.
     16        3. Data about tests is fetched.
     17
     18        * BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/BuildbotQueue.js:
     19        Make it possible to pull all data from a buildbot queue. This needs to be better
     20        optimized eventually, as it's somewhat slow.
     21
    1222014-08-22  Renato Nagy  <nagy.renato@stud.u-szeged.hu>
    223
Note: See TracChangeset for help on using the changeset viewer.