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. */ 6function 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. */ 31WaterfallInfo.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. */ 60WaterfallInfo.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. */ 83WaterfallInfo.prototype.shouldShowBot = function(builderName) { 84 return true; 85}; 86 87/** Updates the HTML. */ 88WaterfallInfo.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