Skip to content

Commit

Permalink
Improve integration tests for pushing Jenkins statuses (#222)
Browse files Browse the repository at this point in the history
* jenkins: refactor push-jenkins tests to prove they actually fail

The previous approach of testing if network requests had been sent from
the bot, via nock scopes, didn't test more then one network request.

That's because we tested all scoped in a one-liner like this;

```js
prCommitsScope.done() && scope.done()
```

It turns out that the above will not invoke the second `scope.done()`,
meaning only the first nock scope (read: outgoing network request) was
asserted. By going away from that one-liner and invoking one by one on
each line, tests starts to explode.

A fix to the bot's source will come in the next commit.

* jenkins: wait until status has been pushed to GitHub before responding

These changes are primarily done so we can get more reliable integration
tests. Previously the incoming requests was responded to, before we
knew whether or not the Jenkins status has been successfully pushed to
GitHub.

That makes it challenging to know when we can assert what we want to
verify in integration tests, as we don't know when the entire operation
has finished. Although the previous approach did what it should in
practise when run in production, it should be just as important to have
reliable tests that we can rely on when doing changes going forward.

* jenkins: move HTTP assertions from .tearDown() alongside response test

As it's way more intuitive to have those outgoing HTTP request
assertions alongside other assertions, than as part of the test tear
down process.
  • Loading branch information
phillipj authored Mar 24, 2019
1 parent a0b8404 commit b5904f9
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 18 deletions.
23 changes: 15 additions & 8 deletions lib/push-jenkins-update.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const url = require('url')

const githubClient = require('./github-client')

function pushStarted (options, build) {
function pushStarted (options, build, cb) {
const pr = findPrInRef(build.ref)

// create unique logger which is easily traceable for every subsequent log statement
Expand All @@ -15,7 +15,9 @@ function pushStarted (options, build) {

findLatestCommitInPr(optsWithPr, (err, latestCommit) => {
if (err) {
return logger.error(err, 'Got error when retrieving GitHub commits for PR')
logger.error(err, 'Got error when retrieving GitHub commits for PR')
cb(err)
return
}

const statusOpts = Object.assign({
Expand All @@ -26,11 +28,11 @@ function pushStarted (options, build) {
message: build.message || 'running tests'
}, options)

createGhStatus(statusOpts, logger)
createGhStatus(statusOpts, logger, cb)
})
}

function pushEnded (options, build) {
function pushEnded (options, build, cb) {
const pr = findPrInRef(build.ref)

// create unique logger which is easily traceable for every subsequent log statement
Expand All @@ -41,7 +43,9 @@ function pushEnded (options, build) {

findLatestCommitInPr(optsWithPr, (err, latestCommit) => {
if (err) {
return logger.error(err, 'Got error when retrieving GitHub commits for PR')
logger.error(err, 'Got error when retrieving GitHub commits for PR')
cb(err)
return
}

const statusOpts = Object.assign({
Expand All @@ -52,7 +56,7 @@ function pushEnded (options, build) {
message: build.message || 'all tests passed'
}, options)

createGhStatus(statusOpts, logger)
createGhStatus(statusOpts, logger, cb)
})
}

Expand Down Expand Up @@ -89,7 +93,7 @@ function findLatestCommitInPr (options, cb, pageNumber = 1) {
})
}

function createGhStatus (options, logger) {
function createGhStatus (options, logger, cb) {
githubClient.repos.createStatus({
owner: options.owner,
repo: options.repo,
Expand All @@ -100,9 +104,12 @@ function createGhStatus (options, logger) {
description: options.message
}, (err, res) => {
if (err) {
return logger.error(err, 'Error while updating Jenkins / GitHub PR status')
logger.error(err, 'Error while updating Jenkins / GitHub PR status')
cb(err)
return
}
logger.info('Jenkins / Github PR status updated')
cb(null)
})
}

Expand Down
14 changes: 8 additions & 6 deletions scripts/jenkins-status.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,10 @@ module.exports = function (app) {
owner: 'nodejs',
repo,
logger: req.log
}, req.body)

res.status(201).end()
}, req.body, (err) => {
const statusCode = err !== null ? 500 : 201
res.status(statusCode).end()
})
})

app.post('/:repo/jenkins/end', (req, res) => {
Expand All @@ -75,8 +76,9 @@ module.exports = function (app) {
owner: 'nodejs',
repo,
logger: req.log
}, req.body)

res.status(201).end()
}, req.body, (err) => {
const statusCode = err !== null ? 500 : 201
res.status(statusCode).end()
})
})
}
12 changes: 8 additions & 4 deletions test/integration/push-jenkins-update.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,14 @@ tap.test('Sends POST requests to https://api.github.com/repos/nodejs/node/status
.reply(201)

t.plan(1)
t.tearDown(() => prCommitsScope.done() && scope.done())

supertest(app)
.post('/node/jenkins/start')
.send(jenkinsPayload)
.expect(201)
.end((err, res) => {
prCommitsScope.done()
scope.done()
t.equal(err, null)
})
})
Expand All @@ -40,13 +41,14 @@ tap.test('Allows repository name to be provided with URL parameter when pushing
.reply(201)

t.plan(1)
t.tearDown(() => prCommitsScope.done() && scope.done())

supertest(app)
.post('/citgm/jenkins/start')
.send(jenkinsPayload)
.expect(201)
.end((err, res) => {
prCommitsScope.done()
scope.done()
t.equal(err, null)
})
})
Expand All @@ -61,13 +63,14 @@ tap.test('Allows repository name to be provided with URL parameter when pushing
.reply(201)

t.plan(1)
t.tearDown(() => prCommitsScope.done() && scope.done())

supertest(app)
.post('/citgm/jenkins/end')
.send(jenkinsPayload)
.expect(201)
.end((err, res) => {
prCommitsScope.done()
scope.done()
t.equal(err, null)
})
})
Expand All @@ -87,13 +90,14 @@ tap.test('Forwards payload provided in incoming POST to GitHub status API', (t)
.reply(201)

t.plan(1)
t.tearDown(() => prCommitsScope.done() && scope.done())

supertest(app)
.post('/node/jenkins/start')
.send(fixture)
.expect(201)
.end((err, res) => {
prCommitsScope.done()
scope.done()
t.equal(err, null)
})
})
Expand Down

0 comments on commit b5904f9

Please sign in to comment.