comq 0.13.0 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/release.yaml +24 -54
- package/.releaserc +35 -0
- package/AGENTS.md +35 -0
- package/CHANGELOG.md +11 -0
- package/features/backpressure.feature +1 -2
- package/features/readme.md +9 -2
- package/features/shards.feature +1 -1
- package/features/steps/backpressure.js +13 -29
- package/features/steps/broker.js +4 -30
- package/features/steps/brokers.js +125 -0
- package/features/steps/context.js +2 -4
- package/features/steps/hooks.js +14 -1
- package/package.json +19 -15
- package/lerna.json +0 -4
|
@@ -1,73 +1,43 @@
|
|
|
1
1
|
name: Release
|
|
2
2
|
|
|
3
3
|
on:
|
|
4
|
-
|
|
5
|
-
types: [closed]
|
|
4
|
+
push:
|
|
6
5
|
branches:
|
|
7
|
-
-
|
|
8
|
-
- alpha
|
|
9
|
-
paths:
|
|
10
|
-
- 'source/**'
|
|
11
|
-
- 'types/**'
|
|
12
|
-
- 'package-lock.json'
|
|
6
|
+
- dev
|
|
13
7
|
|
|
14
|
-
|
|
15
|
-
|
|
8
|
+
permissions:
|
|
9
|
+
contents: write
|
|
10
|
+
issues: write
|
|
11
|
+
pull-requests: write
|
|
12
|
+
id-token: write
|
|
16
13
|
|
|
17
14
|
jobs:
|
|
18
|
-
|
|
19
|
-
if: github.event.pull_request.merged == true
|
|
15
|
+
release:
|
|
20
16
|
runs-on: ubuntu-latest
|
|
17
|
+
env:
|
|
18
|
+
HUSKY: 0
|
|
21
19
|
|
|
22
20
|
steps:
|
|
23
|
-
- name: Setup Node
|
|
24
|
-
uses: actions/setup-node@v6
|
|
25
|
-
with:
|
|
26
|
-
node-version: 20
|
|
27
|
-
registry-url: 'https://registry.npmjs.org'
|
|
28
|
-
|
|
29
21
|
- name: Checkout
|
|
30
22
|
uses: actions/checkout@v6
|
|
31
23
|
with:
|
|
32
24
|
fetch-depth: 0
|
|
25
|
+
persist-credentials: false
|
|
33
26
|
|
|
34
|
-
- name:
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
- name: Import GPG key
|
|
38
|
-
id: gpg
|
|
39
|
-
uses: crazy-max/ghaction-import-gpg@v6
|
|
27
|
+
- name: Setup Node
|
|
28
|
+
uses: actions/setup-node@v6
|
|
40
29
|
with:
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
git_commit_gpgsign: true
|
|
30
|
+
node-version: "24"
|
|
31
|
+
registry-url: https://registry.npmjs.org
|
|
32
|
+
package-manager-cache: false
|
|
45
33
|
|
|
46
|
-
- name:
|
|
47
|
-
run:
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
npx lerna@7.3.0 version --conventional-prerelease --preid alpha --dist-tag alpha --no-commit-hooks --no-changelog --yes --message "ci: %s" --git-tag-command "echo %s" --sign-git-commit
|
|
52
|
-
fi
|
|
53
|
-
|
|
54
|
-
git fetch
|
|
55
|
-
git checkout dev
|
|
56
|
-
git merge ${{ github.base_ref }}
|
|
57
|
-
git push --all origin --no-verify
|
|
58
|
-
env:
|
|
59
|
-
GITHUB_TOKEN: ${{ secrets.TOABOT_GITHUB_TOKEN }}
|
|
60
|
-
GIT_AUTHOR_NAME: ${{ steps.gpg.outputs.name }}
|
|
61
|
-
GIT_AUTHOR_EMAIL: ${{ steps.gpg.outputs.email }}
|
|
62
|
-
GIT_COMMITTER_NAME: ${{ steps.gpg.outputs.name }}
|
|
63
|
-
GIT_COMMITTER_EMAIL: ${{ steps.gpg.outputs.email }}
|
|
34
|
+
- name: Install dependencies
|
|
35
|
+
run: npm ci
|
|
36
|
+
|
|
37
|
+
- name: Run tests
|
|
38
|
+
run: npm test
|
|
64
39
|
|
|
65
|
-
- name:
|
|
40
|
+
- name: Semantic release
|
|
66
41
|
env:
|
|
67
|
-
|
|
68
|
-
run:
|
|
69
|
-
if [ ${{ github.base_ref }} = release ]; then
|
|
70
|
-
npm publish
|
|
71
|
-
else
|
|
72
|
-
npm publish --tag alpha
|
|
73
|
-
fi
|
|
42
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
43
|
+
run: npx semantic-release
|
package/.releaserc
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"branches": [
|
|
3
|
+
"dev"
|
|
4
|
+
],
|
|
5
|
+
"plugins": [
|
|
6
|
+
"@semantic-release/commit-analyzer",
|
|
7
|
+
"@semantic-release/release-notes-generator",
|
|
8
|
+
[
|
|
9
|
+
"@semantic-release/changelog",
|
|
10
|
+
{
|
|
11
|
+
"changelogFile": "CHANGELOG.md"
|
|
12
|
+
}
|
|
13
|
+
],
|
|
14
|
+
[
|
|
15
|
+
"@semantic-release/npm"
|
|
16
|
+
],
|
|
17
|
+
[
|
|
18
|
+
"@semantic-release/git",
|
|
19
|
+
{
|
|
20
|
+
"assets": [
|
|
21
|
+
"package.json",
|
|
22
|
+
"package-lock.json",
|
|
23
|
+
"CHANGELOG.md"
|
|
24
|
+
],
|
|
25
|
+
"message": "chore(release): ${nextRelease.version}\n\n${nextRelease.notes}"
|
|
26
|
+
}
|
|
27
|
+
],
|
|
28
|
+
[
|
|
29
|
+
"@semantic-release/github",
|
|
30
|
+
{
|
|
31
|
+
"owner": "toa-io"
|
|
32
|
+
}
|
|
33
|
+
]
|
|
34
|
+
]
|
|
35
|
+
}
|
package/AGENTS.md
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# AGENTS.md
|
|
2
|
+
|
|
3
|
+
## Cursor Cloud specific instructions
|
|
4
|
+
|
|
5
|
+
### Project Overview
|
|
6
|
+
|
|
7
|
+
ComQ is a Node.js communication library over AMQP (RabbitMQ). It provides RPC, pub/sub, task queues, pipelines, and sharded connections.
|
|
8
|
+
|
|
9
|
+
### Services
|
|
10
|
+
|
|
11
|
+
Feature tests start two RabbitMQ instances automatically via Testcontainers (`features/steps/brokers.js`). Credentials: `developer` / `secret`. AMQP ports are assigned dynamically on the host.
|
|
12
|
+
|
|
13
|
+
### Docker
|
|
14
|
+
|
|
15
|
+
Feature tests require a running Docker daemon. In nested container environments, start Docker with:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
sudo dockerd --exec-opt native.cgroupdriver=cgroupfs &
|
|
19
|
+
sudo chmod 666 /var/run/docker.sock
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Do not use `docker compose up` for feature tests — Testcontainers manages broker lifecycle. `docker compose` may fail here because `deploy.resources.limits.memory` requires cgroupv2 memory limits that are unavailable in nested setups.
|
|
23
|
+
|
|
24
|
+
### Commands
|
|
25
|
+
|
|
26
|
+
- `npm test` — runs `standard` (lint) + `jest` (300 unit tests, no RabbitMQ required)
|
|
27
|
+
- `npm run features` — runs all Cucumber feature tests (starts RabbitMQ via Testcontainers)
|
|
28
|
+
- `npm run lint` — runs `standard --fix --verbose | snazzy`
|
|
29
|
+
|
|
30
|
+
### Testing Notes
|
|
31
|
+
|
|
32
|
+
- Unit tests (`jest`) use mocks and do NOT require running RabbitMQ.
|
|
33
|
+
- Feature tests (`cucumber-js`) start brokers in `BeforeAll` and stop them in `AfterAll`.
|
|
34
|
+
- Recovery/connection tests (in `features/connection.feature`, `features/recovery.feature`, `features/shards.feature`) stop/kill broker containers and take 5-15 minutes to complete.
|
|
35
|
+
- To run only fast feature tests (no broker stop/start): `npx cucumber-js --fail-fast -t 'not @manual' features/events.feature features/rpc.feature features/tasks.feature features/singleton.feature features/properties.feature features/tasks.shards.feature`
|
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# [0.14.0](https://github.com/toa-io/comq/compare/v0.13.0...v0.14.0) (2026-05-24)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Features
|
|
5
|
+
|
|
6
|
+
* **features:** manage RabbitMQ brokers with Testcontainers ([1d9ca59](https://github.com/toa-io/comq/commit/1d9ca591ff458c75caf87ab63224b15942ba7d07))
|
|
7
|
+
* **features:** use Testcontainers for RabbitMQ in Gherkin tests ([#219](https://github.com/toa-io/comq/issues/219)) ([a33e66b](https://github.com/toa-io/comq/commit/a33e66bfc357f0f089c728bc60c08f6f24b2c8d1))
|
|
8
|
+
|
|
9
|
+
# Changelog
|
|
10
|
+
|
|
11
|
+
All notable changes to this project are documented in this file by [semantic-release](https://github.com/semantic-release/semantic-release).
|
package/features/readme.md
CHANGED
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
# Features
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
Feature tests start two RabbitMQ instances automatically via [Testcontainers](https://node.testcontainers.org/modules/rabbitmq/).
|
|
4
|
+
|
|
5
|
+
Run them with:
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm run features
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Docker must be available on the host. No manual `docker compose` setup is required.
|
package/features/shards.feature
CHANGED
|
@@ -41,7 +41,7 @@ Feature: Sharded Connection
|
|
|
41
41
|
Scenario: Shard crashes while publishing events
|
|
42
42
|
Given an active sharded connection
|
|
43
43
|
And events are exclusively consumed from the `flood` exchange
|
|
44
|
-
And I'm publishing 1kB events to the `flood` exchange at
|
|
44
|
+
And I'm publishing 1kB events to the `flood` exchange at 10Hz
|
|
45
45
|
When one of the brokers has crashed
|
|
46
46
|
Then no exceptions are thrown
|
|
47
47
|
And all events have been received
|
|
@@ -4,43 +4,27 @@ const assert = require('node:assert')
|
|
|
4
4
|
const { randomBytes } = require('node:crypto')
|
|
5
5
|
const { quantity, timeout } = require('@toa.io/generic')
|
|
6
6
|
|
|
7
|
-
const { When
|
|
7
|
+
const { When } = require('@cucumber/cucumber')
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
const PAYLOAD = quantity('500k')
|
|
10
|
+
const BATCH = 20
|
|
11
|
+
const DEADLINE = 25_000
|
|
12
|
+
|
|
13
|
+
When('I\'m flooding the {token} queue until back pressure is applied',
|
|
10
14
|
/**
|
|
11
|
-
* @param {string} bytesQ
|
|
12
15
|
* @param {string} queue
|
|
13
|
-
* @param {string} frequencyQ
|
|
14
|
-
* @param {number} seconds
|
|
15
16
|
* @this {comq.features.Context}
|
|
16
17
|
*/
|
|
17
|
-
async function (
|
|
18
|
-
const
|
|
19
|
-
const
|
|
20
|
-
const
|
|
21
|
-
const times = seconds * frequency
|
|
22
|
-
|
|
23
|
-
// intervals less than 1ms are not accurate
|
|
24
|
-
const interval = Math.max((1000 / frequency), 1)
|
|
25
|
-
const each = Math.max(1 / (1000 / frequency), 1)
|
|
26
|
-
|
|
27
|
-
const promises = []
|
|
18
|
+
async function (queue) {
|
|
19
|
+
const buffer = randomBytes(PAYLOAD)
|
|
20
|
+
const deadline = Date.now() + DEADLINE
|
|
21
|
+
const pending = []
|
|
28
22
|
|
|
29
|
-
|
|
30
|
-
|
|
23
|
+
while (!this.events.flow && Date.now() < deadline) {
|
|
24
|
+
for (let i = 0; i < BATCH; i++) { pending.push(this.io.request(queue, buffer).catch(() => {})) }
|
|
31
25
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
if ((i + 1) % each === 0) await timeout(interval)
|
|
26
|
+
await timeout(0)
|
|
35
27
|
}
|
|
36
28
|
|
|
37
|
-
await Promise.all(promises)
|
|
38
|
-
})
|
|
39
|
-
|
|
40
|
-
Then('back pressure was applied',
|
|
41
|
-
/**
|
|
42
|
-
* @this {comq.features.Context}
|
|
43
|
-
*/
|
|
44
|
-
function () {
|
|
45
29
|
assert.equal(this.events.flow, true, 'Back pressure hasn\'t been applied')
|
|
46
30
|
})
|
package/features/steps/broker.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const {
|
|
4
|
-
const { execute } = require('@toa.io/command')
|
|
3
|
+
const { random } = require('@toa.io/generic')
|
|
5
4
|
|
|
6
5
|
const { Given } = require('@cucumber/cucumber')
|
|
6
|
+
const { BROKERS_AMOUNT, actions } = require('./brokers')
|
|
7
7
|
|
|
8
8
|
Given('the broker is/has {status}',
|
|
9
9
|
/**
|
|
10
|
-
* @param {'up' | 'down'} status
|
|
10
|
+
* @param {'up' | 'down' | 'crashed'} status
|
|
11
11
|
* @this {comq.features.Context}
|
|
12
12
|
*/
|
|
13
13
|
async function (status) {
|
|
@@ -18,7 +18,7 @@ Given('the broker is/has {status}',
|
|
|
18
18
|
|
|
19
19
|
Given('one of the brokers is/has {status}',
|
|
20
20
|
/**
|
|
21
|
-
* @param {'up' | 'down'} status
|
|
21
|
+
* @param {'up' | 'down' | 'crashed'} status
|
|
22
22
|
* @this {comq.features.Context}
|
|
23
23
|
*/
|
|
24
24
|
async function (status) {
|
|
@@ -28,29 +28,3 @@ Given('one of the brokers is/has {status}',
|
|
|
28
28
|
|
|
29
29
|
await actions[status](shard)
|
|
30
30
|
})
|
|
31
|
-
|
|
32
|
-
const actions = {
|
|
33
|
-
up: async (n = 0) => {
|
|
34
|
-
await execute('docker start comq-rmq-' + n)
|
|
35
|
-
await healthy(n)
|
|
36
|
-
},
|
|
37
|
-
down: async (n = 0) => {
|
|
38
|
-
await execute('docker stop comq-rmq-' + n)
|
|
39
|
-
},
|
|
40
|
-
crashed: async (n = 0) => {
|
|
41
|
-
await execute('docker kill comq-rmq-' + n)
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
async function healthy (n) {
|
|
46
|
-
let process
|
|
47
|
-
|
|
48
|
-
do {
|
|
49
|
-
await timeout(HEALTHCHECK_INTERVAL)
|
|
50
|
-
|
|
51
|
-
process = await execute('docker inspect -f {{.State.Health.Status}} comq-rmq-' + n)
|
|
52
|
-
} while (process.output !== 'healthy')
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
const BROKERS_AMOUNT = 2
|
|
56
|
-
const HEALTHCHECK_INTERVAL = global.COMQ_TESTING_HEALTHCHECK_INTERVAL ?? 1000
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { execFile } = require('node:child_process')
|
|
4
|
+
const { promisify } = require('node:util')
|
|
5
|
+
const { timeout } = require('@toa.io/generic')
|
|
6
|
+
const { RabbitMQContainer } = require('@testcontainers/rabbitmq')
|
|
7
|
+
const { getContainerRuntimeClient } = require('testcontainers')
|
|
8
|
+
|
|
9
|
+
const docker = promisify(execFile)
|
|
10
|
+
|
|
11
|
+
const IMAGE = 'rabbitmq:3.10.0-management'
|
|
12
|
+
const USER = 'developer'
|
|
13
|
+
const PASSWORD = 'secret'
|
|
14
|
+
const AMQP_PORT = 5672
|
|
15
|
+
const BROKERS_AMOUNT = 2
|
|
16
|
+
const HOST_PORTS = [5673, 5674]
|
|
17
|
+
const HEALTHCHECK_INTERVAL = global.COMQ_TESTING_HEALTHCHECK_INTERVAL ?? 1000
|
|
18
|
+
|
|
19
|
+
/** @type {import('@testcontainers/rabbitmq').StartedRabbitMQContainer[]} */
|
|
20
|
+
const brokers = []
|
|
21
|
+
|
|
22
|
+
async function startBrokers () {
|
|
23
|
+
if (brokers.length > 0) return
|
|
24
|
+
|
|
25
|
+
for (let n = 0; n < BROKERS_AMOUNT; n++) await removeStale(`comq-rmq-${n}`)
|
|
26
|
+
|
|
27
|
+
const started = await Promise.all(
|
|
28
|
+
HOST_PORTS.map((hostPort, n) =>
|
|
29
|
+
new RabbitMQContainer(IMAGE)
|
|
30
|
+
.withEnvironment({
|
|
31
|
+
RABBITMQ_DEFAULT_USER: USER,
|
|
32
|
+
RABBITMQ_DEFAULT_PASS: PASSWORD
|
|
33
|
+
})
|
|
34
|
+
.withAutoRemove(false)
|
|
35
|
+
.withName(`comq-rmq-${n}`)
|
|
36
|
+
.withExposedPorts({ container: AMQP_PORT, host: hostPort })
|
|
37
|
+
.withHealthCheck({
|
|
38
|
+
test: ['CMD', 'rabbitmq-diagnostics', '-q', 'ping'],
|
|
39
|
+
interval: 5000,
|
|
40
|
+
timeout: 1000,
|
|
41
|
+
retries: 5
|
|
42
|
+
})
|
|
43
|
+
.start()
|
|
44
|
+
)
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
brokers.push(...started)
|
|
48
|
+
|
|
49
|
+
await Promise.all(
|
|
50
|
+
Array.from({ length: BROKERS_AMOUNT }, (_, n) => healthy(n))
|
|
51
|
+
)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
async function stopBrokers () {
|
|
55
|
+
await Promise.all(brokers.map((broker) => broker.stop({ remove: true })))
|
|
56
|
+
brokers.length = 0
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* @param {string} name
|
|
61
|
+
*/
|
|
62
|
+
async function removeStale (name) {
|
|
63
|
+
const client = await getContainerRuntimeClient()
|
|
64
|
+
const listed = await client.container.list()
|
|
65
|
+
|
|
66
|
+
for (const info of listed) {
|
|
67
|
+
if (!info.Names.some((entry) => entry === `/${name}`)) continue
|
|
68
|
+
|
|
69
|
+
const container = client.container.getById(info.Id)
|
|
70
|
+
|
|
71
|
+
try {
|
|
72
|
+
await client.container.stop(container, { timeout: 0 })
|
|
73
|
+
} catch {
|
|
74
|
+
// already stopped
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
await container.remove({ force: true })
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* @param {number} [n]
|
|
83
|
+
* @returns {string}
|
|
84
|
+
*/
|
|
85
|
+
function getAddress (n = 0) {
|
|
86
|
+
if (brokers[n] === undefined) throw new Error(`Broker ${n} is not started`)
|
|
87
|
+
|
|
88
|
+
return `localhost:${HOST_PORTS[n]}`
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* @param {number} [n]
|
|
93
|
+
*/
|
|
94
|
+
async function healthy (n = 0) {
|
|
95
|
+
do {
|
|
96
|
+
await timeout(HEALTHCHECK_INTERVAL)
|
|
97
|
+
|
|
98
|
+
const { stdout } = await docker('docker', ['inspect', '-f', '{{.State.Health.Status}}', `comq-rmq-${n}`])
|
|
99
|
+
|
|
100
|
+
if (stdout.trim() === 'healthy') return
|
|
101
|
+
} while (true)
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const actions = {
|
|
105
|
+
up: async (n = 0) => {
|
|
106
|
+
await docker('docker', ['start', `comq-rmq-${n}`])
|
|
107
|
+
await healthy(n)
|
|
108
|
+
},
|
|
109
|
+
down: async (n = 0) => {
|
|
110
|
+
await docker('docker', ['stop', `comq-rmq-${n}`])
|
|
111
|
+
},
|
|
112
|
+
crashed: async (n = 0) => {
|
|
113
|
+
await docker('docker', ['kill', `comq-rmq-${n}`])
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
module.exports = {
|
|
118
|
+
BROKERS_AMOUNT,
|
|
119
|
+
USER,
|
|
120
|
+
PASSWORD,
|
|
121
|
+
startBrokers,
|
|
122
|
+
stopBrokers,
|
|
123
|
+
getAddress,
|
|
124
|
+
actions
|
|
125
|
+
}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const { World } = require('@cucumber/cucumber')
|
|
4
4
|
const { connect, assert } = require('../../')
|
|
5
|
+
const { getAddress, USER, PASSWORD } = require('./brokers')
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* @implements {comq.features.Context}
|
|
@@ -88,14 +89,11 @@ class Context extends World {
|
|
|
88
89
|
}
|
|
89
90
|
|
|
90
91
|
#url (i, user, password) {
|
|
91
|
-
return PROTOCOL + user + ':' + password + '@' +
|
|
92
|
+
return PROTOCOL + user + ':' + password + '@' + getAddress(i)
|
|
92
93
|
}
|
|
93
94
|
}
|
|
94
95
|
|
|
95
96
|
const PROTOCOL = 'amqp://'
|
|
96
|
-
const SHARDS = ['localhost:5673', 'localhost:5674']
|
|
97
|
-
const USER = 'developer'
|
|
98
|
-
const PASSWORD = 'secret'
|
|
99
97
|
|
|
100
98
|
/** @type {comq.diagnostics.Event[]} */
|
|
101
99
|
const EVENTS = ['open', 'close', 'flow', 'discard']
|
package/features/steps/hooks.js
CHANGED
|
@@ -1,11 +1,24 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const { After } = require('@cucumber/cucumber')
|
|
3
|
+
const { BeforeAll, After, AfterAll } = require('@cucumber/cucumber')
|
|
4
|
+
const { startBrokers, stopBrokers, actions, BROKERS_AMOUNT } = require('./brokers')
|
|
5
|
+
|
|
6
|
+
BeforeAll({ timeout: 120_000 }, async function () {
|
|
7
|
+
await startBrokers()
|
|
8
|
+
})
|
|
4
9
|
|
|
5
10
|
After(
|
|
6
11
|
/**
|
|
7
12
|
* @this {comq.features.Context}
|
|
8
13
|
*/
|
|
9
14
|
async function () {
|
|
15
|
+
await Promise.all(
|
|
16
|
+
Array.from({ length: BROKERS_AMOUNT }, (_, n) => actions.up(n))
|
|
17
|
+
)
|
|
18
|
+
|
|
10
19
|
await this.disconnect()
|
|
11
20
|
})
|
|
21
|
+
|
|
22
|
+
AfterAll(async function () {
|
|
23
|
+
await stopBrokers()
|
|
24
|
+
})
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "comq",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.14.0",
|
|
4
4
|
"description": "ComQ",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Artem Gurtovoi",
|
|
@@ -24,17 +24,24 @@
|
|
|
24
24
|
"main": "source/index.js",
|
|
25
25
|
"types": "types/index.d.ts",
|
|
26
26
|
"devDependencies": {
|
|
27
|
-
"@
|
|
28
|
-
"@
|
|
29
|
-
"@
|
|
30
|
-
"@
|
|
31
|
-
"@
|
|
32
|
-
"
|
|
33
|
-
"
|
|
27
|
+
"@semantic-release/changelog": "^6.0.3",
|
|
28
|
+
"@semantic-release/commit-analyzer": "^13.0.1",
|
|
29
|
+
"@semantic-release/git": "^10.0.1",
|
|
30
|
+
"@semantic-release/github": "^12.0.2",
|
|
31
|
+
"@semantic-release/npm": "^13.1.2",
|
|
32
|
+
"@semantic-release/release-notes-generator": "^14.1.0",
|
|
33
|
+
"@cucumber/cucumber": "^12.9.0",
|
|
34
|
+
"@testcontainers/rabbitmq": "^12.0.0",
|
|
35
|
+
"@toa.io/generic": "^1.0.0-alpha.208",
|
|
36
|
+
"@types/amqplib": "^0.10.8",
|
|
37
|
+
"@types/jest": "^30.0.0",
|
|
38
|
+
"husky": "^9.1.7",
|
|
39
|
+
"jest": "^30.4.2",
|
|
34
40
|
"js-yaml": "^4.1.1",
|
|
35
|
-
"randomstring": "^1.3.
|
|
41
|
+
"randomstring": "^1.3.1",
|
|
36
42
|
"snazzy": "^9.0.0",
|
|
37
|
-
"standard": "^17.1.
|
|
43
|
+
"standard": "^17.1.2",
|
|
44
|
+
"testcontainers": "^12.0.0"
|
|
38
45
|
},
|
|
39
46
|
"dependencies": {
|
|
40
47
|
"amqplib": "^2.0.1",
|
|
@@ -43,7 +50,7 @@
|
|
|
43
50
|
"reretry": "^0.1.0"
|
|
44
51
|
},
|
|
45
52
|
"scripts": {
|
|
46
|
-
"prepare": "
|
|
53
|
+
"prepare": "husky",
|
|
47
54
|
"test": "standard && jest",
|
|
48
55
|
"features": "cucumber-js --fail-fast -t 'not @manual'",
|
|
49
56
|
"lint": "standard --fix --verbose | snazzy"
|
|
@@ -52,8 +59,5 @@
|
|
|
52
59
|
"env": [
|
|
53
60
|
"jest"
|
|
54
61
|
]
|
|
55
|
-
}
|
|
56
|
-
"workspaces": [
|
|
57
|
-
"."
|
|
58
|
-
]
|
|
62
|
+
}
|
|
59
63
|
}
|
package/lerna.json
DELETED