Home | History | Annotate | Download | only in sheriffing
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 /** Information about a particular waterfall. */
      6 function WaterfallInfo(waterfallData) {
      7   var waterfallName = waterfallData[0];
      8   var waterfallUrl = waterfallData[1];
      9   var waterfallShowsAllBots = waterfallData[2];
     10 
     11   // Create a table cell that acts as a header for its bot section.
     12   var linkElement = document.createElement('a');
     13   linkElement.href = waterfallUrl;
     14   linkElement.innerHTML = waterfallName;
     15   var thElement = document.createElement('th');
     16   thElement.colSpan = 15;
     17   thElement.className = 'section-header';
     18   thElement.appendChild(linkElement);
     19 
     20   this.botInfo = {};
     21   this.inFlight = 0;
     22   this.name = waterfallName;
     23   this.showsAllBots = waterfallShowsAllBots;
     24   this.thElement = thElement;
     25   this.timeLastRequested = 0;
     26   this.rootJsonUrl = waterfallUrl + 'json/';
     27   this.url = waterfallUrl;
     28 }
     29 
     30 /** Send an asynchronous request to get the main waterfall's JSON. */
     31 WaterfallInfo.prototype.requestJson = function() {
     32   if (this.inFlight) {
     33     var elapsed = new Date().getTime() - this.timeLastRequested;
     34     if (elapsed < MAX_MILLISECONDS_TO_WAIT) return;
     35 
     36     // A response was not received in a reasonable timeframe. Try again.
     37     this.inFlight--;
     38     gNumRequestsInFlight--;
     39     gNumRequestsRetried++;
     40   }
     41 
     42   this.inFlight++;
     43   this.timeLastRequested = new Date().getTime();
     44   gNumRequestsInFlight++;
     45 
     46   // Create the request and send it off.
     47   var waterfallInfo = this;
     48   var url = this.url + 'json/builders/';
     49   var request = new XMLHttpRequest();
     50   request.open('GET', url, true);
     51   request.onreadystatechange = function() {
     52     if (request.readyState == 4 && request.status == 200) {
     53       waterfallInfo.parseJSON(JSON.parse(request.responseText));
     54     }
     55   };
     56   request.send(null);
     57 };
     58 
     59 /** Parse out the data received about the waterfall. */
     60 WaterfallInfo.prototype.parseJSON = function(buildersJson) {
     61   this.inFlight--;
     62   gNumRequestsInFlight--;
     63 
     64   // Go through each builder on the waterfall and get the latest status.
     65   var builderNames = Object.keys(buildersJson);
     66   for (var i = 0; i < builderNames.length; ++i) {
     67     var builderName = builderNames[i];
     68 
     69     if (!this.showsAllBots && !this.shouldShowBot(builderName)) continue;
     70 
     71     // Prepare the bot info.
     72     var builderJson = buildersJson[builderName];
     73     if (!this.botInfo[builderName]) {
     74       this.botInfo[builderName] = new BotInfo(builderName,
     75                                               builderJson.category);
     76     }
     77     this.botInfo[builderName].update(this.rootJsonUrl, builderJson);
     78     gWaterfallDataIsDirty = true;
     79   }
     80 };
     81 
     82 /** Override this function to filter out particular bots. */
     83 WaterfallInfo.prototype.shouldShowBot = function(builderName) {
     84   return true;
     85 };
     86 
     87 /** Updates the HTML. */
     88 WaterfallInfo.prototype.updateWaterfallStatusHTML = function() {
     89   var table = document.getElementById('build-info');
     90 
     91   // Point at the waterfall.
     92   var headerCell = this.thElement;
     93   headerCell.className =
     94       'section-header' + (this.inFlight > 0 ? ' in-flight' : '');
     95   var headerRow = table.insertRow(-1);
     96   headerRow.appendChild(headerCell);
     97 
     98   // Print out useful bits about the bots.
     99   var botNames = sortBotNamesByCategory(this.botInfo);
    100   for (var i = 0; i < botNames.length; ++i) {
    101     var botName = botNames[i];
    102     var botInfo = this.botInfo[botName];
    103     var waterfallBaseUrl = this.url + 'builders/';
    104 
    105     var botRowElement = botInfo.createHtml(waterfallBaseUrl);
    106 
    107     // Determine whether we should apply keyword filter.
    108     var filter = document.getElementById('text-filter').value.trim();
    109     if (filter.length > 0) {
    110       var keywords = filter.split(' ');
    111       var buildNumbers = Object.keys(botInfo.builds);
    112       var matchesFilter = false;
    113 
    114       for (var x = 0; x < buildNumbers.length && !matchesFilter; ++x) {
    115         var buildStatus = botInfo.builds[buildNumbers[x]].statusText;
    116         for (var y = 0; y < keywords.length && !matchesFilter; ++y) {
    117           if (buildStatus.indexOf(keywords[y]) >= 0)
    118             matchesFilter = true;
    119         }
    120       }
    121 
    122       if (!matchesFilter)
    123         continue;
    124     }
    125 
    126     // If the user doesn't want to see completely green bots, hide it.
    127     var shouldHideStable =
    128         document.getElementById('checkbox-hide-stable').checked;
    129     if (shouldHideStable && botInfo.isSteadyGreen)
    130       continue;
    131 
    132     table.appendChild(botRowElement);
    133   }
    134 };
    135