Skip to content

Commit

Permalink
Check Jenkins query exception message
Browse files Browse the repository at this point in the history
Ignore invalid build url when the error is 404

Fixes: adoptium#4

Signed-off-by: lanxia <lan_xia@ca.ibm.com>
  • Loading branch information
llxia committed Nov 12, 2018
1 parent 1841e5b commit 8c3aad4
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 78 deletions.
101 changes: 50 additions & 51 deletions TestResultSummaryService/BuildProcessor.js
Original file line number Diff line number Diff line change
@@ -1,106 +1,105 @@
const DataManager = require( './DataManager' );
const JenkinsInfo = require( './JenkinsInfo' );
const LogStream = require( './LogStream' );
const Parsers = require( `./parsers/` );
const ParentBuild = require( `./parsers/ParentBuild` );
const ObjectID = require( 'mongodb' ).ObjectID;
const { OutputDB } = require( './Database' );
const { logger } = require( './Utils' );
const DataManager = require('./DataManager');
const JenkinsInfo = require('./JenkinsInfo');
const LogStream = require('./LogStream');
const Parsers = require(`./parsers/`);
const ParentBuild = require(`./parsers/ParentBuild`);
const ObjectID = require('mongodb').ObjectID;
const { OutputDB } = require('./Database');
const { logger } = require('./Utils');

class BuildProcessor {
async execute( task ) {
async execute(task) {
const { url, buildName, buildNum } = task;
const jenkinsInfo = new JenkinsInfo();
const buildInfo = await jenkinsInfo.getBuildInfo( task.url, task.buildName, task.buildNum );
const buildInfo = await jenkinsInfo.getBuildInfo(task.url, task.buildName, task.buildNum);

if ( buildInfo ) {
if (buildInfo) {
if (buildInfo.code === 404) {
/*
* Return code is 404. The url is invalid or the build does not
* exist on Jenkins any more, just set status to Done and store
* the build info
*/
task.status = "Done";
await new DataManager().updateBuild(task);
return;
}
let output = "";
if ( task.status === "Streaming" ) {
if (task.status === "Streaming") {
let startPtr = 0;
//if output exists, get last position from output and continue stream. Otherwise, create build.
if ( task.buildOutputId ) {
// if output exists, get last position from output and continue
// streaming. Otherwise, create build.
if (task.buildOutputId) {
const outputDB = new OutputDB();
const result = await outputDB.getData( { _id: new ObjectID( task.buildOutputId ) } ).toArray();
const result = await outputDB.getData({ _id: new ObjectID(task.buildOutputId) }).toArray();

if ( result && result.length === 1 ) {
if (result && result.length === 1) {
startPtr = result[0].output.length;
output = result[0].output;
} else {
throw new Error( "outputDB.getData cannot find match", result );
throw new Error("outputDB.getData cannot find match", result);
}
}

let chunk = null;
try {
const logStream = new LogStream( {
const logStream = new LogStream({
baseUrl: url,
job: buildName,
build: buildNum,
pollInterval: 1 * 60 * 1000,
} );
chunk = await logStream.next( startPtr );
} catch ( e ) {
logger.error( e );
logger.error( "Cannot get log stream ", task );
});
chunk = await logStream.next(startPtr);
} catch (e) {
logger.error(e);
logger.error("Cannot get log stream ", task);
}
output += chunk;
logger.debug( "startPtr", startPtr );
logger.silly( "chunk", chunk );
logger.debug("startPtr", startPtr);
logger.silly("chunk", chunk);

task.output = output;
await new DataManager().updateBuildWithOutput( task );
await new DataManager().updateBuildWithOutput(task);

if ( !buildInfo.building && buildInfo.result !== null ) {
await new DataManager().updateBuild( {
if (!buildInfo.building && buildInfo.result !== null) {
await new DataManager().updateBuild({
_id: task._id,
buildDuration: buildInfo.duration,
buildResult: buildInfo.result,
buildUrl: buildInfo.url,
timestamp: buildInfo.timestamp,
status: "Done",
} );
} else if ( !task.timestamp || !task.buildUrl ) {
await new DataManager().updateBuild( {
});
} else if (!task.timestamp || !task.buildUrl) {
await new DataManager().updateBuild({
_id: task._id,
buildUrl: buildInfo.url,
timestamp: buildInfo.timestamp,
} );
});
}
} else if ( task.status === "NotDone" ) {
} else if (task.status === "NotDone") {
// if the build is done, update the record in db.
// else if no timestamp or buildUrl, update the record in db.
// Otherwise, do nothing.
if ( buildInfo && !buildInfo.building && buildInfo.result !== null ) {
if (buildInfo && !buildInfo.building && buildInfo.result !== null) {
task.timestamp = buildInfo.timestamp;
task.buildUrl = buildInfo.url;
task.buildDuration = buildInfo.duration;
task.buildResult = buildInfo.result;
task.status = "Done";

output = await jenkinsInfo.getBuildOutput( task.url, task.buildName, task.buildNum );
output = await jenkinsInfo.getBuildOutput(task.url, task.buildName, task.buildNum);
task.output = output;
await new DataManager().updateBuildWithOutput( task );
} else if ( !task.timestamp || !task.buildUrl ) {
await new DataManager().updateBuild( {
await new DataManager().updateBuildWithOutput(task);
} else if (!task.timestamp || !task.buildUrl) {
await new DataManager().updateBuild({
_id: task._id,
buildUrl: buildInfo.url,
timestamp: buildInfo.timestamp,
} );
});
}
}
} else {
/*
if the build does not exist on Jenkins any more, just
set status to Done and store the build info
*/
// TODO: the code can be more precise and check for error
// that is caught in jenkinsInfo.getBuildInfo() to
// determine if it is a build does not exist or connection
// issue.
task.status = "Done";
await new DataManager().updateBuild( task );
}

}
}
module.exports = BuildProcessor;
57 changes: 30 additions & 27 deletions TestResultSummaryService/JenkinsInfo.js
Original file line number Diff line number Diff line change
@@ -1,50 +1,53 @@
const Promise = require( 'bluebird' );
const jenkinsapi = require( 'jenkins-api' );
const { logger } = require( './Utils' );
const Promise = require('bluebird');
const jenkinsapi = require('jenkins-api');
const { logger } = require('./Utils');

const options = { request: { timeout: 2000 } };

//Server connection may drop. If timeout, retry.
// Server connection may drop. If timeout, retry.
const retry = fn => {
const promise = Promise.promisify( fn );
return async function() {
for ( let i = 0; i < 5; i++ ) {
const promise = Promise.promisify(fn);
return async function () {
for (let i = 0; i < 5; i++) {
try {
return await promise.apply( null, arguments );
} catch ( e ) {
logger.warn( `Try #${i + 1}: connection issue`, arguments );
logger.warn( e );
return await promise.apply(null, arguments);
} catch (e) {
logger.warn(`Try #${i + 1}: connection issue`, arguments);
logger.warn(e);
if (e.toString().includes("unexpected status code: 404")) {
return { code: 404 };
}
}
}
}
}

class JenkinsInfo {
async getAllBuilds( url, buildName ) {
const jenkins = jenkinsapi.init( url, options );
const all_builds = retry( jenkins.all_builds );
const builds = await all_builds( buildName );
async getAllBuilds(url, buildName) {
const jenkins = jenkinsapi.init(url, options);
const all_builds = retry(jenkins.all_builds);
const builds = await all_builds(buildName);
return builds;
}

async getBuildOutput( url, buildName, buildNum ) {
const jenkins = jenkinsapi.init( url, options );
const console_output = retry( jenkins.console_output );
const { body } = await console_output( buildName, buildNum );
async getBuildOutput(url, buildName, buildNum) {
const jenkins = jenkinsapi.init(url, options);
const console_output = retry(jenkins.console_output);
const { body } = await console_output(buildName, buildNum);
return body;
}

async getBuildInfo( url, buildName, buildNum ) {
const jenkins = jenkinsapi.init( url, options );
const build_info = retry( jenkins.build_info );
const body = await build_info( buildName, buildNum );
async getBuildInfo(url, buildName, buildNum) {
const jenkins = jenkinsapi.init(url, options);
const build_info = retry(jenkins.build_info);
const body = await build_info(buildName, buildNum);
return body;
}

async getLastBuildInfo( url, buildName ) {
const jenkins = jenkinsapi.init( url, options );
const last_build_info = retry( jenkins.last_build_info );
const body = await last_build_info( buildName );
async getLastBuildInfo(url, buildName) {
const jenkins = jenkinsapi.init(url, options);
const last_build_info = retry(jenkins.last_build_info);
const body = await last_build_info(buildName);
return body;
}
}
Expand Down

0 comments on commit 8c3aad4

Please sign in to comment.