Skip to content

Commit f988058

Browse files
authored
fix: some others flaky tests (#1808)
* fix: some others flaky tests * fix: minor refactor of timers * style: remove useless console.log
1 parent c0a6668 commit f988058

File tree

4 files changed

+37
-26
lines changed

4 files changed

+37
-26
lines changed

src/lib/PingTimer.ts

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
import { clearTimeout as clearT, setTimeout as setT } from 'worker-timers'
2-
import isBrowser, { isWebWorker } from './is-browser'
1+
import timers from './timers'
32

43
export default class PingTimer {
54
private keepalive: number
@@ -8,16 +7,6 @@ export default class PingTimer {
87

98
private checkPing: () => void
109

11-
// dont directly assign globals to class props otherwise this throws in web workers: Uncaught TypeError: Illegal invocation
12-
// See: https://stackoverflow.com/questions/9677985/uncaught-typeerror-illegal-invocation-in-chrome
13-
private _setTimeout: typeof setT =
14-
isBrowser && !isWebWorker
15-
? setT
16-
: (func, time) => setTimeout(func, time)
17-
18-
private _clearTimeout: typeof clearT =
19-
isBrowser && !isWebWorker ? clearT : (timer) => clearTimeout(timer)
20-
2110
constructor(keepalive: number, checkPing: () => void) {
2211
this.keepalive = keepalive * 1000
2312
this.checkPing = checkPing
@@ -26,14 +15,14 @@ export default class PingTimer {
2615

2716
clear() {
2817
if (this.timer) {
29-
this._clearTimeout(this.timer)
18+
timers.clear(this.timer)
3019
this.timer = null
3120
}
3221
}
3322

3423
reschedule() {
3524
this.clear()
36-
this.timer = this._setTimeout(() => {
25+
this.timer = timers.set(() => {
3726
this.checkPing()
3827
// prevent possible race condition where the timer is destroyed on _cleauUp
3928
// and recreated here

src/lib/timers.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import isBrowser, { isWebWorker } from './is-browser'
2+
import { clearTimeout as clearT, setTimeout as setT } from 'worker-timers'
3+
4+
// dont directly assign globals to class props otherwise this throws in web workers: Uncaught TypeError: Illegal invocation
5+
// See: https://stackoverflow.com/questions/9677985/uncaught-typeerror-illegal-invocation-in-chrome
6+
7+
const timers: { set: typeof setT; clear: typeof clearT } = {
8+
set:
9+
isBrowser && !isWebWorker
10+
? setT
11+
: (func, time) => setTimeout(func, time),
12+
clear: isBrowser && !isWebWorker ? clearT : (timer) => clearTimeout(timer),
13+
}
14+
15+
export default timers

test/abstract_client.ts

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ import { IPublishPacket, IPubrelPacket, ISubackPacket, QoS } from 'mqtt-packet'
2121
import { DoneCallback, ErrorWithReasonCode } from 'src/lib/shared'
2222
import { fail } from 'assert'
2323
import { describe, it, beforeEach, afterEach } from 'node:test'
24-
import { nextTick } from 'process'
2524

2625
/**
2726
* These tests try to be consistent with names for servers (brokers) and clients,
@@ -44,6 +43,10 @@ import { nextTick } from 'process'
4443
*
4544
*/
4645

46+
const fakeTimersOptions = {
47+
shouldClearNativeTimers: true,
48+
}
49+
4750
export default function abstractTest(server, config, ports) {
4851
const version = config.protocolVersion || 4
4952

@@ -1963,7 +1966,7 @@ export default function abstractTest(server, config, ports) {
19631966

19641967
// eslint-disable-next-line
19651968
beforeEach(() => {
1966-
clock = sinon.useFakeTimers()
1969+
clock = sinon.useFakeTimers(fakeTimersOptions)
19671970
})
19681971

19691972
afterEach(() => {
@@ -2054,7 +2057,7 @@ export default function abstractTest(server, config, ports) {
20542057
timeout: 10000,
20552058
},
20562059
function _test(t, done) {
2057-
const clock = sinon.useFakeTimers()
2060+
const clock = sinon.useFakeTimers(fakeTimersOptions)
20582061

20592062
t.after(() => {
20602063
clock.restore()
@@ -2076,6 +2079,7 @@ export default function abstractTest(server, config, ports) {
20762079
assert.equal(err.message, 'Keepalive timeout')
20772080
client.once('connect', () => {
20782081
client.end(true, done)
2082+
clock.tick(100)
20792083
client = null
20802084
})
20812085
})
@@ -2094,7 +2098,7 @@ export default function abstractTest(server, config, ports) {
20942098
'should not reconnect if pingresp is successful',
20952099
{ timeout: 1000 },
20962100
function _test(t, done) {
2097-
const clock = sinon.useFakeTimers()
2101+
const clock = sinon.useFakeTimers(fakeTimersOptions)
20982102

20992103
t.after(() => {
21002104
clock.restore()
@@ -2118,6 +2122,7 @@ export default function abstractTest(server, config, ports) {
21182122
if (packet.cmd === 'pingreq') {
21192123
client.removeAllListeners('close')
21202124
client.end(true, done)
2125+
clock.tick(100)
21212126
client = null
21222127
}
21232128
})
@@ -2910,7 +2915,7 @@ export default function abstractTest(server, config, ports) {
29102915
})
29112916

29122917
it('should reconnect after stream disconnect', function _test(t, done) {
2913-
const clock = sinon.useFakeTimers()
2918+
const clock = sinon.useFakeTimers(fakeTimersOptions)
29142919

29152920
t.after(() => {
29162921
clock.restore()
@@ -2929,12 +2934,13 @@ export default function abstractTest(server, config, ports) {
29292934
tryReconnect = false
29302935
} else {
29312936
client.end(true, done)
2937+
clock.tick(100)
29322938
}
29332939
})
29342940
})
29352941

29362942
it("should emit 'reconnect' when reconnecting", function _test(t, done) {
2937-
const clock = sinon.useFakeTimers()
2943+
const clock = sinon.useFakeTimers(fakeTimersOptions)
29382944

29392945
t.after(() => {
29402946
clock.restore()
@@ -2960,12 +2966,13 @@ export default function abstractTest(server, config, ports) {
29602966
} else {
29612967
assert.isTrue(reconnectEvent)
29622968
client.end(true, done)
2969+
clock.tick(100)
29632970
}
29642971
})
29652972
})
29662973

29672974
it("should emit 'offline' after going offline", function _test(t, done) {
2968-
const clock = sinon.useFakeTimers()
2975+
const clock = sinon.useFakeTimers(fakeTimersOptions)
29692976

29702977
t.after(() => {
29712978
clock.restore()
@@ -2991,6 +2998,7 @@ export default function abstractTest(server, config, ports) {
29912998
} else {
29922999
assert.isTrue(offlineEvent)
29933000
client.end(true, done)
3001+
clock.tick(100)
29943002
}
29953003
})
29963004
})
@@ -3030,7 +3038,7 @@ export default function abstractTest(server, config, ports) {
30303038
timeout: 10000,
30313039
},
30323040
function _test(t, done) {
3033-
const clock = sinon.useFakeTimers()
3041+
const clock = sinon.useFakeTimers(fakeTimersOptions)
30343042

30353043
t.after(() => {
30363044
clock.restore()
@@ -3070,6 +3078,7 @@ export default function abstractTest(server, config, ports) {
30703078
)
30713079
}
30723080
})
3081+
clock.tick(100)
30733082
}
30743083
})
30753084
},
@@ -3084,8 +3093,8 @@ export default function abstractTest(server, config, ports) {
30843093
})
30853094
// bind client.end so that when it is called it is automatically passed in the done callback
30863095
setTimeout(() => {
3087-
client.end.call(client, done)
3088-
}, 50)
3096+
client.end(done)
3097+
}, 100)
30893098
})
30903099

30913100
it('should emit connack timeout error', function _test(t, done) {

test/client_mqtt5.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -702,10 +702,8 @@ describe('MQTT 5.0', () => {
702702
protocolVersion: 5,
703703
properties: { authenticationData: Buffer.from([1, 2, 3, 4]) },
704704
}
705-
console.log('client connecting')
706705
const client = mqtt.connect(opts)
707706
client.on('error', (error) => {
708-
console.log('error hit')
709707
assert.strictEqual(
710708
error.message,
711709
'Packet has no Authentication Method',

0 commit comments

Comments
 (0)