Skip to content

Commit

Permalink
Fix master build and bump beta version (#137)
Browse files Browse the repository at this point in the history
* use property matchers for getOpts spec

* v2.0.0-beta.2

* Reduce pipeline concurrency for integration tests

* update changelog

* update yarn.locks for examples

* clean yarn cache upon cleaning repo

* bump root dev deps

* correct docs

* utilize implicit returns when possible

* capatilize constants

* moved streaming bootstrapping into bootstrap
  • Loading branch information
erikengervall authored Feb 13, 2020
1 parent 0a8e2c9 commit 7da1dda
Show file tree
Hide file tree
Showing 36 changed files with 306 additions and 294 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/nodejs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ jobs:
with:
node-version: ${{ matrix.node-version }}
- run: yarn prep
- run: yarn test:unit --concurrency 10
- run: yarn test:unit

####### Integration tests
integration_tests:
Expand All @@ -72,7 +72,7 @@ jobs:
with:
node-version: ${{ matrix.node-version }}
- run: yarn prep
- run: yarn test:examples --concurrency 10
- run: yarn test:examples --concurrency 2

####### Publish to npm
npm_publish:
Expand Down
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [2.0.0-beta.2] - 2019-02-12

### Changed

- Adopted RxJS to listen in on docker events, greatly improving the responsiveness and sturdiness of all checks [#136](https://github.com/erikengervall/dockest/pull/136)
- Support function as a command with containerId as argument [#133](https://github.com/erikengervall/dockest/pull/133)

## [2.0.0-beta.1] - 2019-02-01

### Added
Expand Down
3 changes: 1 addition & 2 deletions docs/api_reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -223,8 +223,7 @@ services:

Default: `() => Promise.resolve()`

The Dockest Service's healthcheck function is there to determine the service's health (or responsiveness) by e.g.,
E.g. responsiveness checking a database using `select 1`. The healthcheck function receive the corresponding Compose service configuration from the Compose file as first argument and the containerId as the second.
The Dockest Service's healthcheck function helps determining a service's health (or "responsiveness") by, for example, querying a database using `select 1`. The healthcheck function receive the corresponding Compose service configuration from the Compose file as first argument and the containerId as the second.

The healthcheck takes a single argument in form of an object.

Expand Down
2 changes: 1 addition & 1 deletion lerna.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": "2.0.0-beta.1",
"version": "2.0.0-beta.2",
"npmClient": "yarn",
"packages": [
"packages/dockest",
Expand Down
20 changes: 10 additions & 10 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"url": "https://github.com/erikengervall/dockest.git"
},
"scripts": {
"clean": "lerna run clean --stream && lerna clean --yes && rimraf ./node_modules && yarn && yarn prep",
"clean": "lerna run clean --stream && lerna clean --yes && rimraf ./node_modules && yarn cache clean && yarn && yarn prep",
"dev:link": "lerna run dev:dockest:link --stream && lerna run dev:examples:link --stream",
"dev:link:list": "ls -la ~/.config/yarn/link/@examples",
"dev:unlink": "lerna run dev:examples:unlink --stream && lerna run dev:dockest:unlink --stream",
Expand All @@ -35,21 +35,21 @@
"bump": "yarn lerna version --no-push"
},
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^2.17.0",
"@typescript-eslint/parser": "^2.17.0",
"@typescript-eslint/typescript-estree": "^2.17.0",
"concurrently": "^5.0.2",
"@typescript-eslint/eslint-plugin": "^2.19.2",
"@typescript-eslint/parser": "^2.19.2",
"@typescript-eslint/typescript-estree": "^2.19.2",
"concurrently": "^5.1.0",
"eslint": "^6.8.0",
"eslint-config-prettier": "^6.9.0",
"eslint-plugin-import": "^2.20.0",
"eslint-config-prettier": "^6.10.0",
"eslint-plugin-import": "^2.20.1",
"eslint-plugin-no-only-tests": "^2.4.0",
"eslint-plugin-prettier": "^3.1.2",
"husky": "^4.2.1",
"husky": "^4.2.2",
"lerna": "^3.20.2",
"lint-staged": ">=10.0.2",
"lint-staged": ">=10.0.7",
"prettier": "^1.19.1",
"prettier-eslint": "^9.0.1",
"rimraf": "^3.0.0"
"rimraf": "^3.0.2"
},
"husky": {
"hooks": {
Expand Down
2 changes: 1 addition & 1 deletion packages/dockest/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "dockest",
"version": "2.0.0-beta.1",
"version": "2.0.0-beta.2",
"main": "dist/index.js",
"module": "dist/index.js",
"files": [
Expand Down
10 changes: 5 additions & 5 deletions packages/dockest/src/@types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Logger } from './Logger'
import { DockerServiceEventStream } from './run/createDockerServiceEventStream'
import { DockerEventEmitter } from './run/createDockerEventEmitter'
import { DockerServiceEventStream } from './run/bootstrap/createDockerServiceEventStream'
import { DockerEventEmitter } from './run/bootstrap/createDockerEventEmitter'

type ContainerId = string
type DefaultHealthcheck = () => Promise<void>
Expand All @@ -17,14 +17,14 @@ export interface Healthcheck {
containerId,
defaultHealthchecks,
dockerComposeFileService,
logger,
dockerEventStream$,
logger,
}: {
containerId: ContainerId
defaultHealthchecks: DefaultHealthchecks
dockerComposeFileService: DockerComposeFileService
logger: Runner['logger']
dockerEventStream$: DockerServiceEventStream
logger: Runner['logger']
}): Promise<any>
}

Expand All @@ -33,12 +33,12 @@ export interface Runner {
containerId: ContainerId
dependents: Runner[]
dockerComposeFileService: DockerComposeFileService
dockerEventStream$: DockerServiceEventStream
healthcheck: Healthcheck
logger: Logger
serviceName: ServiceName
host?: string
isBridgeNetworkMode?: boolean
dockerEventStream$: DockerServiceEventStream
}

export interface RunnersObj {
Expand Down
2 changes: 1 addition & 1 deletion packages/dockest/src/Errors.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Runner, DockestConfig } from './@types'
import { DockerEventType } from './run/createDockerEventEmitter'
import { DockerEventType } from './run/bootstrap/createDockerEventEmitter'

export interface Payload {
runner?: Runner
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,11 @@ export interface DockerEventEmitter {
}

export const createDockerEventEmitter = (composeFilePath: string): DockerEventEmitter => {
const command = ` \
docker-compose \
-f ${composeFilePath} \
events \
--json
`
const command = `docker-compose \
--file ${composeFilePath} \
events \
--json`

const childProcess = execa(command, { shell: true, reject: false })

if (!childProcess.stdout) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { fromEventPattern, Observable } from 'rxjs'
import { shareReplay } from 'rxjs/operators'
import { DockerEventEmitter, DockerEventType } from './createDockerEventEmitter'

export type DockerServiceEventStream = Observable<DockerEventType>

export const createDockerServiceEventStream = (
serviceName: string,
eventEmitter: DockerEventEmitter,
): DockerServiceEventStream =>
fromEventPattern<DockerEventType>(
handler => {
eventEmitter.addListener(serviceName, handler)
},
handler => {
eventEmitter.removeListener(serviceName, handler)
},
)
// Every new subscriber should receive access to all previous emitted events, because of this we use shareReplay.
.pipe(shareReplay())
3 changes: 1 addition & 2 deletions packages/dockest/src/run/bootstrap/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import { mergeComposeFiles } from './mergeComposeFiles'
import { setupExitHandler } from './setupExitHandler'
import { transformDockestServicesToRunners } from './transformDockestServicesToRunners'
import { writeComposeFile } from './writeComposeFile'
import { createDockerEventEmitter } from './createDockerEventEmitter'
import { DockestConfig, DockestService } from '../../@types'
import { createDockerEventEmitter } from '../createDockerEventEmitter'

export const bootstrap = async ({
composeFile,
Expand All @@ -29,7 +29,6 @@ export const bootstrap = async ({
const { mergedComposeFiles } = await mergeComposeFiles({ composeFile })
const { dockerComposeFile } = getParsedComposeFile(mergedComposeFiles)
const composeFilePath = writeComposeFile(mergedComposeFiles, dockerComposeFile)

const dockerEventEmitter = createDockerEventEmitter(composeFilePath)

mutables.runners = transformDockestServicesToRunners({
Expand Down
9 changes: 5 additions & 4 deletions packages/dockest/src/run/bootstrap/setupExitHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export interface ErrorPayload {
signal?: any
}

const logPrefix = '[Exit Handler]'
const LOG_PREFIX = '[Exit Handler]'

export const setupExitHandler = async ({
dumpErrors,
Expand All @@ -41,6 +41,7 @@ export const setupExitHandler = async ({
if (mutables.jestRanWithResult) {
return
}

if (errorPayload.reason instanceof BaseError) {
const {
payload: { error, runner, ...restPayload },
Expand All @@ -66,9 +67,9 @@ export const setupExitHandler = async ({
Object.keys(restPayload).length > 0 &&
(logPayload.data.restPayload = restPayload)

Logger.error(`${logPrefix} ${message}`, logPayload)
Logger.error(`${LOG_PREFIX} ${message}`, logPayload)
} else {
Logger.error(`${logPrefix} ${JSON.stringify(errorPayload, null, 2)}`)
Logger.error(`${LOG_PREFIX} ${JSON.stringify(errorPayload, null, 2)}`)
}

if (customExitHandler && typeof customExitHandler === 'function') {
Expand All @@ -93,7 +94,7 @@ export const setupExitHandler = async ({
}
}

Logger.measurePerformance(perfStart, { logPrefix })
Logger.measurePerformance(perfStart, { logPrefix: LOG_PREFIX })
process.exit(errorPayload.code || 1)
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { DockerEventEmitter } from './createDockerEventEmitter'
import { createDockerServiceEventStream } from './createDockerServiceEventStream'
import { ConfigurationError } from '../../Errors'
import { DockestConfig, DockerComposeFile, Runner, RunnersObj, DockestService } from '../../@types'
import { Logger } from '../../Logger'
import { DockerEventEmitter } from '../createDockerEventEmitter'
import { createDockerServiceEventStream } from '../createDockerServiceEventStream'

export const transformDockestServicesToRunners = ({
dockerComposeFile,
Expand Down
23 changes: 0 additions & 23 deletions packages/dockest/src/run/createDockerServiceEventStream.ts

This file was deleted.

46 changes: 11 additions & 35 deletions packages/dockest/src/run/waitForServices/checkConnection.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,76 +9,52 @@ jest.mock('rxjs/operators', () => {
return operators
})

it('fails when the die event is emitted', async done => {
const acquireConnection: AcquireConnectionFunctionType = () => Promise.resolve()
const checkConnection = createCheckConnection({ acquireConnection })
const acquireConnection: AcquireConnectionFunctionType = () => Promise.resolve()
const checkConnection = createCheckConnection({ acquireConnection })

it('fails when the die event is emitted', async done => {
const dockerEventStream$ = new ReplaySubject()

dockerEventStream$.next({ action: 'die' })

const runner = createRunner({ dockerEventStream$ } as any)

checkConnection({
runner,
})
.then(() => {
done.fail('Should have thrown an error.')
})
checkConnection({ runner })
.then(() => done.fail('Should have thrown an error.'))
.catch(err => {
expect(err.message).toEqual('Container unexpectedly died.')
done()
})
})

it('fails when the kill event is emitted', async done => {
const acquireConnection: AcquireConnectionFunctionType = () => Promise.resolve()
const checkConnection = createCheckConnection({ acquireConnection })

const dockerEventStream$ = new ReplaySubject()

dockerEventStream$.next({ action: 'kill' })

const runner = createRunner({ dockerEventStream$ } as any)

checkConnection({
runner,
})
.then(() => {
done.fail('Should have thrown an error.')
})
checkConnection({ runner })
.then(() => done.fail('Should have thrown an error.'))
.catch(err => {
expect(err.message).toEqual('Container unexpectedly died.')
done()
})
})

it('succeeds with zero port checks', async () => {
const acquireConnection: AcquireConnectionFunctionType = () => Promise.resolve()
const checkConnection = createCheckConnection({ acquireConnection })

const dockerEventStream$ = new ReplaySubject() as any

const runner = createRunner({
dockerEventStream$,
dockerComposeFileService: { image: 'node:10-alpine', ports: [] },
})

const result = await checkConnection({
runner,
})
const result = await checkConnection({ runner })

expect(result).toEqual(undefined)
})

it('succeeds when the port check is successfull', async () => {
const acquireConnection: AcquireConnectionFunctionType = () => Promise.resolve()
const checkConnection = createCheckConnection({ acquireConnection })

const runner = createRunner({})

const result = await checkConnection({
runner,
})
const result = await checkConnection({ runner })

expect(result).toEqual(undefined)
})

Expand Down
Loading

0 comments on commit 7da1dda

Please sign in to comment.