4
4
using System . Diagnostics ;
5
5
using System . IO ;
6
6
using System . Net . Sockets ;
7
+ using System . Linq ;
7
8
using System . Net . Test . Common ;
8
9
using System . Threading ;
9
10
using System . Threading . Tasks ;
10
11
using Microsoft . DotNet . RemoteExecutor ;
11
12
using Xunit ;
12
13
using Xunit . Abstractions ;
14
+ using TestUtilities ;
13
15
14
16
namespace System . Net . Http . Functional . Tests
15
17
{
@@ -107,7 +109,21 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri =>
107
109
options : new GenericLoopbackOptions ( ) { UseSsl = false } ) ;
108
110
}
109
111
110
- [ OuterLoop ]
112
+ [ Fact ] public async Task ConnectionFailure_AfterInitialRequestCancelled_SecondRequestSucceedsOnNewConnection2 ( ) => await ConnectionFailure_AfterInitialRequestCancelled_SecondRequestSucceedsOnNewConnection ( true ) ;
113
+ [ Fact ] public async Task ConnectionFailure_AfterInitialRequestCancelled_SecondRequestSucceedsOnNewConnection3 ( ) => await ConnectionFailure_AfterInitialRequestCancelled_SecondRequestSucceedsOnNewConnection ( true ) ;
114
+ [ Fact ] public async Task ConnectionFailure_AfterInitialRequestCancelled_SecondRequestSucceedsOnNewConnection4 ( ) => await ConnectionFailure_AfterInitialRequestCancelled_SecondRequestSucceedsOnNewConnection ( true ) ;
115
+ [ Fact ] public async Task ConnectionFailure_AfterInitialRequestCancelled_SecondRequestSucceedsOnNewConnection5 ( ) => await ConnectionFailure_AfterInitialRequestCancelled_SecondRequestSucceedsOnNewConnection ( true ) ;
116
+ [ Fact ] public async Task ConnectionFailure_AfterInitialRequestCancelled_SecondRequestSucceedsOnNewConnection6 ( ) => await ConnectionFailure_AfterInitialRequestCancelled_SecondRequestSucceedsOnNewConnection ( true ) ;
117
+ [ Fact ] public async Task ConnectionFailure_AfterInitialRequestCancelled_SecondRequestSucceedsOnNewConnection7 ( ) => await ConnectionFailure_AfterInitialRequestCancelled_SecondRequestSucceedsOnNewConnection ( true ) ;
118
+ [ Fact ] public async Task ConnectionFailure_AfterInitialRequestCancelled_SecondRequestSucceedsOnNewConnection8 ( ) => await ConnectionFailure_AfterInitialRequestCancelled_SecondRequestSucceedsOnNewConnection ( true ) ;
119
+ [ Fact ] public async Task ConnectionFailure_AfterInitialRequestCancelled_SecondRequestSucceedsOnNewConnection9 ( ) => await ConnectionFailure_AfterInitialRequestCancelled_SecondRequestSucceedsOnNewConnection ( true ) ;
120
+ [ Fact ] public async Task ConnectionFailure_AfterInitialRequestCancelled_SecondRequestSucceedsOnNewConnection10 ( ) => await ConnectionFailure_AfterInitialRequestCancelled_SecondRequestSucceedsOnNewConnection ( true ) ;
121
+ [ Fact ] public async Task ConnectionFailure_AfterInitialRequestCancelled_SecondRequestSucceedsOnNewConnection11 ( ) => await ConnectionFailure_AfterInitialRequestCancelled_SecondRequestSucceedsOnNewConnection ( true ) ;
122
+ [ Fact ] public async Task ConnectionFailure_AfterInitialRequestCancelled_SecondRequestSucceedsOnNewConnection12 ( ) => await ConnectionFailure_AfterInitialRequestCancelled_SecondRequestSucceedsOnNewConnection ( true ) ;
123
+ [ Fact ] public async Task ConnectionFailure_AfterInitialRequestCancelled_SecondRequestSucceedsOnNewConnection13 ( ) => await ConnectionFailure_AfterInitialRequestCancelled_SecondRequestSucceedsOnNewConnection ( true ) ;
124
+ [ Fact ] public async Task ConnectionFailure_AfterInitialRequestCancelled_SecondRequestSucceedsOnNewConnection14 ( ) => await ConnectionFailure_AfterInitialRequestCancelled_SecondRequestSucceedsOnNewConnection ( true ) ;
125
+ [ Fact ] public async Task ConnectionFailure_AfterInitialRequestCancelled_SecondRequestSucceedsOnNewConnection15 ( ) => await ConnectionFailure_AfterInitialRequestCancelled_SecondRequestSucceedsOnNewConnection ( true ) ;
126
+
111
127
[ Theory ]
112
128
[ InlineData ( true ) ]
113
129
[ InlineData ( false ) ]
@@ -125,18 +141,19 @@ public async Task ConnectionFailure_AfterInitialRequestCancelled_SecondRequestSu
125
141
return ;
126
142
}
127
143
144
+ using var listener = new TestEventListener ( _output , TestEventListener . NetworkingEvents ) ;
145
+
128
146
await LoopbackServerFactory . CreateClientAndServerAsync ( async uri =>
129
147
{
130
148
int connectCount = 0 ;
131
149
132
- TaskCompletionSource tcsFirstConnectionInitiated = new TaskCompletionSource ( TaskCreationOptions . RunContinuationsAsynchronously ) ;
133
- TaskCompletionSource tcsFirstRequestCanceled = new TaskCompletionSource ( TaskCreationOptions . RunContinuationsAsynchronously ) ;
150
+ var tcsFirstConnectionInitiated = new TaskCompletionSource ( TaskCreationOptions . RunContinuationsAsynchronously ) ;
151
+ var tcsFirstRequestCanceled = new TaskCompletionSource ( TaskCreationOptions . RunContinuationsAsynchronously ) ;
134
152
135
- using ( var handler = CreateHttpClientHandler ( allowAllCertificates : true ) )
136
- using ( var client = CreateHttpClient ( handler ) )
153
+ using ( HttpClientHandler handler = CreateHttpClientHandler ( ) )
154
+ using ( HttpClient client = CreateHttpClient ( handler ) )
137
155
{
138
- var socketsHandler = GetUnderlyingSocketsHttpHandler ( handler ) ;
139
- socketsHandler . ConnectCallback = async ( context , token ) =>
156
+ GetUnderlyingSocketsHttpHandler ( handler ) . ConnectCallback = async ( context , token ) =>
140
157
{
141
158
// Note we force serialization of connection creation by waiting on tcsFirstConnectionInitiated below,
142
159
// so we don't need to worry about concurrent access to connectCount.
@@ -145,6 +162,8 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri =>
145
162
146
163
Assert . True ( connectCount <= 2 ) ;
147
164
165
+ _output . WriteLine ( $ "Connection count { connectCount } ") ;
166
+
148
167
if ( isFirstConnection )
149
168
{
150
169
tcsFirstConnectionInitiated . SetResult ( ) ;
@@ -157,6 +176,8 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri =>
157
176
// Wait until first request is cancelled and has completed
158
177
await tcsFirstRequestCanceled . Task ;
159
178
179
+ _output . WriteLine ( $ "After tcsFirstRequestCanceled { isFirstConnection } ") ;
180
+
160
181
if ( isFirstConnection )
161
182
{
162
183
// Fail the first connection attempt
@@ -170,27 +191,34 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri =>
170
191
} ;
171
192
172
193
using CancellationTokenSource cts = new CancellationTokenSource ( ) ;
173
- Task < HttpResponseMessage > t1 = client . SendAsync ( new HttpRequestMessage ( HttpMethod . Get , uri ) { Version = UseVersion , VersionPolicy = HttpVersionPolicy . RequestVersionExact } , cts . Token ) ;
194
+ Task < HttpResponseMessage > t1 = client . SendAsync ( CreateRequest ( HttpMethod . Get , uri , UseVersion , exactVersion : true ) , cts . Token ) ;
195
+ _output . WriteLine ( "t1" ) ;
174
196
175
197
// Wait for the connection attempt to be initiated before we send the second request, to avoid races in connection creation
176
- await tcsFirstConnectionInitiated . Task ;
177
- Task < HttpResponseMessage > t2 = client . SendAsync ( new HttpRequestMessage ( HttpMethod . Get , uri ) { Version = UseVersion , VersionPolicy = HttpVersionPolicy . RequestVersionExact } , default ) ;
198
+ await tcsFirstConnectionInitiated . Task . WaitAsync ( TestHelper . PassingTestTimeout ) ;
199
+ Task < HttpResponseMessage > t2 = client . SendAsync ( CreateRequest ( HttpMethod . Get , uri , UseVersion , exactVersion : true ) , CancellationToken . None ) ;
200
+ _output . WriteLine ( "t2" ) ;
178
201
179
202
// Cancel the first message and wait for it to complete
180
203
cts . Cancel ( ) ;
181
- await Assert . ThrowsAnyAsync < OperationCanceledException > ( ( ) => t1 ) ;
204
+ await Assert . ThrowsAnyAsync < OperationCanceledException > ( ( ) => t1 ) . WaitAsync ( TestHelper . PassingTestTimeout ) ;
205
+ _output . WriteLine ( "ThrowsAnyAsync" ) ;
182
206
183
207
// Signal connections to proceed
184
208
tcsFirstRequestCanceled . SetResult ( ) ;
185
209
186
210
// Second request should succeed, even though the first connection failed
187
- HttpResponseMessage resp2 = await t2 ;
211
+ HttpResponseMessage resp2 = await t2 . WaitAsync ( TestHelper . PassingTestTimeout ) ;
212
+ _output . WriteLine ( "resp2" ) ;
188
213
Assert . Equal ( HttpStatusCode . OK , resp2 . StatusCode ) ;
189
- Assert . Equal ( "Hello world" , await resp2 . Content . ReadAsStringAsync ( ) ) ;
214
+ Assert . Equal ( "Hello world" , await resp2 . Content . ReadAsStringAsync ( ) . WaitAsync ( TestHelper . PassingTestTimeout ) ) ;
215
+
216
+ Assert . True ( connectCount == 2 ) ;
190
217
}
191
218
} , async server =>
192
219
{
193
- await server . AcceptConnectionSendResponseAndCloseAsync ( content : "Hello world" ) ;
220
+ await server . HandleRequestAsync ( content : "Hello world" ) . WaitAsync ( TestHelper . PassingTestTimeout ) ;
221
+ _output . WriteLine ( "Server done" ) ;
194
222
} ,
195
223
options : new GenericLoopbackOptions ( ) { UseSsl = useSsl } ) ;
196
224
}
0 commit comments