@libp2p/interface-compliance-tests 6.5.0-8484de8a2 → 6.5.0-87bc8d4fb
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/dist/src/connection-encryption/index.d.ts.map +1 -1
- package/dist/src/connection-encryption/index.js +15 -24
- package/dist/src/connection-encryption/index.js.map +1 -1
- package/dist/src/connection-encryption/utils/index.d.ts +3 -0
- package/dist/src/connection-encryption/utils/index.d.ts.map +1 -0
- package/dist/src/connection-encryption/utils/index.js +21 -0
- package/dist/src/connection-encryption/utils/index.js.map +1 -0
- package/dist/src/matchers.d.ts +12 -0
- package/dist/src/matchers.d.ts.map +1 -0
- package/dist/src/matchers.js +14 -0
- package/dist/src/matchers.js.map +1 -0
- package/dist/src/mocks/connection-manager.d.ts +27 -0
- package/dist/src/mocks/connection-manager.d.ts.map +1 -0
- package/dist/src/mocks/connection-manager.js +147 -0
- package/dist/src/mocks/connection-manager.js.map +1 -0
- package/dist/src/mocks/connection.d.ts +41 -0
- package/dist/src/mocks/connection.d.ts.map +1 -0
- package/dist/src/mocks/connection.js +236 -0
- package/dist/src/mocks/connection.js.map +1 -0
- package/dist/src/mocks/duplex.d.ts +4 -0
- package/dist/src/mocks/duplex.d.ts.map +1 -0
- package/dist/src/mocks/duplex.js +9 -0
- package/dist/src/mocks/duplex.js.map +1 -0
- package/dist/src/mocks/index.d.ts +12 -0
- package/dist/src/mocks/index.d.ts.map +1 -0
- package/dist/src/mocks/index.js +8 -0
- package/dist/src/mocks/index.js.map +1 -0
- package/dist/src/mocks/multiaddr-connection.d.ts +17 -0
- package/dist/src/mocks/multiaddr-connection.d.ts.map +1 -0
- package/dist/src/mocks/multiaddr-connection.js +64 -0
- package/dist/src/mocks/multiaddr-connection.js.map +1 -0
- package/dist/src/mocks/muxer.d.ts +36 -0
- package/dist/src/mocks/muxer.d.ts.map +1 -0
- package/dist/src/mocks/muxer.js +234 -0
- package/dist/src/mocks/muxer.js.map +1 -0
- package/dist/src/mocks/registrar.d.ts +16 -0
- package/dist/src/mocks/registrar.d.ts.map +1 -0
- package/dist/src/mocks/registrar.js +66 -0
- package/dist/src/mocks/registrar.js.map +1 -0
- package/dist/src/mocks/upgrader.d.ts +9 -0
- package/dist/src/mocks/upgrader.d.ts.map +1 -0
- package/dist/src/mocks/upgrader.js +46 -0
- package/dist/src/mocks/upgrader.js.map +1 -0
- package/dist/src/pubsub/api.d.ts +6 -0
- package/dist/src/pubsub/api.d.ts.map +1 -0
- package/dist/src/pubsub/api.js +88 -0
- package/dist/src/pubsub/api.js.map +1 -0
- package/dist/src/pubsub/connection-handlers.d.ts +6 -0
- package/dist/src/pubsub/connection-handlers.d.ts.map +1 -0
- package/dist/src/pubsub/connection-handlers.js +329 -0
- package/dist/src/pubsub/connection-handlers.js.map +1 -0
- package/dist/src/pubsub/emit-self.d.ts +6 -0
- package/dist/src/pubsub/emit-self.d.ts.map +1 -0
- package/dist/src/pubsub/emit-self.js +80 -0
- package/dist/src/pubsub/emit-self.js.map +1 -0
- package/dist/src/pubsub/index.d.ts +18 -0
- package/dist/src/pubsub/index.d.ts.map +1 -0
- package/dist/src/pubsub/index.js +17 -0
- package/dist/src/pubsub/index.js.map +1 -0
- package/dist/src/pubsub/messages.d.ts +6 -0
- package/dist/src/pubsub/messages.d.ts.map +1 -0
- package/dist/src/pubsub/messages.js +48 -0
- package/dist/src/pubsub/messages.js.map +1 -0
- package/dist/src/pubsub/multiple-nodes.d.ts +6 -0
- package/dist/src/pubsub/multiple-nodes.d.ts.map +1 -0
- package/dist/src/pubsub/multiple-nodes.js +350 -0
- package/dist/src/pubsub/multiple-nodes.js.map +1 -0
- package/dist/src/pubsub/two-nodes.d.ts +6 -0
- package/dist/src/pubsub/two-nodes.d.ts.map +1 -0
- package/dist/src/pubsub/two-nodes.js +216 -0
- package/dist/src/pubsub/two-nodes.js.map +1 -0
- package/dist/src/pubsub/utils.d.ts +5 -0
- package/dist/src/pubsub/utils.d.ts.map +1 -0
- package/dist/src/pubsub/utils.js +27 -0
- package/dist/src/pubsub/utils.js.map +1 -0
- package/dist/src/stream-muxer/base-test.d.ts.map +1 -1
- package/dist/src/stream-muxer/base-test.js +345 -62
- package/dist/src/stream-muxer/base-test.js.map +1 -1
- package/dist/src/stream-muxer/close-test.d.ts.map +1 -1
- package/dist/src/stream-muxer/close-test.js +320 -253
- package/dist/src/stream-muxer/close-test.js.map +1 -1
- package/dist/src/stream-muxer/index.js +2 -2
- package/dist/src/stream-muxer/index.js.map +1 -1
- package/dist/src/stream-muxer/{stream-test.d.ts → mega-stress-test.d.ts} +2 -2
- package/dist/src/stream-muxer/mega-stress-test.d.ts.map +1 -0
- package/dist/src/stream-muxer/mega-stress-test.js +11 -0
- package/dist/src/stream-muxer/mega-stress-test.js.map +1 -0
- package/dist/src/stream-muxer/spawner.d.ts +4 -0
- package/dist/src/stream-muxer/spawner.d.ts.map +1 -0
- package/dist/src/stream-muxer/spawner.js +39 -0
- package/dist/src/stream-muxer/spawner.js.map +1 -0
- package/dist/src/stream-muxer/stress-test.d.ts.map +1 -1
- package/dist/src/stream-muxer/stress-test.js +16 -70
- package/dist/src/stream-muxer/stress-test.js.map +1 -1
- package/dist/src/transport/index.d.ts.map +1 -1
- package/dist/src/transport/index.js +203 -232
- package/dist/src/transport/index.js.map +1 -1
- package/dist/src/transport/utils.js +2 -2
- package/dist/src/transport/utils.js.map +1 -1
- package/package.json +51 -23
- package/src/connection-encryption/index.ts +20 -27
- package/src/connection-encryption/utils/index.ts +27 -0
- package/src/matchers.ts +18 -0
- package/src/mocks/connection-manager.ts +216 -0
- package/src/mocks/connection.ts +309 -0
- package/src/mocks/duplex.ts +11 -0
- package/src/mocks/index.ts +11 -0
- package/src/mocks/multiaddr-connection.ts +80 -0
- package/src/mocks/muxer.ts +331 -0
- package/src/mocks/registrar.ts +86 -0
- package/src/mocks/upgrader.ts +65 -0
- package/src/pubsub/api.ts +116 -0
- package/src/pubsub/connection-handlers.ts +413 -0
- package/src/pubsub/emit-self.ts +99 -0
- package/src/pubsub/index.ts +34 -0
- package/src/pubsub/messages.ts +59 -0
- package/src/pubsub/multiple-nodes.ts +440 -0
- package/src/pubsub/two-nodes.ts +272 -0
- package/src/pubsub/utils.ts +34 -0
- package/src/stream-muxer/base-test.ts +413 -75
- package/src/stream-muxer/close-test.ts +343 -304
- package/src/stream-muxer/index.ts +2 -2
- package/src/stream-muxer/mega-stress-test.ts +14 -0
- package/src/stream-muxer/spawner.ts +57 -0
- package/src/stream-muxer/stress-test.ts +18 -92
- package/src/transport/index.ts +241 -280
- package/src/transport/utils.ts +2 -2
- package/dist/src/stream-muxer/stream-test.d.ts.map +0 -1
- package/dist/src/stream-muxer/stream-test.js +0 -289
- package/dist/src/stream-muxer/stream-test.js.map +0 -1
- package/src/stream-muxer/stream-test.ts +0 -380
|
@@ -1,380 +0,0 @@
|
|
|
1
|
-
import { StreamCloseEvent, StreamMessageEvent } from '@libp2p/interface'
|
|
2
|
-
import { multiaddrConnectionPair } from '@libp2p/utils'
|
|
3
|
-
import { expect } from 'aegir/chai'
|
|
4
|
-
import delay from 'delay'
|
|
5
|
-
import all from 'it-all'
|
|
6
|
-
import { pEvent } from 'p-event'
|
|
7
|
-
import Sinon from 'sinon'
|
|
8
|
-
import { Uint8ArrayList } from 'uint8arraylist'
|
|
9
|
-
import { isValidTick } from '../is-valid-tick.ts'
|
|
10
|
-
import type { TestSetup } from '../index.ts'
|
|
11
|
-
import type { MultiaddrConnection, Stream, StreamMuxer, StreamMuxerFactory } from '@libp2p/interface'
|
|
12
|
-
|
|
13
|
-
export default (common: TestSetup<StreamMuxerFactory>): void => {
|
|
14
|
-
describe('streams', () => {
|
|
15
|
-
let dialer: StreamMuxer
|
|
16
|
-
let listener: StreamMuxer
|
|
17
|
-
let outboundStream: Stream
|
|
18
|
-
let inboundStream: Stream
|
|
19
|
-
let streams: [Stream, Stream]
|
|
20
|
-
let outboundConnection: MultiaddrConnection
|
|
21
|
-
let inboundConnection: MultiaddrConnection
|
|
22
|
-
|
|
23
|
-
beforeEach(async () => {
|
|
24
|
-
([outboundConnection, inboundConnection] = multiaddrConnectionPair())
|
|
25
|
-
|
|
26
|
-
const dialerFactory = await common.setup()
|
|
27
|
-
dialer = dialerFactory.createStreamMuxer(outboundConnection)
|
|
28
|
-
|
|
29
|
-
const listenerFactory = await common.setup()
|
|
30
|
-
listener = listenerFactory.createStreamMuxer(inboundConnection)
|
|
31
|
-
|
|
32
|
-
streams = await Promise.all([
|
|
33
|
-
pEvent<'stream', CustomEvent<Stream>>(listener, 'stream').then(evt => evt.detail),
|
|
34
|
-
dialer.createStream()
|
|
35
|
-
])
|
|
36
|
-
|
|
37
|
-
inboundStream = streams[0]
|
|
38
|
-
outboundStream = streams[1]
|
|
39
|
-
})
|
|
40
|
-
|
|
41
|
-
afterEach(async () => {
|
|
42
|
-
await dialer?.close()
|
|
43
|
-
await listener?.close()
|
|
44
|
-
})
|
|
45
|
-
|
|
46
|
-
it('should have correct status after opening', () => {
|
|
47
|
-
streams.forEach(stream => {
|
|
48
|
-
expect(stream).to.have.property('status', 'open', `${stream.direction} stream status was incorrect`)
|
|
49
|
-
expect(stream).to.have.property('writeStatus', 'writable', `${stream.direction} stream writeStatus was incorrect`)
|
|
50
|
-
expect(stream).to.have.property('readStatus', 'readable', `${stream.direction} stream readStatus was incorrect`)
|
|
51
|
-
})
|
|
52
|
-
})
|
|
53
|
-
|
|
54
|
-
it('should have correct timeline after opening', () => {
|
|
55
|
-
streams.forEach(stream => {
|
|
56
|
-
expect(isValidTick(stream.timeline.open)).to.equal(true, `${stream.direction} stream timeline.open was incorrect`)
|
|
57
|
-
expect(stream).to.not.have.nested.property('timeline.close', `${stream.direction} stream timeline.close was incorrect`)
|
|
58
|
-
expect(stream).to.not.have.nested.property('timeline.closeRead', `${stream.direction} stream timeline.closeRead was incorrect`)
|
|
59
|
-
expect(stream).to.not.have.nested.property('timeline.closeWrite', `${stream.direction} stream timeline.closeWrite was incorrect`)
|
|
60
|
-
expect(stream).to.not.have.nested.property('timeline.reset', `${stream.direction} stream timeline.reset was incorrect`)
|
|
61
|
-
expect(stream).to.not.have.nested.property('timeline.abort', `${stream.direction} stream timeline.abort was incorrect`)
|
|
62
|
-
})
|
|
63
|
-
})
|
|
64
|
-
|
|
65
|
-
it('outbound stream sends data', async () => {
|
|
66
|
-
const messageEventPromise = pEvent<'message', StreamMessageEvent>(inboundStream, 'message')
|
|
67
|
-
const data = Uint8Array.from([0, 1, 2, 3, 4])
|
|
68
|
-
|
|
69
|
-
outboundStream.send(data)
|
|
70
|
-
|
|
71
|
-
const evt = await messageEventPromise
|
|
72
|
-
expect(evt.data.subarray()).to.equalBytes(data)
|
|
73
|
-
})
|
|
74
|
-
|
|
75
|
-
it('inbound stream sends data', async () => {
|
|
76
|
-
const messageEventPromise = pEvent<'message', StreamMessageEvent>(outboundStream, 'message')
|
|
77
|
-
const data = Uint8Array.from([0, 1, 2, 3, 4])
|
|
78
|
-
|
|
79
|
-
inboundStream.send(data)
|
|
80
|
-
|
|
81
|
-
const evt = await messageEventPromise
|
|
82
|
-
expect(evt.data.subarray()).to.equalBytes(data)
|
|
83
|
-
})
|
|
84
|
-
|
|
85
|
-
it('closes', async () => {
|
|
86
|
-
const signal = AbortSignal.timeout(1_000)
|
|
87
|
-
|
|
88
|
-
void outboundStream.close({
|
|
89
|
-
signal
|
|
90
|
-
})
|
|
91
|
-
void inboundStream.close({
|
|
92
|
-
signal
|
|
93
|
-
})
|
|
94
|
-
|
|
95
|
-
expect(outboundStream).to.have.property('status', 'open')
|
|
96
|
-
expect(outboundStream).to.have.property('readStatus', 'readable')
|
|
97
|
-
expect(outboundStream).to.have.property('writeStatus', 'closing')
|
|
98
|
-
|
|
99
|
-
await Promise.all([
|
|
100
|
-
pEvent(outboundStream, 'close', {
|
|
101
|
-
signal
|
|
102
|
-
}),
|
|
103
|
-
pEvent(inboundStream, 'close', {
|
|
104
|
-
signal
|
|
105
|
-
})
|
|
106
|
-
])
|
|
107
|
-
|
|
108
|
-
streams.forEach(stream => {
|
|
109
|
-
expect(stream).to.have.property('status', 'closed', `${stream.direction} stream status was incorrect`)
|
|
110
|
-
expect(stream).to.have.property('writeStatus', 'closed', `${stream.direction} stream writeStatus was incorrect`)
|
|
111
|
-
expect(stream).to.have.property('readStatus', 'closed', `${stream.direction} stream readStatus was incorrect`)
|
|
112
|
-
|
|
113
|
-
expect(isValidTick(stream.timeline.open)).to.equal(true, `${stream.direction} stream timeline.open was incorrect`)
|
|
114
|
-
expect(isValidTick(stream.timeline.close)).to.equal(true, `${stream.direction} stream timeline.close was incorrect`)
|
|
115
|
-
|
|
116
|
-
expect(stream).to.not.have.nested.property('timeline.reset', `${stream.direction} stream timeline.reset was incorrect`)
|
|
117
|
-
expect(stream).to.not.have.nested.property('timeline.abort', `${stream.direction} stream timeline.abort was incorrect`)
|
|
118
|
-
})
|
|
119
|
-
})
|
|
120
|
-
|
|
121
|
-
it('should send large amounts of data in both directions', async function () {
|
|
122
|
-
const timeout = 360_000
|
|
123
|
-
this.timeout(timeout)
|
|
124
|
-
|
|
125
|
-
const sent = new Array(10)
|
|
126
|
-
.fill(0)
|
|
127
|
-
.map((val, index) => new Uint8Array(1024 * 1024).fill(index))
|
|
128
|
-
|
|
129
|
-
// send data in both directions simultaneously
|
|
130
|
-
const [
|
|
131
|
-
outboundReceived,
|
|
132
|
-
inboundReceived
|
|
133
|
-
] = await Promise.all([
|
|
134
|
-
all(outboundStream),
|
|
135
|
-
all(inboundStream),
|
|
136
|
-
(async () => {
|
|
137
|
-
for (const buf of sent) {
|
|
138
|
-
if (!outboundStream.send(buf)) {
|
|
139
|
-
await pEvent(outboundStream, 'drain', {
|
|
140
|
-
rejectionEvents: [
|
|
141
|
-
'close'
|
|
142
|
-
]
|
|
143
|
-
})
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
await outboundStream.close()
|
|
148
|
-
})(),
|
|
149
|
-
(async () => {
|
|
150
|
-
for (const buf of sent) {
|
|
151
|
-
if (!inboundStream.send(buf)) {
|
|
152
|
-
await pEvent(inboundStream, 'drain', {
|
|
153
|
-
rejectionEvents: [
|
|
154
|
-
'close'
|
|
155
|
-
]
|
|
156
|
-
})
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
await inboundStream.close()
|
|
161
|
-
})()
|
|
162
|
-
])
|
|
163
|
-
|
|
164
|
-
expect(new Uint8ArrayList(...outboundReceived)).to.have.property('byteLength', new Uint8ArrayList(...sent).byteLength)
|
|
165
|
-
expect(new Uint8ArrayList(...inboundReceived)).to.have.property('byteLength', new Uint8ArrayList(...sent).byteLength)
|
|
166
|
-
})
|
|
167
|
-
|
|
168
|
-
it('closes for writing', async () => {
|
|
169
|
-
const signal = AbortSignal.timeout(1_000)
|
|
170
|
-
|
|
171
|
-
const eventPromise = pEvent(inboundStream, 'remoteCloseWrite')
|
|
172
|
-
|
|
173
|
-
void outboundStream.close({
|
|
174
|
-
signal
|
|
175
|
-
})
|
|
176
|
-
|
|
177
|
-
expect(outboundStream).to.have.property('writeStatus', 'closing')
|
|
178
|
-
|
|
179
|
-
await delay(100)
|
|
180
|
-
|
|
181
|
-
expect(inboundStream).to.have.property('readStatus', 'readable')
|
|
182
|
-
|
|
183
|
-
await eventPromise
|
|
184
|
-
|
|
185
|
-
streams.forEach(stream => {
|
|
186
|
-
expect(stream).to.have.property('status', 'open', `${stream.direction} stream status was incorrect`)
|
|
187
|
-
|
|
188
|
-
expect(isValidTick(stream.timeline.open)).to.equal(true, `${stream.direction} stream timeline.open was incorrect`)
|
|
189
|
-
|
|
190
|
-
expect(stream).to.not.have.nested.property('timeline.close', `${stream.direction} stream timeline.close was incorrect`)
|
|
191
|
-
expect(stream).to.not.have.nested.property('timeline.reset', `${stream.direction} stream timeline.reset was incorrect`)
|
|
192
|
-
expect(stream).to.not.have.nested.property('timeline.abort', `${stream.direction} stream timeline.abort was incorrect`)
|
|
193
|
-
})
|
|
194
|
-
|
|
195
|
-
expect(outboundStream).to.have.property('writeStatus', 'closed', 'outbound stream writeStatus was incorrect')
|
|
196
|
-
expect(outboundStream).to.have.property('readStatus', 'readable', 'inbound stream readStatus was incorrect')
|
|
197
|
-
|
|
198
|
-
expect(outboundStream).to.not.have.nested.property('timeline.closeRead', 'inbound stream timeline.closeRead was incorrect')
|
|
199
|
-
|
|
200
|
-
expect(inboundStream).to.have.property('writeStatus', 'writable', 'inbound stream writeStatus was incorrect')
|
|
201
|
-
expect(inboundStream).to.have.property('readStatus', 'readable', 'inbound stream readStatus was incorrect')
|
|
202
|
-
})
|
|
203
|
-
|
|
204
|
-
it('aborts', async () => {
|
|
205
|
-
const eventPromises = Promise.all([
|
|
206
|
-
pEvent<'close', StreamCloseEvent>(outboundStream, 'close'),
|
|
207
|
-
pEvent<'close', StreamCloseEvent>(inboundStream, 'close')
|
|
208
|
-
])
|
|
209
|
-
|
|
210
|
-
const err = new Error('Urk!')
|
|
211
|
-
outboundStream.abort(err)
|
|
212
|
-
|
|
213
|
-
const [outboundEvent, inboundEvent] = await eventPromises
|
|
214
|
-
|
|
215
|
-
streams.forEach(stream => {
|
|
216
|
-
expect(stream).to.have.property('writeStatus', 'closed', `${stream.direction} stream writeStatus was incorrect`)
|
|
217
|
-
expect(stream).to.have.property('readStatus', 'closed', `${stream.direction} stream readStatus was incorrect`)
|
|
218
|
-
|
|
219
|
-
expect(isValidTick(stream.timeline.open)).to.equal(true, `${stream.direction} stream timeline.open was incorrect`)
|
|
220
|
-
|
|
221
|
-
expect(stream).to.not.have.nested.property('timeline.close', `${stream.direction} stream timeline.close was incorrect`)
|
|
222
|
-
})
|
|
223
|
-
|
|
224
|
-
expect(outboundStream).to.have.property('status', 'aborted', 'outbound stream status was incorrect')
|
|
225
|
-
expect(isValidTick(outboundStream.timeline.close)).to.equal(true, 'outbound stream timeline.abort was incorrect')
|
|
226
|
-
|
|
227
|
-
expect(inboundStream).to.have.property('status', 'reset', 'inbound stream status was incorrect')
|
|
228
|
-
expect(isValidTick(inboundStream.timeline.close)).to.equal(true, 'inbound stream timeline.reset was incorrect')
|
|
229
|
-
|
|
230
|
-
expect(() => outboundStream.send(Uint8Array.from([0, 1, 2, 3]))).to.throw()
|
|
231
|
-
.with.property('name', 'StreamStateError', 'could still write to aborted stream')
|
|
232
|
-
|
|
233
|
-
expect(() => inboundStream.send(Uint8Array.from([0, 1, 2, 3]))).to.throw()
|
|
234
|
-
.with.property('name', 'StreamStateError', 'could still write to reset stream')
|
|
235
|
-
|
|
236
|
-
expect(outboundEvent).to.have.property('error', err)
|
|
237
|
-
expect(inboundEvent).to.have.nested.property('error.name', 'StreamResetError')
|
|
238
|
-
})
|
|
239
|
-
|
|
240
|
-
it('does not send close read when remote closes write', async () => {
|
|
241
|
-
// @ts-expect-error internal method of AbstractMessageStream
|
|
242
|
-
const sendCloseReadSpy = Sinon.spy(outboundStream, 'sendCloseRead')
|
|
243
|
-
|
|
244
|
-
await Promise.all([
|
|
245
|
-
pEvent(outboundStream, 'remoteCloseWrite'),
|
|
246
|
-
inboundStream.close()
|
|
247
|
-
])
|
|
248
|
-
|
|
249
|
-
await delay(100)
|
|
250
|
-
|
|
251
|
-
expect(sendCloseReadSpy.called).to.be.false()
|
|
252
|
-
})
|
|
253
|
-
|
|
254
|
-
it('does not send close read or write when remote resets', async () => {
|
|
255
|
-
// @ts-expect-error internal method of AbstractMessageStream
|
|
256
|
-
const sendCloseReadSpy = Sinon.spy(outboundStream, 'sendCloseRead')
|
|
257
|
-
// @ts-expect-error internal method of AbstractMessageStream
|
|
258
|
-
const sendCloseWriteSpy = Sinon.spy(outboundStream, 'sendCloseWrite')
|
|
259
|
-
|
|
260
|
-
await Promise.all([
|
|
261
|
-
pEvent(outboundStream, 'close'),
|
|
262
|
-
inboundStream.abort(new Error('Urk!'))
|
|
263
|
-
])
|
|
264
|
-
|
|
265
|
-
await delay(100)
|
|
266
|
-
|
|
267
|
-
await outboundStream.close()
|
|
268
|
-
|
|
269
|
-
await delay(100)
|
|
270
|
-
|
|
271
|
-
expect(sendCloseReadSpy.called).to.be.false()
|
|
272
|
-
expect(sendCloseWriteSpy.called).to.be.false()
|
|
273
|
-
})
|
|
274
|
-
|
|
275
|
-
it('should wait for sending data to finish when closing gracefully', async () => {
|
|
276
|
-
let sent = 0
|
|
277
|
-
let received = 0
|
|
278
|
-
let filledBuffer = false
|
|
279
|
-
const receivedAll = Promise.withResolvers<boolean>()
|
|
280
|
-
|
|
281
|
-
inboundStream.addEventListener('message', (evt) => {
|
|
282
|
-
received += evt.data.byteLength
|
|
283
|
-
|
|
284
|
-
if (filledBuffer && received === sent) {
|
|
285
|
-
receivedAll.resolve(true)
|
|
286
|
-
}
|
|
287
|
-
})
|
|
288
|
-
|
|
289
|
-
// fill the send buffer
|
|
290
|
-
while (true) {
|
|
291
|
-
const length = 1024
|
|
292
|
-
sent += length
|
|
293
|
-
const sendMore = outboundStream.send(new Uint8Array(length))
|
|
294
|
-
|
|
295
|
-
if (sendMore === false) {
|
|
296
|
-
filledBuffer = true
|
|
297
|
-
break
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
expect(outboundStream.writeStatus).to.equal('writable')
|
|
302
|
-
expect(outboundStream.writableNeedsDrain).to.be.true()
|
|
303
|
-
|
|
304
|
-
// close gracefully
|
|
305
|
-
await outboundStream.close()
|
|
306
|
-
|
|
307
|
-
await expect(receivedAll.promise).to.eventually.be.true('did not receive all data')
|
|
308
|
-
})
|
|
309
|
-
|
|
310
|
-
it('should wait for sending data to finish when closing the writable end gracefully', async () => {
|
|
311
|
-
let sent = 0
|
|
312
|
-
let received = 0
|
|
313
|
-
let filledBuffer = false
|
|
314
|
-
const receivedAll = Promise.withResolvers<boolean>()
|
|
315
|
-
|
|
316
|
-
inboundStream.addEventListener('message', (evt) => {
|
|
317
|
-
received += evt.data.byteLength
|
|
318
|
-
|
|
319
|
-
if (filledBuffer && received === sent) {
|
|
320
|
-
receivedAll.resolve(true)
|
|
321
|
-
}
|
|
322
|
-
})
|
|
323
|
-
|
|
324
|
-
// fill the send buffer
|
|
325
|
-
while (true) {
|
|
326
|
-
const length = 1024
|
|
327
|
-
sent += length
|
|
328
|
-
const sendMore = outboundStream.send(new Uint8Array(length))
|
|
329
|
-
|
|
330
|
-
if (sendMore === false) {
|
|
331
|
-
filledBuffer = true
|
|
332
|
-
break
|
|
333
|
-
}
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
expect(outboundStream.writeStatus).to.equal('writable')
|
|
337
|
-
expect(outboundStream.writableNeedsDrain).to.be.true()
|
|
338
|
-
|
|
339
|
-
// close gracefully
|
|
340
|
-
await outboundStream.close()
|
|
341
|
-
|
|
342
|
-
await expect(receivedAll.promise).to.eventually.be.true('did not receive all data')
|
|
343
|
-
})
|
|
344
|
-
|
|
345
|
-
it('should abort close due to timeout with slow sender', async () => {
|
|
346
|
-
const chunkSize = 1024
|
|
347
|
-
|
|
348
|
-
// make the 'drain' event slow to fire
|
|
349
|
-
// @ts-expect-error private fields
|
|
350
|
-
outboundConnection.local.delay = 1000
|
|
351
|
-
|
|
352
|
-
inboundStream = streams[0]
|
|
353
|
-
outboundStream = streams[1]
|
|
354
|
-
|
|
355
|
-
// ensure there are bytes left in the write queue
|
|
356
|
-
// @ts-expect-error private fields
|
|
357
|
-
outboundStream.maxMessageSize = chunkSize - 1
|
|
358
|
-
|
|
359
|
-
// fill the send buffer
|
|
360
|
-
while (true) {
|
|
361
|
-
const sendMore = outboundStream.send(new Uint8Array(chunkSize * 10))
|
|
362
|
-
|
|
363
|
-
if (sendMore === false) {
|
|
364
|
-
expect(outboundStream).to.have.nested.property('writeBuffer.byteLength').that.is.greaterThan(0)
|
|
365
|
-
|
|
366
|
-
break
|
|
367
|
-
}
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
expect(outboundStream.writeStatus).to.equal('writable')
|
|
371
|
-
expect(outboundStream.writableNeedsDrain).to.be.true()
|
|
372
|
-
|
|
373
|
-
// close stream, should be aborted as drain event will not have fired
|
|
374
|
-
await expect(outboundStream.close({
|
|
375
|
-
signal: AbortSignal.timeout(10)
|
|
376
|
-
})).to.eventually.be.rejected
|
|
377
|
-
.with.property('name', 'TimeoutError')
|
|
378
|
-
})
|
|
379
|
-
})
|
|
380
|
-
}
|