Skip to content
This repository has been archived by the owner on Jan 4, 2023. It is now read-only.

Commit

Permalink
[FIX-JENKINS-39229_Regression_Initial_stage_run_does_not_show_graph] …
Browse files Browse the repository at this point in the history
…add … (#79)

* [JENKINS-39229_Regression_Initial_stage_run_does_not_show_graph] add test to cover edge case first run with no stage and then coming stage.

* [JENKINS-39229_Regression_Initial_stage_run_does_not_show_graph] Fix description and shorten pipeline script.
  • Loading branch information
scherler committed Dec 1, 2016
1 parent 4599be9 commit 28064f2
Show file tree
Hide file tree
Showing 5 changed files with 171 additions and 0 deletions.
79 changes: 79 additions & 0 deletions src/main/js/api/sse.js
@@ -1,7 +1,10 @@
var sseClient = require('@jenkins-cd/sse-gateway/headless-client');
var jobChannel = undefined;
var pipelineChannel = undefined;
var jobEventListeners = [];
var pipelineEventListeners = [];
var jobEventHistory = [];
var pipelineEventHistory = [];
var sseConnection;

/**
Expand Down Expand Up @@ -36,6 +39,18 @@ exports.connect = function(browser, done) {
done();
}
});
// Subscribe to job channel so we have it ready to listen
// before any tests start running.
pipelineChannel = sseConnection.subscribe({
channelName: 'pipeline',
onEvent: function (event) {
callPipelineEventListeners(event);
},
onSubscribed: function () {
console.log('Subscribed to the "pipeline" event channel.');
done();
}
});
}
});
}
Expand All @@ -55,7 +70,9 @@ exports.disconnect = function(onDisconnected) {
}
sseConnection = undefined;
jobEventListeners = [];
pipelineEventListeners = [];
jobEventHistory = [];
pipelineEventHistory = [];
console.log('Disconnected from the Jenkins SSE Gateway.');
if (onDisconnected) {
onDisconnected();
Expand All @@ -67,6 +84,11 @@ exports.disconnect = function(onDisconnected) {
jobChannel = undefined;
clientDisconnect();
});
} else if (pipelineChannel) {
sseConnection.unsubscribe(pipelineChannel, function() {
pipelineChannel = undefined;
clientDisconnect();
});
} else {
clientDisconnect();
}
Expand Down Expand Up @@ -99,6 +121,39 @@ exports.onJobEvent = function(filter, callback, checkEventHistory) {
jobEventListeners.push(listener);
};

exports.onPipelineEvent = function(filter, callback, checkEventHistory) {
if(typeof checkEventHistory === 'boolean' ? checkEventHistory : true) {
var sendHistoricalEvent = function(event) {
setTimeout(function() {
callback(event);
}, 1);
};
for (var i = 0; i < pipelineEventHistory.length; i++) {
if (isMatchingEvent(pipelineEventHistory[i], filter)) {
// If we find a matching event in the event history then we
// create a timeout to send the event to the callback and then
// bail immediately, without adding the listener to the list
// of pipeline listeners.
sendHistoricalEvent(pipelineEventHistory[i]);
return;
}
}
}

var listener = {
filter: filter,
callback: callback
};

pipelineEventListeners.push(listener);
};
exports.onPipelineStage = function (pipelineName, callback) {
exports.onPipelineEvent({
jenkins_event: 'pipeline_stage',
pipeline_job_name: pipelineName
}, callback);
};

exports.onJobCreated = function(jobName, callback) {
exports.onJobEvent({
jenkins_event: 'job_crud_created',
Expand Down Expand Up @@ -145,6 +200,30 @@ function callJobEventListeners(event) {
}
}

function callPipelineEventListeners(event) {
try {
var newListenerList = [];
for (var i = 0; i < pipelineEventListeners.length; i++) {
var pipelineEventListener = pipelineEventListeners[i];

if (isMatchingEvent(event, pipelineEventListener.filter)) {
try {
pipelineEventListener.callback(event);
} catch(e) {
console.error(e);
}
} else {
// Only add the handlers that were not called.
newListenerList.push(pipelineEventListener);
}
}
pipelineEventListeners = newListenerList;
} finally {
pipelineEventHistory.push(event);
}

}

// Check the event against the event filter.
function isMatchingEvent(event, eventFilter) {
for (var prop in eventFilter) {
Expand Down
37 changes: 37 additions & 0 deletions src/main/js/custom_commands/waitForPipelineStageEvent.js
@@ -0,0 +1,37 @@
/** @module waitForJobRunEnded
* @memberof custom_commands
* */
const util = require('util');
const events = require('events');
var sseClient = require('../api/sse');

function Cmd() {
events.EventEmitter.call(this);
}
util.inherits(Cmd, events.EventEmitter);

/**
* @description Nightwatch command to wait for a stage event to be published.
* @param {String} pipelineName - the name of the job we are waiting on
* @param {Function} [onPipelineStageEvent] - callback to be invoke when finished, will pass the sse event to the callback
* */
const waitForPipelineStageEvent = function (pipelineName, onPipelineStageEvent) {
var self = this;

console.log('Waiting for pipeline "' + pipelineName + '" stage event.');
sseClient.onPipelineStage(pipelineName, function(event) {
console.log('Pipeline "' + pipelineName + '" stage event arrived.');
try {
if (onPipelineStageEvent) {
onPipelineStageEvent(event);
}
} finally {
self.emit('complete');
}
});

return this;
};
Cmd.prototype.command = waitForPipelineStageEvent;

module.exports = Cmd;
1 change: 1 addition & 0 deletions src/test/js/edgeCases/index.js
Expand Up @@ -3,6 +3,7 @@
* @description We are testing different REGRESSIONS that had appeared, so they do not appear again.
*
* @see {@link module:edgeCases.folder}
* @see {@link module:edgeCases.initialStage}
*/
module.exports = {

Expand Down
45 changes: 45 additions & 0 deletions src/test/js/edgeCases/initialStage.js
@@ -0,0 +1,45 @@
/** @module initialStage
* @memberof edgeCases
* @description
*
* Tests: test whether the stageGraph is rendered in the first run when the first step is not a stage
* but afterward we will create stages
*
* REGRESSION covered:
*
* @see {@link https://issues.jenkins-ci.org/browse/JENKINS-39229|JENKINS-39229} Initial stage run does not show graph
*
*
*/
const jobName = 'initialStage';
module.exports = {
/** Create Pipeline Job "initialStage" */
'Step 01': function (browser) {
const pipelinesCreate = browser.page.pipelineCreate().navigate();
pipelinesCreate.createPipeline(jobName, 'initialStage.groovy');
},
/** Build Pipeline Job*/
'Step 02': function (browser) {
const pipelinePage = browser.page.jobUtils().forJob(jobName);
pipelinePage.buildStarted(function () {
// Reload the job page and check that there was a build done.
pipelinePage
.waitForElementVisible('div#pipeline-box')
.forRun(1)
.waitForElementVisible('@executer');
});
},
/** Check Job Blue Ocean Pipeline Activity Page has run */
'Step 03': function (browser) {
const blueActivityPage = browser.page.bluePipelineActivity().forJob(jobName, 'jenkins');
// Check the run itself
blueActivityPage.waitForRunRunningVisible('initialStage-1');
const blueRunDetailPage = browser.page.bluePipelineRunDetail().forRun(jobName, 'jenkins', 1);

blueRunDetailPage.assertBasicLayoutOkay();
blueRunDetailPage.waitForPipelineStageEvent('initialStage', function () {
blueRunDetailPage.validateGraph(); // test whether we have a pipeline graph
blueRunDetailPage.waitForJobRunEnded(jobName);
});
},
}
9 changes: 9 additions & 0 deletions src/test/resources/test_scripts/initialStage.groovy
@@ -0,0 +1,9 @@
node {
sh 'ping -c 5 www.spiegel.de'
stage ('Build1') {
sh 'ping -c 5 www.spiegel.de'
}
stage ('Build2') {
sh 'ping -c 5 www.spiegel.de'
}
}

0 comments on commit 28064f2

Please sign in to comment.