@@ -114,6 +114,61 @@ describe('Connection Manager', () => {
114
114
expect ( lowestSpy ) . to . have . property ( 'callCount' , 1 )
115
115
} )
116
116
117
+ it ( 'should close shortest-lived connection if the tag values are equal' , async ( ) => {
118
+ const max = 5
119
+ libp2p = await createNode ( {
120
+ config : createBaseOptions ( {
121
+ connectionManager : {
122
+ maxConnections : max ,
123
+ minConnections : 2
124
+ }
125
+ } ) ,
126
+ started : false
127
+ } )
128
+
129
+ await libp2p . start ( )
130
+
131
+ const connectionManager = libp2p . connectionManager as DefaultConnectionManager
132
+ const connectionManagerMaybeDisconnectOneSpy = sinon . spy ( connectionManager , '_pruneConnections' )
133
+ const spies = new Map < string , sinon . SinonSpy < [ ] , Promise < void > > > ( )
134
+
135
+ const createConnection = async ( value : number , open : number = Date . now ( ) , peerTag : string = 'test-tag' ) => {
136
+ // #TODO: Mock the connection timeline to simulate an older connection
137
+ const connection = mockConnection ( mockMultiaddrConnection ( { ...mockDuplex ( ) , timeline : { open } } , await createEd25519PeerId ( ) ) )
138
+ const spy = sinon . spy ( connection , 'close' )
139
+
140
+ // The lowest tag value will have the longest connection
141
+ spies . set ( peerTag , spy )
142
+ await libp2p . peerStore . tagPeer ( connection . remotePeer , peerTag , {
143
+ value
144
+ } )
145
+
146
+ await connectionManager . _onConnect ( new CustomEvent ( 'connection' , { detail : connection } ) )
147
+ }
148
+
149
+ // Create one short of enough connections to iniate pruning
150
+ for ( let i = 1 ; i < max ; i ++ ) {
151
+ const value = i * 10
152
+ await createConnection ( value )
153
+ }
154
+
155
+ const value = 0 * 10
156
+ // Add a connection with the lowest tag value BUT the longest lived connection
157
+ await createConnection ( value , 18000 , 'longest' )
158
+ // Add one more connection with the lowest tag value BUT the shortest-lived connection
159
+ await createConnection ( value , Date . now ( ) , 'shortest' )
160
+
161
+ // get the lowest tagged value, but this would be also the longest lived connection
162
+ const longestLivedWithLowestTagSpy = spies . get ( 'longest' )
163
+
164
+ // Get lowest tagged connection but with a shorter-lived connection
165
+ const shortestLivedWithLowestTagSpy = spies . get ( 'shortest' )
166
+
167
+ expect ( connectionManagerMaybeDisconnectOneSpy . callCount ) . to . equal ( 1 )
168
+ expect ( longestLivedWithLowestTagSpy ) . to . have . property ( 'callCount' , 0 )
169
+ expect ( shortestLivedWithLowestTagSpy ) . to . have . property ( 'callCount' , 1 )
170
+ } )
171
+
117
172
it ( 'should close connection when the maximum has been reached even without tags' , async ( ) => {
118
173
const max = 5
119
174
libp2p = await createNode ( {
0 commit comments