YUI(Yconfig).use( 'gallery-base64', 'node', 'history', 'io', 'cookie', 'querystring-stringify-simple', 'json', 'linaro-overlay-utils', 'linaro-trivia', 'jsonp', 'datatable', function (Y) { var history = new Y.HistoryHash(); Y.on( 'history:change', function (e) { if (e.src === Y.HistoryHash.SRC_HASH) { // URL changed if (typeof getDownloadURL.downloadUrl != "undefined") { delete getDownloadURL.downloadUrl; } displayJobByNumber(e.changed.build.newVal); } } ); var allBuilds; var buildNumber = history.get('build'); var fetchLatest = (buildNumber === undefined); var jobData = 'actions[parameters[name,value]],timestamp,duration,artifacts[displayPath,fileName,relativePath],result,number'; var buildName = rawBuildName.replace('/', '_').substring(1); var treeExp = 'actions[parameterDefinitions[defaultParameterValue[value],name]],builds[number],queueItem[params],description'; if (fetchLatest) { treeExp += ',lastBuild[' + jobData + ']'; } var jobUrl = globalConfig.jenkinsURL + "/job/" + buildName; function patternInName (name, list) { // Check for patterns from 'list' in 'name'. // If found returns 'true' otherwise 'false'. for (var i = 0; i < list.length; i++) { if (name.indexOf(list[i])>=0) { return true; } } return false; } function receivedTestResultJSON (response, loadingNode) { var columns = [ {label:"Name", formatter: function (o) { return '' + o.data.name + ''; } }, {label:"Pass", formatter: function (o) { return o.data.results.pass || 0; } }, {label:"Fail", formatter: function (o) { return o.data.results.fail || 0; } }, {label:"Measurement", formatter: function (o) { var measurements = o.data.results.measurements; if (!measurements || (measurements.length == 0)){ return " "; } var contents = new Array(); var index = 0; for (var index=0; index < measurements.length; index++){ var item = measurements[index]; var oneLine = ""; oneLine = oneLine + "" + item.item +""; oneLine = oneLine + "" + item.measurement +""; oneLine = oneLine + "" + item.units +""; oneLine = oneLine + ""; contents[index] = oneLine; } return ""+contents.join(" ")+"
"; }} ]; var recordset = new Y.Recordset({records: response.test_runs}); var newTable = Y.Node.create(''); loadingNode.replace(newTable); var dt = new Y.DataTable.Base( { columnset: columns }); dt.set('recordset', recordset); dt.render(newTable); } function receivedJobJSON (response, job_info_json_url) { var newNode = Y.Node.create('
'); newNode.appendChild(Y.Node.create('

').setContent('Status: ' + response.status)); var linkNode = Y.Node.create('

Job details

'); linkNode.one('a').setAttribute('href', job_info_json_url); if (response.results_link) { var loadingString = Y.Node.create('

Loading

'); newNode.appendChild(loadingString); var resultLink = Y.Node.create('Result details'); resultLink.setAttribute('href', response.results_link); linkNode.appendChild(document.createTextNode(' ')); linkNode.appendChild(resultLink); Y.jsonp( response.results_link + 'json?callback={callback}', { args: [loadingString], on: { success: receivedTestResultJSON } } ); } newNode.appendChild(linkNode); Y.one("#testresults").get('childNodes').remove(); Y.one("#testresults").appendChild(newNode); } function receivedLavaJobInfo (e, response) { var job_info; try { job_info = Y.JSON.parse(response.responseText); } catch (e) { Y.one("#testresults").setContent("Unexpected error getting LAVA job id"); console.error("Exception parsing (expected) lava-job-id file: ", e, response.responseText); return; } if (typeof job_info.lava_url == "undefined") { Y.one("#testresults").setContent("This build did not undergo LAVA testing."); return; } var job_info_json_url = job_info.lava_url; if (job_info_json_url.substr(job_info_json_url.length - 1) != '/') { job_info_json_url = job_info_json_url + '/'; } job_info_json_url = job_info_json_url + 'scheduler/job/' + job_info.job_id; Y.one("#testresults").append("
Requesting LAVA job information..."); Y.jsonp( job_info_json_url + '/json?callback={callback}', { args: [job_info_json_url], on: { success: receivedJobJSON, failure: function (e) { // TODO: This should check for 403 first, but wouldn't // work due to lp:1003817 Y.one("#testresults").append('
To see test results, please ' + 'login ' + 'to LAVA and refresh this page. ' + '(Test results are available to Linaro members).'); } } } ); } function getProxyURL () { return '/api/proxy-remote-file?url='; } function getDownloadURL(results) { /* Work out where to download from. The assumption is that all downloads will end up on snapshots.linaro.org soon, but we want to detect if they haven't moved. If we can't find a build on snapshots and we can find it locally, point the download location to the local build. If we can't find it locally either, keep pointing at snapshots. */ if (typeof getDownloadURL.downloadUrl != "undefined") { return getDownloadURL.downloadUrl; // Return cached result } var downloadUrl = 'http://snapshots.linaro.org/android/' + rawBuildName + '/' + results.number.toString() + '/'; var test_snapshots = Y.io( '/api/test-dir-exists?url=' + downloadUrl, { sync: true }); if (test_snapshots.status != 200) // snapshots.linaro.org doesn't host this build { // Test to see if the local server (probably android-build.linaro.org) does. var testUrl = 'http://android-build.linaro.org/builds/' + rawBuildName + '/' + results.number.toString() + '/'; var test_local = Y.io( '/api/test-dir-exists?url=' + testUrl, { sync: true }); if (test_local.status == 200) { // Found a build host - update download link. downloadUrl = testUrl; } } getDownloadURL.downloadUrl = downloadUrl; // Save result to speed up future calls return downloadUrl; } var element_mapping = { status: function (results) { return results.result || "RUNNING"; }, configuration: function (results) { for (var i = 0; i < results.actions.length; i++) { if (results.actions[i].parameters) { var params = results.actions[i].parameters; for (var j = 0; j < params.length; j++) { if (params[j].name == "CONFIG") { try { return Y.Base64.decode(params[j].value); } catch (error) { console.error("Exception decoding base64 job config: ", error); return 'Not Base64 encoded?'; } } } } } return '???'; }, started: function (results) { return Y.linaro.formatDateFromTimestamp(results.timestamp); }, finished: function (results) { if (results.timestamp && results.duration) { return Y.linaro.formatDateFromTimestamp(results.timestamp + results.duration); } else { return ''; } }, loglink: function (results) { return 'Parsed - Tail - Raw'; }, testresults: function (results) { var downloadUrl = getDownloadURL(results); Y.io( getProxyURL() + downloadUrl + '/lava-job-info', { on: { success: receivedLavaJobInfo, failure: function(id, resp) { Y.one('#testresults').append('
Could not load lava-job-info: ' + resp.responseText); } } }); return 'Loading...'; }, output: function (results) { /* Generate a download list */ /* In case getDownloadURL fails for some reason, we always have a link to where new builds should be. */ var downloadUrl = 'http://snapshots.linaro.org/android/' + rawBuildName + '/' + results.number.toString() + '/'; handleRenderedFiles('android/' + rawBuildName + '/' + results.number.toString()); var hiddenFilesPatterns = ['HOWTO_', 'BUILD-INFO', 'EULA', 'textile']; Y.one('#all-output a').setAttribute('href', downloadUrl); Y.one('#all-output a').removeClass('hidden'); Y.one('#all-output span').addClass('hidden'); downloadUrl = getDownloadURL(results); /* Decision made about downloadUrl. Now use it. We test to see if we can find manifest.txt, which is a list of all files available for download. If we can't find it we try using results.artifacts. If that fails, we display a message saying that we can't provide a downloads list. */ var io_result = Y.io( getProxyURL() + downloadUrl + '/MANIFEST', { sync: true }); if (io_result.status == 200) { var manifest = io_result.responseText.split("\n"); // If we get webpage instead of plain text, it's likely because // this is restricted build. if (manifest.indexOf('') >= 0) { return; } var listNode = Y.Node.create('