From 68564ddd5309f540587ab31dd0f5446b67bbcb13 Mon Sep 17 00:00:00 2001 From: Philip Harrison Date: Tue, 27 Jul 2021 15:47:01 +0100 Subject: [PATCH] Verify pr is created --- .github/workflows/integration-test.yml | 3 -- __tests__/helpers.ts | 20 +++++++++ __tests__/server/server.js | 44 ++++++++++++------- __tests__/updater-integration.test.ts | 58 +++++++++++++------------- src/updater.ts | 1 + 5 files changed, 79 insertions(+), 47 deletions(-) diff --git a/.github/workflows/integration-test.yml b/.github/workflows/integration-test.yml index 415f527..b63f604 100644 --- a/.github/workflows/integration-test.yml +++ b/.github/workflows/integration-test.yml @@ -1,4 +1,3 @@ -name: 'build-test' on: pull_request jobs: @@ -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" diff --git a/__tests__/helpers.ts b/__tests__/helpers.ts index 5ba9ac8..bc9ded0 100644 --- a/__tests__/helpers.ts +++ b/__tests__/helpers.ts @@ -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 => { const docker = new Docker() @@ -15,3 +18,20 @@ export const removeDanglingUpdaterContainers = async (): Promise => { } } } + +export const runFakeDependabotApi = async (port: number): Promise => { + 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() + } +} diff --git a/__tests__/server/server.js b/__tests__/server/server.js index 46df77e..8027ef1 100755 --- a/__tests__/server/server.js +++ b/__tests__/server/server.js @@ -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) => { @@ -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: { @@ -39,13 +42,33 @@ 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', @@ -53,18 +76,7 @@ server.use( }) ) -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}`) }) diff --git a/__tests__/updater-integration.test.ts b/__tests__/updater-integration.test.ts index d5a81ee..3e01d5b 100644 --- a/__tests__/updater-integration.test.ts +++ b/__tests__/updater-integration.test.ts @@ -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', () => { @@ -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' + ) }) }) diff --git a/src/updater.ts b/src/updater.ts index eea17c8..06a8b31 100644 --- a/src/updater.ts +++ b/src/updater.ts @@ -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`