Skip to content

Commit

Permalink
feat: add helper methods that easily allow writing tests for "dockest…
Browse files Browse the repository at this point in the history
… inside docker" and "dockest on docker host" environments.
  • Loading branch information
n1ru4l committed Sep 26, 2019
1 parent 301eb3a commit fdce244
Show file tree
Hide file tree
Showing 9 changed files with 68 additions and 8 deletions.
2 changes: 2 additions & 0 deletions examples/aws-code-build-example/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
dockest.tgz
.artifacts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import http from 'http'
import fetch from 'node-fetch'
import isDocker from 'is-docker'
import { getHostAddress, getServiceAddress } from 'dockest/dist/test-helper'

const TARGET_HOST = isDocker() ? 'website' : 'localhost'
const TARGET_HOST = getServiceAddress('website', 9000)

// hostname is either our docker container hostname or if not run inside a docker container the docker host
const HOSTNAME = isDocker() ? process.env.HOSTNAME : 'host.docker.internal'
const HOSTNAME = getHostAddress()
const PORT = 8080

let server: http.Server
Expand Down Expand Up @@ -38,7 +38,7 @@ test('can send a request to the container and it can send a request to us', asyn
})
})

const res = await fetch(`http://${TARGET_HOST}:9000`, {
const res = await fetch(`http://${TARGET_HOST}`, {
method: 'post',
body: `http://${HOSTNAME}:${PORT}`,
}).then(res => res.text())
Expand Down
6 changes: 4 additions & 2 deletions examples/aws-code-build-example/run_tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@ yarn pack --filename examples/aws-code-build-example/dockest.tgz
cd examples/aws-code-build-example

# build dockest
# yarn install
# yarn test
yarn cache clean
yarn install --no-lockfile
yarn test

# build with dockest inside docker container
rm -rf node_modules
./codebuild_build.sh -i n1ru4l/aws-codebuild-node -a .artifacts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ exports[`createComposeObjFromRunners should create composeObj from all initializ
Object {
"services": Object {
"general": Object {
"extra_hosts": Array [],
"image": "general/image:123",
"ports": Array [],
},
Expand All @@ -19,6 +20,7 @@ Object {
"KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR": 1,
"KAFKA_ZOOKEEPER_CONNECT": "zookeeper:2181",
},
"extra_hosts": Array [],
"image": "kafka/image:123",
"ports": Array [
Object {
Expand All @@ -33,6 +35,7 @@ Object {
"POSTGRES_PASSWORD": "_",
"POSTGRES_USER": "_",
},
"extra_hosts": Array [],
"image": "postgres/image:123",
"ports": Array [
Object {
Expand All @@ -42,6 +45,7 @@ Object {
],
},
"redis": Object {
"extra_hosts": Array [],
"image": "redis/image:123",
"ports": Array [
Object {
Expand All @@ -54,6 +58,7 @@ Object {
"environment": Object {
"ZOOKEEPER_CLIENT_PORT": 2181,
},
"extra_hosts": Array [],
"image": "zookeeper/image:123",
"ports": Array [
Object {
Expand All @@ -76,6 +81,7 @@ Object {
"POSTGRES_PASSWORD": "_",
"POSTGRES_USER": "_",
},
"extra_hosts": Array [],
"image": "postgres/image:123",
"ports": Array [
Object {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import execa from 'execa'
import { ComposeService, DependsOn, ComposeFile } from '../../runners/@types'
import { DockestConfig } from '../../index'

Expand All @@ -18,6 +19,16 @@ export default (config: DockestConfig, dockerComposeFileVersion: string) => {
services: {},
}

const extra_hosts: string[] = []

if (!config.$.isInsideDockerContainer) {
if (process.platform === 'linux') {
const command = `ip -4 addr show docker0 | grep -oP '(?<=inet\s)\d+(\.\d+){3}'`
const result = execa.sync(command, { reject: false })
extra_hosts.push(`host.docker.internal:${result.stdout}`)
}
}

config.runners.forEach(runner => {
const {
runnerConfig: { service, dependsOn },
Expand All @@ -29,7 +40,7 @@ export default (config: DockestConfig, dockerComposeFileVersion: string) => {

composeObj.services = {
...composeObj.services,
[service]: composeService,
[service]: { ...composeService, extra_hosts },
...depComposeServices,
}
})
Expand Down
3 changes: 3 additions & 0 deletions src/onInstantiation/generateComposeFile/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ export default (config: DockestConfig, yaml = yamlLib, fs = fsLib) => {

// write final config to fs
fs.writeFileSync(GENERATED_COMPOSE_FILE_PATH, yaml.safeDump(composeObjFromComposeFile))
// set environment variable that can be used with the test-helpers
// jest.runCLI will pass this environment variable into the testcase runners
process.env.DOCKEST_INTERNAL_CONFIG = JSON.stringify(composeObjFromComposeFile)

return { composeFileConfig: composeObjFromComposeFile }
}
2 changes: 1 addition & 1 deletion src/onRun/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const onRun = async (config: DockestConfig) => {

if (isInsideDockerContainer) {
await createBridgeNetwork()
await joinBridgeNetwork(hostname)
await joinBridgeNetwork(hostname, 'host.dockest-runner.internal')
}

await waitForRunnersReadiness(config)
Expand Down
1 change: 1 addition & 0 deletions src/runners/@types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export interface ComposeService {
target: string
}
| string
extra_hosts?: string[]
}

export interface ComposeFile {
Expand Down
35 changes: 35 additions & 0 deletions src/test-helper/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/* eslint-disable import/default */
import isDocker from 'is-docker'
import { ComposeFile } from '../runners/@types'

const isInsideDockerContainer = isDocker()

if (!process.env.DOCKEST_INTERNAL_CONFIG) {
throw new Error('Not executed inside dockest context.')
}

const config: ComposeFile = JSON.parse(process.env.DOCKEST_INTERNAL_CONFIG)

export const getHostAddress = () => {
if (!isInsideDockerContainer) {
return `host.docker.internal`
}

return `host.dockest-runner.internal`
}

export const getServiceAddress = (serviceName: string, targetPort: number | string) => {
const service = config.services[serviceName]
if (!service) {
throw new Error(`Service "${serviceName}" does not exist.`)
}
const portBinding = service.ports.find(portBinding => portBinding.target === targetPort)
if (!portBinding) {
throw new Error(`Service "${serviceName}" has no target port ${portBinding}.`)
}

if (isInsideDockerContainer) {
return `${serviceName}:${portBinding.target}`
}
return `localhost:${portBinding.published}`
}

0 comments on commit fdce244

Please sign in to comment.