1
1
import { expect } from 'aegir/chai'
2
2
import all from 'it-all'
3
3
import { byteStream } from 'it-byte-stream'
4
- import drain from 'it-drain'
5
4
import map from 'it-map'
6
5
import { duplexPair } from 'it-pair/duplex'
7
6
import { pipe } from 'it-pipe'
@@ -12,22 +11,19 @@ import { toString as uint8ArrayToString } from 'uint8arrays/to-string'
12
11
import { isValidTick } from '../is-valid-tick.js'
13
12
import type { TestSetup } from '../index.js'
14
13
import type { Stream , StreamMuxerFactory } from '@libp2p/interface'
15
- import type { Source , Duplex } from 'it-stream-types'
14
+ import type { Source } from 'it-stream-types'
16
15
import type { DeferredPromise } from 'p-defer'
17
16
18
- async function drainAndClose ( stream : Duplex < any > ) : Promise < void > {
19
- await pipe ( [ ] , stream , drain )
20
- }
21
-
22
17
export default ( common : TestSetup < StreamMuxerFactory > ) : void => {
23
18
describe ( 'base' , ( ) => {
24
- it ( 'Open a stream from the dialer' , async ( ) => {
19
+ it ( 'should open a stream from the dialer' , async ( ) => {
25
20
const p = duplexPair < Uint8Array | Uint8ArrayList > ( )
26
- const dialerFactory = await common . setup ( )
27
- const dialer = dialerFactory . createStreamMuxer ( { direction : 'outbound' } )
28
21
const onStreamPromise : DeferredPromise < Stream > = defer ( )
29
22
const onStreamEndPromise : DeferredPromise < Stream > = defer ( )
30
23
24
+ const dialerFactory = await common . setup ( )
25
+ const dialer = dialerFactory . createStreamMuxer ( { direction : 'outbound' } )
26
+
31
27
const listenerFactory = await common . setup ( )
32
28
const listener = listenerFactory . createStreamMuxer ( {
33
29
direction : 'inbound' ,
@@ -42,18 +38,20 @@ export default (common: TestSetup<StreamMuxerFactory>): void => {
42
38
void pipe ( p [ 0 ] , dialer , p [ 0 ] )
43
39
void pipe ( p [ 1 ] , listener , p [ 1 ] )
44
40
45
- const conn = await dialer . newStream ( )
46
- expect ( dialer . streams ) . to . include ( conn )
47
- expect ( isValidTick ( conn . timeline . open ) ) . to . equal ( true )
41
+ const dialerStream = await dialer . newStream ( )
42
+ expect ( dialer . streams ) . to . include ( dialerStream )
43
+ expect ( isValidTick ( dialerStream . timeline . open ) ) . to . equal ( true )
48
44
49
- void drainAndClose ( conn )
45
+ const dialerBytes = byteStream ( dialerStream )
46
+ void dialerBytes . write ( uint8ArrayFromString ( 'hello' ) )
50
47
51
- const stream = await onStreamPromise . promise
52
- expect ( isValidTick ( stream . timeline . open ) ) . to . equal ( true )
48
+ const listenerStream = await onStreamPromise . promise
49
+ expect ( isValidTick ( listenerStream . timeline . open ) ) . to . equal ( true )
53
50
// Make sure the stream is being tracked
54
- expect ( listener . streams ) . to . include ( stream )
51
+ expect ( listener . streams ) . to . include ( listenerStream )
55
52
56
- void drainAndClose ( stream )
53
+ await dialerStream . close ( )
54
+ await listenerStream . close ( )
57
55
58
56
// Make sure stream is closed properly
59
57
const endedStream = await onStreamEndPromise . promise
@@ -66,22 +64,26 @@ export default (common: TestSetup<StreamMuxerFactory>): void => {
66
64
// Make sure the stream is removed from tracking
67
65
expect ( isValidTick ( endedStream . timeline . close ) ) . to . equal ( true )
68
66
69
- await drainAndClose ( dialer )
70
- await drainAndClose ( listener )
67
+ await dialer . close ( )
68
+ await listener . close ( )
71
69
72
70
// ensure we have no streams left
73
71
expect ( dialer . streams ) . to . have . length ( 0 )
74
72
expect ( listener . streams ) . to . have . length ( 0 )
75
73
} )
76
74
77
- it ( 'Open a stream from the listener' , async ( ) => {
75
+ it ( 'should open a stream from the listener' , async ( ) => {
78
76
const p = duplexPair < Uint8Array | Uint8ArrayList > ( )
79
77
const onStreamPromise : DeferredPromise < Stream > = defer ( )
78
+ const onStreamEndPromise : DeferredPromise < Stream > = defer ( )
80
79
const dialerFactory = await common . setup ( )
81
80
const dialer = dialerFactory . createStreamMuxer ( {
82
81
direction : 'outbound' ,
83
82
onIncomingStream : ( stream : Stream ) => {
84
83
onStreamPromise . resolve ( stream )
84
+ } ,
85
+ onStreamEnd : ( stream ) => {
86
+ onStreamEndPromise . resolve ( stream )
85
87
}
86
88
} )
87
89
@@ -91,21 +93,35 @@ export default (common: TestSetup<StreamMuxerFactory>): void => {
91
93
void pipe ( p [ 0 ] , dialer , p [ 0 ] )
92
94
void pipe ( p [ 1 ] , listener , p [ 1 ] )
93
95
94
- const conn = await listener . newStream ( )
96
+ const listenerStream = await listener . newStream ( )
97
+ const listenerBytes = byteStream ( listenerStream )
98
+ void listenerBytes . write ( uint8ArrayFromString ( 'hello' ) )
95
99
96
- void drainAndClose ( conn )
100
+ const dialerStream = await onStreamPromise . promise
97
101
98
- const stream = await onStreamPromise . promise
99
- expect ( isValidTick ( stream . timeline . open ) ) . to . equal ( true )
100
- expect ( listener . streams ) . to . include ( conn )
101
- expect ( isValidTick ( conn . timeline . open ) ) . to . equal ( true )
102
- void drainAndClose ( stream )
102
+ expect ( isValidTick ( dialerStream . timeline . open ) ) . to . equal ( true )
103
+ expect ( listener . streams ) . to . include ( listenerStream )
104
+ expect ( isValidTick ( listenerStream . timeline . open ) ) . to . equal ( true )
105
+
106
+ await dialerStream . close ( )
107
+ await listenerStream . close ( )
108
+
109
+ // Make sure stream is closed properly
110
+ const endedStream = await onStreamEndPromise . promise
111
+ expect ( dialer . streams ) . to . not . include ( endedStream )
112
+
113
+ if ( endedStream . timeline . close == null ) {
114
+ throw new Error ( 'timeline had no close time' )
115
+ }
116
+
117
+ // Make sure the stream is removed from tracking
118
+ expect ( isValidTick ( endedStream . timeline . close ) ) . to . equal ( true )
103
119
104
- await drainAndClose ( dialer )
105
- await drainAndClose ( listener )
120
+ await dialer . close ( )
121
+ await listener . close ( )
106
122
} )
107
123
108
- it ( 'Open a stream on both sides' , async ( ) => {
124
+ it ( 'should open a stream on both sides' , async ( ) => {
109
125
const p = duplexPair < Uint8Array | Uint8ArrayList > ( )
110
126
const onDialerStreamPromise : DeferredPromise < Stream > = defer ( )
111
127
const onListenerStreamPromise : DeferredPromise < Stream > = defer ( )
@@ -132,19 +148,19 @@ export default (common: TestSetup<StreamMuxerFactory>): void => {
132
148
const listenerInitiatorStream = await listener . newStream ( )
133
149
134
150
await Promise . all ( [
135
- drainAndClose ( dialerInitiatorStream ) ,
136
- drainAndClose ( listenerInitiatorStream ) ,
137
- onDialerStreamPromise . promise . then ( async stream => { await drainAndClose ( stream ) } ) ,
138
- onListenerStreamPromise . promise . then ( async stream => { await drainAndClose ( stream ) } )
151
+ dialerInitiatorStream . close ( ) ,
152
+ listenerInitiatorStream . close ( ) ,
153
+ onDialerStreamPromise . promise . then ( async stream => { await stream . close ( ) } ) ,
154
+ onListenerStreamPromise . promise . then ( async stream => { await stream . close ( ) } )
139
155
] )
140
156
141
157
await Promise . all ( [
142
- drainAndClose ( dialer ) ,
143
- drainAndClose ( listener )
158
+ dialer . close ( ) ,
159
+ listener . close ( )
144
160
] )
145
161
} )
146
162
147
- it ( 'Open a stream on one side, write, open a stream on the other side' , async ( ) => {
163
+ it ( 'should open a stream on one side, write, open a stream on the other side' , async ( ) => {
148
164
const toString = ( source : Source < Uint8ArrayList > ) : AsyncGenerator < string > => map ( source , ( u ) => uint8ArrayToString ( u . subarray ( ) ) )
149
165
const p = duplexPair < Uint8Array | Uint8ArrayList > ( )
150
166
const onDialerStreamPromise : DeferredPromise < Stream > = defer ( )
0 commit comments