Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test(cli): add conn pub sub command test cases #1754

Merged
merged 11 commits into from
Sep 6, 2024
1 change: 1 addition & 0 deletions .github/workflows/units_test_cli.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ jobs:
run: |
cd cli
yarn
yarn build
yarn test:coverage

# - name: Upload coverage reports to Codecov
Expand Down
56 changes: 56 additions & 0 deletions cli/src/__tests__/cli/conn.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { exec, ChildProcess } from 'child_process'
import { expect, jest, afterAll } from '@jest/globals'
import util from 'util'

const execAsync = util.promisify(exec)
jest.setTimeout(60000) // Increased timeout to 60 seconds

describe('conn', () => {
let childProcess: ChildProcess | null = null

afterAll(() => {
if (childProcess) {
childProcess.kill()
}
})

it('can get the connect command help info', async () => {
const { stdout } = await execAsync('node ./bin/index.js conn --help')
expect(stdout.trim()).toContain('Usage: mqttx conn [options]')
})

it('can connect to public mqtt broker', (done) => {
childProcess = exec('node ./bin/index.js conn -h broker.emqx.io -p 1883 -u mqttx_test_conn')

let isConnecting = false
let isConnected = false

const checkConnection = (data: string) => {
if (data.includes('Connecting')) {
isConnecting = true
isConnecting = true
}

if (data.includes('Connected')) {
isConnected = true
isConnecting = false
expect(isConnecting).toBe(false)
expect(isConnected).toBe(true)
clearTimeout(timeoutId)
done()
}
}

childProcess.stdout?.on('data', checkConnection)
childProcess.stderr?.on('data', (data) => {
checkConnection(data)
})

// Set a timeout in case the connection takes too long
const timeoutId = setTimeout(() => {
if (!isConnected) {
done(new Error('Connection timed out'))
}
}, 55000)
})
})
12 changes: 12 additions & 0 deletions cli/src/__tests__/cli/getVersion.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { execSync } from 'child_process'
import { expect } from '@jest/globals'
import packageJson from '../../../package.json'

describe('-v, --version', () => {
it('should print version', async () => {
const result = await execSync('node ./bin/index.js -v')
expect(result.toString().trim()).toEqual(
`${packageJson.version}\nhttps://mqttx.app/changelogs/v${packageJson.version}`,
)
})
})
57 changes: 57 additions & 0 deletions cli/src/__tests__/cli/pub.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { exec, ChildProcess } from 'child_process'
import { expect, jest, afterAll } from '@jest/globals'
import util from 'util'

const execAsync = util.promisify(exec)
jest.setTimeout(30000)

describe('pub', () => {
let childProcess: ChildProcess | null = null

afterAll(() => {
if (childProcess) {
childProcess.kill()
}
})

it('can get the pub command help info', async () => {
const { stdout } = await execAsync('node ./bin/index.js pub --help')
expect(stdout.trim()).toContain('Usage: mqttx pub [options]')
})

it('can publish a message to a topic', (done) => {
const topic = `test/mqttx/cli/${Date.now()}`
const message = 'Hello MQTT'
childProcess = exec(
`node ./bin/index.js pub -h broker.emqx.io -p 1883 -u mqttx_test_pub -t ${topic} -m "${message}"`,
)

let isConnecting = false
let isPublished = false

const checkPublication = (data: string) => {
if (data.includes('Connecting')) {
isConnecting = true
}

if (data.includes('Message published')) {
isPublished = true
isConnecting = false
expect(isConnecting).toBe(false)
expect(isPublished).toBe(true)
clearTimeout(timeoutId)
done()
}
}

childProcess.stdout?.on('data', checkPublication)
childProcess.stderr?.on('data', checkPublication)

// Set a timeout in case the publication takes too long
const timeoutId = setTimeout(() => {
if (!isPublished) {
done(new Error('Publication timed out'))
}
}, 25000)
})
})
65 changes: 65 additions & 0 deletions cli/src/__tests__/cli/sub.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { exec, ChildProcess } from 'child_process'
import { expect, jest, afterAll, describe, it } from '@jest/globals'
import util from 'util'

const execAsync = util.promisify(exec)
jest.setTimeout(300000)

describe('sub', () => {
let childProcesses: ChildProcess[] = []

afterAll(() => {
childProcesses.forEach((process) => {
process.kill()
})
childProcesses = []
})

it('can get the sub command help info', async () => {
const { stdout } = await execAsync('node ./bin/index.js sub --help')
expect(stdout.trim()).toContain('Usage: mqttx sub [options]')
})

it('can subscribe to a topic and receive messages', (done) => {
const topic = `testtopic/#`
const childProcess = exec(`node ./bin/index.js sub -h broker.emqx.io -p 1883 -u mqttx_test_sub -t ${topic}`)
childProcesses.push(childProcess)

let isSubscribing = false
let isSubscribed = false
let messageReceived = false

const checkOutput = (data: string) => {
if (data.includes('Subscribing')) {
isSubscribing = true
}

if (data.includes(`Subscribed to ${topic}`)) {
isSubscribed = true
isSubscribing = false
}

if (data.includes('topic:') && data.includes('qos:')) {
messageReceived = true
}

if (isSubscribed && messageReceived) {
expect(isSubscribing).toBe(false)
expect(isSubscribed).toBe(true)
expect(messageReceived).toBe(true)
clearTimeout(timeoutId)
done()
}
}

childProcess.stdout?.on('data', checkOutput)
childProcess.stderr?.on('data', checkOutput)

// Set a timeout in case the subscription or message reception takes too long
const timeoutId = setTimeout(() => {
if (!isSubscribed || !messageReceived) {
done(new Error('Subscription or message reception timed out'))
}
}, 25000)
})
})
Loading