Skip to content

Commit

Permalink
Verify pr is created
Browse files Browse the repository at this point in the history
  • Loading branch information
Philip Harrison committed Jul 27, 2021
1 parent e60f3c5 commit 68564dd
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 47 deletions.
3 changes: 0 additions & 3 deletions .github/workflows/integration-test.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
name: 'build-test'
on: pull_request

jobs:
Expand All @@ -16,6 +15,4 @@ jobs:
- run: |
npm ci
- name: Run integration test files
env:
DEPENDABOT_API_URL: 'http://host.docker.internal:9000'
run: npm test "integration"
20 changes: 20 additions & 0 deletions __tests__/helpers.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import Docker from 'dockerode'
import {UPDATER_IMAGE_NAME} from '../src/main'
import waitPort from 'wait-port'
import path from 'path'
import {spawn} from 'child_process'

export const removeDanglingUpdaterContainers = async (): Promise<void> => {
const docker = new Docker()
Expand All @@ -15,3 +18,20 @@ export const removeDanglingUpdaterContainers = async (): Promise<void> => {
}
}
}

export const runFakeDependabotApi = async (port: number): Promise<Function> => {
const server = spawn(`${path.join(__dirname, 'server/server.js')}`, [
`${port}`
])
server.stdout.on('data', (data: any) => {
console.log(`json-server log: ${data}`) // eslint-disable-line no-console
})
server.stderr.on('data', (data: any) => {
console.error(`json-server error: ${data}`) // eslint-disable-line no-console
})
await waitPort({port})

return (): void => {
server.kill()
}
}
44 changes: 28 additions & 16 deletions __tests__/server/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const db = JSON.parse(fs.readFileSync(path.join(__dirname, 'db.json')))
const router = jsonServer.router(db)
const middlewares = jsonServer.defaults()

const SERVER_PORT = 9000
const SERVER_PORT = process.argv.slice(2)[0] || 9000

// NOTE: Serialise the response like dependabot-api
router.render = (_, res) => {
Expand All @@ -24,6 +24,9 @@ router.render = (_, res) => {
})
}

server.use(middlewares)

// Inject a legit GITHUB_TOKEN to increase rate limits fetching manifests from github
server.get('/update_jobs/:id/credentials', (_, res) => {
res.jsonp({
data: {
Expand All @@ -39,32 +42,41 @@ server.get('/update_jobs/:id/credentials', (_, res) => {
})
})

server.post(
'/update_jobs/:id/create_pull_request',
jsonServer.bodyParser,
(req, res) => {
const data = {...req.body.data, id: req.params.id}
db.pull_requests.push(data)
router.db.write()

res.jsonp({})
}
)

// TEMP HACK: Always return 204 on post so the updater doesn't buil out
server.use(jsonServer.bodyParser, (req, res, next) => {
if (req.method === 'POST' && req.body.data) {
req.body = req.body.data
res.sendStatus(204)
return
}
next()
})

// NOTE: These map to resources in db.json
server.use(
jsonServer.rewriter({
'/update_jobs/:id/details': '/update_jobs/:id',
'/update_jobs/:id/credentials': '/credentials/:id',
'/update_jobs/:id/create_pull_request': '/pull_requests',
'/update_jobs/:id/update_pull_request': '/pull_requests',
'/update_jobs/:id/close_pull_request': '/pull_requests',
'/update_jobs/:id/record_update_job_error': '/update_job_errors/:id',
'/update_jobs/:id/mark_as_processed': '/update_jobs/:id',
'/update_jobs/:id/update_dependency_list': '/dependencies/:id',
'/update_jobs/:id/record_package_manager_version': '/update_jobs/:id'
})
)

server.use(jsonServer.bodyParser)
// TEMP HACK: Always return 204 on post so the updater doesn't buil out
server.use((req, res, next) => {
if (req.method === 'POST' && req.body.data) {
req.body = req.body.data
res.sendStatus(204)
}
next()
})

server.use(middlewares)
server.use(router)
server.listen(SERVER_PORT, () => {
console.log(`JSON Server is running on http://localhost:${SERVER_PORT}`)
console.log(`json-server is running on http://localhost:${SERVER_PORT}`)
})
58 changes: 30 additions & 28 deletions __tests__/updater-integration.test.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
import path from 'path'
import axios from 'axios'
import waitPort from 'wait-port'
import {spawn} from 'child_process'

import {Updater} from '../src/updater'
import {UPDATER_IMAGE_NAME} from '../src/main'
import {APIClient, JobParameters} from '../src/api-client'
import {ImageService} from '../src/image-service'
import {UPDATER_IMAGE_NAME} from '../src/main'
import {Updater} from '../src/updater'

import {removeDanglingUpdaterContainers, runFakeDependabotApi} from './helpers'

import {removeDanglingUpdaterContainers} from './helpers'
const FAKE_SERVER_PORT = 9000

describe('Updater', () => {
Expand All @@ -23,57 +21,61 @@ describe('Updater', () => {
// }

// This runs the tests against a fake dependabot-api server using json-server
const fakeDependabotApiUrl = `http://host.docker.internal:${FAKE_SERVER_PORT}`
const dependabotApiUrl =
const fakeDependabotApiUrl = `http://localhost:${FAKE_SERVER_PORT}`
// Used from this action to get job details and credentials
const externalDependabotApiUrl =
process.env.DEPENDABOT_API_URL || fakeDependabotApiUrl
// Used from within the updater container to update the job state and create prs
const internalDockerHost =
process.platform === 'darwin' ? 'host.docker.internal' : 'localhost'
const internalDependabotApiUrl =
process.env.DEPENDABOT_API_URL ||
`http://${internalDockerHost}:${FAKE_SERVER_PORT}`
const params = new JobParameters(
1,
process.env.JOB_TOKEN || 'job-token',
process.env.CREDENTIALS_TOKEN || 'cred-token',
process.env.DEPENDABOT_API_URL ||
`http://host.docker.internal:${FAKE_SERVER_PORT}`
internalDependabotApiUrl
)

const client = axios.create({baseURL: params.dependabotAPIURL})
const client = axios.create({baseURL: externalDependabotApiUrl})
const apiClient = new APIClient(client, params)
const updater = new Updater(UPDATER_IMAGE_NAME, apiClient)

beforeAll(async () => {
// Skip the test when we haven't preloaded the updater image
if (process.env.SKIP_INTEGRATION_TESTS) {
// Skip this test on CI, as it takes too long to download the image
return
}

await ImageService.pull(UPDATER_IMAGE_NAME)

if (dependabotApiUrl === fakeDependabotApiUrl) {
server = spawn(`${path.join(__dirname, 'server/server.js')}`)
server.stdout.on('data', (data: any) => {
console.log(`json-server log: ${data}`) // eslint-disable-line no-console
})
server.stderr.on('data', (data: any) => {
console.error(`json-server error: ${data}`) // eslint-disable-line no-console
})
await waitPort({port: FAKE_SERVER_PORT})
if (externalDependabotApiUrl === fakeDependabotApiUrl) {
server = await runFakeDependabotApi(FAKE_SERVER_PORT)
}
})

afterEach(async () => {
server && server.kill()
server && server() // teardown server process
await removeDanglingUpdaterContainers()
})

jest.setTimeout(30000)
it('should fetch manifests', async () => {
jest.setTimeout(25000)
it('should run the updater and create a pull request', async () => {
// Skip the test when we haven't preloaded the updater image
if (process.env.SKIP_INTEGRATION_TESTS) {
// Skip this test on CI, as it takes too long to download the image
return
}

await updater.runUpdater()

// TODO: Check if the pr was persisted in json-server
// const res = await client.get('/pull_requests/1')
// expect(res.status).toEqual(200)
// NOTE: This will not work when running against the actual dependabot-api
// Checks if the pr was persisted in the fake json-server
const res = await client.get('/pull_requests/1')

expect(res.status).toEqual(200)
expect(res.data.data.attributes['pr-title']).toEqual(
'Bump fetch-factory from 0.0.1 to 0.2.1'
)
})
})
1 change: 1 addition & 0 deletions src/updater.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ export class Updater {
],
Cmd: ['bin/run', updaterCommand],
HostConfig: {
NetworkMode: 'host',
Binds: [
`${path.join(__dirname, '../output')}:${JOB_OUTPUT_PATH}:rw`,
`${path.join(__dirname, '../repo')}:${REPO_CONTENTS_PATH}:rw`
Expand Down

0 comments on commit 68564dd

Please sign in to comment.