OLD | NEW |
1 /* | 1 /* |
2 Copyright 2013 Google Inc | 2 Copyright 2013 Google Inc |
3 | 3 |
4 Licensed under the Apache License, Version 2.0 (the "License"); | 4 Licensed under the Apache License, Version 2.0 (the "License"); |
5 you may not use this file except in compliance with the License. | 5 you may not use this file except in compliance with the License. |
6 You may obtain a copy of the License at | 6 You may obtain a copy of the License at |
7 | 7 |
8 http://www.apache.org/licenses/LICENSE-2.0 | 8 http://www.apache.org/licenses/LICENSE-2.0 |
9 | 9 |
10 Unless required by applicable law or agreed to in writing, software | 10 Unless required by applicable law or agreed to in writing, software |
(...skipping 15 matching lines...) Expand all Loading... |
26 using System.Threading.Tasks; | 26 using System.Threading.Tasks; |
27 | 27 |
28 using NUnit.Framework; | 28 using NUnit.Framework; |
29 | 29 |
30 using Google.Apis.Http; | 30 using Google.Apis.Http; |
31 using Google.Apis.Util; | 31 using Google.Apis.Util; |
32 using Google.Apis.Testing; | 32 using Google.Apis.Testing; |
33 | 33 |
34 namespace Google.Apis.Tests.Apis.Http | 34 namespace Google.Apis.Tests.Apis.Http |
35 { | 35 { |
36 /// <summary> Tests for <see cref="Google.Apis.Http.ConfigurableMessageHandl
er"/>. </summary> | 36 /// <summary>Tests for <see cref="Google.Apis.Http.ConfigurableMessageHandle
r"/>.</summary> |
37 [TestFixture] | 37 [TestFixture] |
38 public class ConfigurableMessageHandlerTest | 38 public class ConfigurableMessageHandlerTest |
39 { | 39 { |
40 #region Handlers | 40 #region Handlers |
41 | 41 |
42 /// <summary> Unsuccessful handler which always returns <c>true</c>. </s
ummary> | 42 /// <summary>Unsuccessful handler which always returns <c>true</c>.</sum
mary> |
43 private class TrueUnsuccessfulResponseHandler : IHttpUnsuccessfulRespons
eHandler | 43 private class TrueUnsuccessfulResponseHandler : IHttpUnsuccessfulRespons
eHandler |
44 { | 44 { |
45 public bool HandleResponse(HandleUnsuccessfulResponseArgs args) | 45 public Task<bool> HandleResponseAsync(HandleUnsuccessfulResponseArgs
args) |
46 { | 46 { |
47 return true; | 47 TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>(
); |
| 48 tcs.SetResult(true); |
| 49 return tcs.Task; |
48 } | 50 } |
49 } | 51 } |
50 | 52 |
51 /// <summary> Message handler which returns a new successful (and empty)
response. </summary> | 53 /// <summary>Message handler which returns a new successful (and empty)
response.</summary> |
52 private class MockMessageHandler : HttpMessageHandler | 54 private class MockMessageHandler : HttpMessageHandler |
53 { | 55 { |
54 protected override Task<HttpResponseMessage> SendAsync(HttpRequestMe
ssage request, | 56 protected override Task<HttpResponseMessage> SendAsync(HttpRequestMe
ssage request, |
55 CancellationToken cancellationToken) | 57 CancellationToken cancellationToken) |
56 { | 58 { |
57 TaskCompletionSource<HttpResponseMessage> tcs = new TaskCompleti
onSource<HttpResponseMessage>(); | 59 TaskCompletionSource<HttpResponseMessage> tcs = new TaskCompleti
onSource<HttpResponseMessage>(); |
58 tcs.SetResult(new HttpResponseMessage()); | 60 tcs.SetResult(new HttpResponseMessage()); |
59 return tcs.Task; | 61 return tcs.Task; |
60 } | 62 } |
61 } | 63 } |
62 | 64 |
63 #endregion | 65 #endregion |
64 | 66 |
65 #region Redirect | 67 #region Redirect |
66 | 68 |
67 /// <summary> Redirect message handler which return redirect response. <
/summary> | 69 /// <summary>Redirect message handler which return redirect response.</s
ummary> |
68 private class RedirectMessageHandler : CountableMessageHandler | 70 private class RedirectMessageHandler : CountableMessageHandler |
69 { | 71 { |
70 /// <summary> Gets or sets the redirect location Uri string. </summa
ry> | 72 /// <summary>Gets or sets the redirect location Uri string.</summary
> |
71 private string Location { get; set; } | 73 private string Location { get; set; } |
72 | 74 |
73 /// <summary> Constructs a new redirect message handler with the giv
en location. </summary> | 75 /// <summary>Constructs a new redirect message handler with the give
n location.</summary> |
74 public RedirectMessageHandler(string location) | 76 public RedirectMessageHandler(string location) |
75 { | 77 { |
76 Location = location; | 78 Location = location; |
77 } | 79 } |
78 | 80 |
79 protected override System.Threading.Tasks.Task<HttpResponseMessage>
SendAsyncCore( | 81 protected override System.Threading.Tasks.Task<HttpResponseMessage>
SendAsyncCore( |
80 HttpRequestMessage request, CancellationToken cancellationToken) | 82 HttpRequestMessage request, CancellationToken cancellationToken) |
81 { | 83 { |
82 TaskCompletionSource<HttpResponseMessage> tcs = new TaskCompleti
onSource<HttpResponseMessage>(); | 84 TaskCompletionSource<HttpResponseMessage> tcs = new TaskCompleti
onSource<HttpResponseMessage>(); |
83 var response = new HttpResponseMessage(); | 85 var response = new HttpResponseMessage(); |
(...skipping 19 matching lines...) Expand all Loading... |
103 Assert.That(request.Headers.IfNoneMatch.Count == 0); | 105 Assert.That(request.Headers.IfNoneMatch.Count == 0); |
104 Assert.IsNull(request.Headers.IfModifiedSince); | 106 Assert.IsNull(request.Headers.IfModifiedSince); |
105 Assert.IsNull(request.Headers.IfUnmodifiedSince); | 107 Assert.IsNull(request.Headers.IfUnmodifiedSince); |
106 } | 108 } |
107 | 109 |
108 tcs.SetResult(response); | 110 tcs.SetResult(response); |
109 return tcs.Task; | 111 return tcs.Task; |
110 } | 112 } |
111 } | 113 } |
112 | 114 |
113 /// <summary> Tests that the message handler handles redirect messages s
uccessfully. </summary> | 115 /// <summary>Tests that the message handler handles redirect messages su
ccessfully.</summary> |
114 [Test] | 116 [Test] |
115 public void SendAsync_Redirect() | 117 public void SendAsync_Redirect() |
116 { | 118 { |
117 var location = "https://google.com"; | 119 var location = "https://google.com"; |
118 var redirectHandler = new RedirectMessageHandler(location); | 120 var redirectHandler = new RedirectMessageHandler(location); |
119 var configurableHanlder = new ConfigurableMessageHandler(redirectHan
dler) | 121 var configurableHanlder = new ConfigurableMessageHandler(redirectHan
dler) |
120 { | 122 { |
121 NumTries = 8 | 123 NumTries = 8 |
122 }; | 124 }; |
123 using (var client = new HttpClient(configurableHanlder)) | 125 using (var client = new HttpClient(configurableHanlder)) |
124 { | 126 { |
125 var request = new HttpRequestMessage(HttpMethod.Get, location); | 127 var request = new HttpRequestMessage(HttpMethod.Get, location); |
126 request.Headers.IfModifiedSince = new DateTimeOffset(DateTime.No
w); | 128 request.Headers.IfModifiedSince = new DateTimeOffset(DateTime.No
w); |
127 request.Headers.IfUnmodifiedSince = new DateTimeOffset(DateTime.
Now); | 129 request.Headers.IfUnmodifiedSince = new DateTimeOffset(DateTime.
Now); |
128 request.Headers.IfMatch.Add(new EntityTagHeaderValue("\"a\"")); | 130 request.Headers.IfMatch.Add(new EntityTagHeaderValue("\"a\"")); |
129 request.Headers.IfNoneMatch.Add(new EntityTagHeaderValue("\"b\""
)); | 131 request.Headers.IfNoneMatch.Add(new EntityTagHeaderValue("\"b\""
)); |
130 | 132 |
131 HttpResponseMessage response = client.SendAsync(request).Result; | 133 HttpResponseMessage response = client.SendAsync(request).Result; |
132 | 134 |
133 Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.Redir
ect)); | 135 Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.Redir
ect)); |
134 Assert.That(response.Headers.Location, Is.EqualTo(new Uri(locati
on + configurableHanlder.NumTries))); | 136 Assert.That(response.Headers.Location, Is.EqualTo(new Uri(locati
on + configurableHanlder.NumTries))); |
135 Assert.That(redirectHandler.Calls, Is.EqualTo(configurableHanlde
r.NumTries)); | 137 Assert.That(redirectHandler.Calls, Is.EqualTo(configurableHanlde
r.NumTries)); |
136 } | 138 } |
137 } | 139 } |
138 | 140 |
139 /// <summary> | 141 /// <summary> |
140 /// Tests that the message handler doesn't handle redirect messages when
follow redirect is <c>false</c>.· | 142 /// Tests that the message handler doesn't handle redirect messages when
follow redirect is <c>false</c>.· |
141 /// </summary> | 143 /// </summary> |
142 [Test] | 144 [Test] |
143 public void SendAsync_Redirect_FollowRedirectFalse() | 145 public void SendAsync_Redirect_FollowRedirectFalse() |
144 { | 146 { |
145 const int tries = 12; | 147 const int tries = 12; |
146 var location = "https://google.com"; | 148 var location = "https://google.com"; |
147 var redirectHandler = new RedirectMessageHandler(location); | 149 var redirectHandler = new RedirectMessageHandler(location); |
148 var configurableHanlder = new ConfigurableMessageHandler(redirectHan
dler) | 150 var configurableHanlder = new ConfigurableMessageHandler(redirectHan
dler) |
149 { | 151 { |
(...skipping 14 matching lines...) Expand all Loading... |
164 Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.Redir
ect)); | 166 Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.Redir
ect)); |
165 Assert.That(response.Headers.Location, Is.EqualTo(new Uri(locati
on + 1))); | 167 Assert.That(response.Headers.Location, Is.EqualTo(new Uri(locati
on + 1))); |
166 Assert.That(redirectHandler.Calls, Is.EqualTo(1)); | 168 Assert.That(redirectHandler.Calls, Is.EqualTo(1)); |
167 } | 169 } |
168 } | 170 } |
169 | 171 |
170 #endregion | 172 #endregion |
171 | 173 |
172 #region Execute interceptor | 174 #region Execute interceptor |
173 | 175 |
174 /// <summary> | 176 /// <summary> |
175 /// Mock interceptor handler which verifies that an interceptor is being
called on a request.· | 177 /// Mock interceptor handler which verifies that an interceptor is being
called on a request.· |
176 /// </summary> | 178 /// </summary> |
177 private class InterceptorMessageHandler : CountableMessageHandler | 179 private class InterceptorMessageHandler : CountableMessageHandler |
178 { | 180 { |
179 /// <summary> Gets or sets an injected response message which will b
e returned on send. </summary> | 181 /// <summary>Gets or sets an injected response message which will be
returned on send.</summary> |
180 public HttpResponseMessage InjectedResponseMessage { get; set; } | 182 public HttpResponseMessage InjectedResponseMessage { get; set; } |
181 | 183 |
182 const string InjectedHeader = "Some-Header"; | 184 const string InjectedHeader = "Some-Header"; |
183 const string InjectedValue = "123"; | 185 const string InjectedValue = "123"; |
184 | 186 |
185 protected override Task<HttpResponseMessage> SendAsyncCore(HttpReque
stMessage request, | 187 protected override Task<HttpResponseMessage> SendAsyncCore(HttpReque
stMessage request, |
186 CancellationToken cancellationToken) | 188 CancellationToken cancellationToken) |
187 { | 189 { |
188 Assert.That(request.Headers.GetValues(InjectedHeader).First(), I
s.EqualTo(InjectedValue)); | 190 Assert.That(request.Headers.GetValues(InjectedHeader).First(), I
s.EqualTo(InjectedValue)); |
189 | 191 |
190 TaskCompletionSource<HttpResponseMessage> tcs = new TaskCompleti
onSource<HttpResponseMessage>(); | 192 TaskCompletionSource<HttpResponseMessage> tcs = new TaskCompleti
onSource<HttpResponseMessage>(); |
191 tcs.SetResult(InjectedResponseMessage); | 193 tcs.SetResult(InjectedResponseMessage); |
192 return tcs.Task; | 194 return tcs.Task; |
193 } | 195 } |
194 | 196 |
195 /// <summary> A mock interceptor which inject a header to a request.
</summary> | 197 /// <summary>A mock interceptor which inject a header to a request.<
/summary> |
196 internal class Interceptor : IHttpExecuteInterceptor | 198 internal class Interceptor : IHttpExecuteInterceptor |
197 { | 199 { |
198 public int Calls { get; set; } | 200 public int Calls { get; set; } |
199 | 201 |
200 public void Intercept(HttpRequestMessage request) | 202 public Task InterceptAsync(HttpRequestMessage request, Cancellat
ionToken token) |
201 { | 203 { |
202 ++Calls; | 204 ++Calls; |
203 request.Headers.Add(InjectedHeader, InjectedValue); | 205 request.Headers.Add(InjectedHeader, InjectedValue); |
| 206 return TaskEx.Delay(0); |
204 } | 207 } |
205 } | 208 } |
206 } | 209 } |
207 | 210 |
208 /// <summary> Tests that execute interceptor is called on successful res
ponse. </summary> | 211 /// <summary>Tests that execute interceptor is called on successful resp
onse.</summary> |
209 [Test] | 212 [Test] |
210 public void SendAsync_ExecuteInterceptor() | 213 public void SendAsync_ExecuteInterceptor() |
211 { | 214 { |
212 SubtestSendAsyncExecuteInterceptor(HttpStatusCode.OK); | 215 SubtestSendAsyncExecuteInterceptor(HttpStatusCode.OK); |
213 } | 216 } |
214 | 217 |
215 /// <summary> | 218 /// <summary> |
216 /// Tests that execute interceptor is called once on unsuccessful reques
t. In this test unsuccessful response· | 219 /// Tests that execute interceptor is called once on unsuccessful reques
t. In this test unsuccessful response· |
217 /// handler isn't plugged to the handler.· | 220 /// handler isn't plugged to the handler.· |
218 /// </summary> | 221 /// </summary> |
219 [Test] | 222 [Test] |
220 public void SendAsync_ExecuteInterceptor_AbnormalResponse() | 223 public void SendAsync_ExecuteInterceptor_AbnormalResponse() |
221 { | 224 { |
222 SubtestSendAsyncExecuteInterceptor(HttpStatusCode.BadRequest); | 225 SubtestSendAsyncExecuteInterceptor(HttpStatusCode.BadRequest); |
223 } | 226 } |
224 | 227 |
225 /// <summary> Tests that execute interceptor is called. </summary> | 228 /// <summary>Tests that execute interceptor is called.</summary> |
226 private void SubtestSendAsyncExecuteInterceptor(HttpStatusCode code) | 229 private void SubtestSendAsyncExecuteInterceptor(HttpStatusCode code) |
227 { | 230 { |
228 var handler = new InterceptorMessageHandler(); | 231 var handler = new InterceptorMessageHandler(); |
229 handler.InjectedResponseMessage = new HttpResponseMessage() | 232 handler.InjectedResponseMessage = new HttpResponseMessage() |
230 { | 233 { |
231 StatusCode = code | 234 StatusCode = code |
232 }; | 235 }; |
233 | 236 |
234 var configurableHanlder = new ConfigurableMessageHandler(handler); | 237 var configurableHanlder = new ConfigurableMessageHandler(handler); |
235 var interceptor = new InterceptorMessageHandler.Interceptor(); | 238 var interceptor = new InterceptorMessageHandler.Interceptor(); |
236 configurableHanlder.ExecuteInterceptors.Add(interceptor); | 239 configurableHanlder.ExecuteInterceptors.Add(interceptor); |
237 | 240 |
238 using (var client = new HttpClient(configurableHanlder)) | 241 using (var client = new HttpClient(configurableHanlder)) |
239 { | 242 { |
240 var request = new HttpRequestMessage(HttpMethod.Get, "https://te
st-execute-interceptor"); | 243 var request = new HttpRequestMessage(HttpMethod.Get, "https://te
st-execute-interceptor"); |
241 | 244 |
242 HttpResponseMessage response = client.SendAsync(request).Result; | 245 HttpResponseMessage response = client.SendAsync(request).Result; |
243 Assert.That(interceptor.Calls, Is.EqualTo(1)); | 246 Assert.That(interceptor.Calls, Is.EqualTo(1)); |
244 Assert.That(handler.Calls, Is.EqualTo(1)); | 247 Assert.That(handler.Calls, Is.EqualTo(1)); |
245 } | 248 } |
246 } | 249 } |
247 | 250 |
248 /// <summary> | 251 /// <summary> |
249 /// Tests that execute interceptor is called for each request. In this c
ase an unsuccessful response handler is· | 252 /// Tests that execute interceptor is called for each request. In this c
ase an unsuccessful response handler is· |
250 /// plugged to the handler | 253 /// plugged to the handler |
251 /// </summary> | 254 /// </summary> |
252 [Test] | 255 [Test] |
253 public void SendAsync_ExecuteInterceptor_AbnormalResponse_UnsuccessfulRe
sponseHandler() | 256 public void SendAsync_ExecuteInterceptor_AbnormalResponse_UnsuccessfulRe
sponseHandler() |
254 { | 257 { |
255 var handler = new InterceptorMessageHandler(); | 258 var handler = new InterceptorMessageHandler(); |
256 handler.InjectedResponseMessage = new HttpResponseMessage() | 259 handler.InjectedResponseMessage = new HttpResponseMessage() |
257 { | 260 { |
258 StatusCode = HttpStatusCode.ServiceUnavailable | 261 StatusCode = HttpStatusCode.ServiceUnavailable |
(...skipping 11 matching lines...) Expand all Loading... |
270 HttpResponseMessage response = client.SendAsync(request).Result; | 273 HttpResponseMessage response = client.SendAsync(request).Result; |
271 Assert.That(interceptor.Calls, Is.EqualTo(configurableHanlder.Nu
mTries)); | 274 Assert.That(interceptor.Calls, Is.EqualTo(configurableHanlder.Nu
mTries)); |
272 Assert.That(handler.Calls, Is.EqualTo(configurableHanlder.NumTri
es)); | 275 Assert.That(handler.Calls, Is.EqualTo(configurableHanlder.NumTri
es)); |
273 } | 276 } |
274 } | 277 } |
275 | 278 |
276 #endregion | 279 #endregion |
277 | 280 |
278 #region Unsuccessful reponse handler | 281 #region Unsuccessful reponse handler |
279 | 282 |
280 /// <summary> | 283 /// <summary> |
281 /// Mock unsuccessful response handler which verifies that unsuccessful
response handler is being called. | 284 /// Mock unsuccessful response handler which verifies that unsuccessful
response handler is being called. |
282 /// </summary> | 285 /// </summary> |
283 private class UnsuccessfulResponseMessageHandler : CountableMessageHandl
er | 286 private class UnsuccessfulResponseMessageHandler : CountableMessageHandl
er |
284 { | 287 { |
285 /// <summary> Gets or sets the status code to return on the response
.</summary> | 288 /// <summary>Gets or sets the status code to return on the response.
</summary> |
286 public HttpStatusCode ResponseStatusCode { get; set; } | 289 public HttpStatusCode ResponseStatusCode { get; set; } |
287 | 290 |
288 /// <summary> Gets or sets the cancellation token source.</summary> | 291 /// <summary>Gets or sets the cancellation token source.</summary> |
289 public CancellationTokenSource CancellationTokenSource { get; set; } | 292 public CancellationTokenSource CancellationTokenSource { get; set; } |
290 | 293 |
291 /// <summary> | 294 /// <summary> |
292 /// Gets or sets the request number to invoke the Cancel method on <
see cref="CancellationTokenSource"/>. | 295 /// Gets or sets the request number to invoke the Cancel method on <
see cref="CancellationTokenSource"/>. |
293 /// </summary> | 296 /// </summary> |
294 public int CancelRequestNum { get; set; } | 297 public int CancelRequestNum { get; set; } |
295 | 298 |
296 protected override Task<HttpResponseMessage> SendAsyncCore(HttpReque
stMessage request, | 299 protected override Task<HttpResponseMessage> SendAsyncCore(HttpReque
stMessage request, |
297 CancellationToken cancellationToken) | 300 CancellationToken cancellationToken) |
298 { | 301 { |
299 if (Calls == CancelRequestNum) | 302 if (Calls == CancelRequestNum) |
300 { | 303 { |
301 CancellationTokenSource.Cancel(); | 304 CancellationTokenSource.Cancel(); |
302 } | 305 } |
303 | 306 |
304 TaskCompletionSource<HttpResponseMessage> tcs = new TaskCompleti
onSource<HttpResponseMessage>(); | 307 TaskCompletionSource<HttpResponseMessage> tcs = new TaskCompleti
onSource<HttpResponseMessage>(); |
305 tcs.SetResult(new HttpResponseMessage { StatusCode = ResponseSta
tusCode }); | 308 tcs.SetResult(new HttpResponseMessage { StatusCode = ResponseSta
tusCode }); |
306 return tcs.Task; | 309 return tcs.Task; |
307 } | 310 } |
308 | 311 |
309 /// <summary> Unsuccessful response handler which "handles" only ser
vice unavailable responses. </summary> | 312 /// <summary>Unsuccessful response handler which "handles" only serv
ice unavailable responses.</summary> |
310 internal class ServiceUnavailableResponseHandler : IHttpUnsuccessful
ResponseHandler | 313 internal class ServiceUnavailableResponseHandler : IHttpUnsuccessful
ResponseHandler |
311 { | 314 { |
312 public int Calls { get; set; } | 315 public int Calls { get; set; } |
313 | 316 |
314 public bool HandleResponse(HandleUnsuccessfulResponseArgs args) | 317 public Task<bool> HandleResponseAsync(HandleUnsuccessfulResponse
Args args) |
315 { | 318 { |
316 ++Calls; | 319 ++Calls; |
317 return args.Response.StatusCode.Equals(HttpStatusCode.Servic
eUnavailable); | 320 TaskCompletionSource<bool> tcs = new TaskCompletionSource<bo
ol>(); |
| 321 tcs.SetResult(args.Response.StatusCode.Equals(HttpStatusCode
.ServiceUnavailable)); |
| 322 return tcs.Task; |
318 } | 323 } |
319 } | 324 } |
320 } | 325 } |
321 | 326 |
322 /// <summary> Test helper for testing unsuccessful response handlers. </
summary> | 327 /// <summary>Test helper for testing unsuccessful response handlers.</su
mmary> |
323 private void SubtestSendAsyncUnsuccessfulReponseHanlder(HttpStatusCode c
ode) | 328 private void SubtestSendAsyncUnsuccessfulReponseHanlder(HttpStatusCode c
ode) |
324 { | 329 { |
325 var handler = new UnsuccessfulResponseMessageHandler { ResponseStatu
sCode = code }; | 330 var handler = new UnsuccessfulResponseMessageHandler { ResponseStatu
sCode = code }; |
326 | 331 |
327 var configurableHanlder = new ConfigurableMessageHandler(handler); | 332 var configurableHanlder = new ConfigurableMessageHandler(handler); |
328 var unsuccessfulHandler = new UnsuccessfulResponseMessageHandler.Ser
viceUnavailableResponseHandler(); | 333 var unsuccessfulHandler = new UnsuccessfulResponseMessageHandler.Ser
viceUnavailableResponseHandler(); |
329 configurableHanlder.UnsuccessfulResponseHandlers.Add(unsuccessfulHan
dler); | 334 configurableHanlder.UnsuccessfulResponseHandlers.Add(unsuccessfulHan
dler); |
330 | 335 |
331 using (var client = new HttpClient(configurableHanlder)) | 336 using (var client = new HttpClient(configurableHanlder)) |
332 { | 337 { |
(...skipping 11 matching lines...) Expand all Loading... |
344 } | 349 } |
345 else | 350 else |
346 { | 351 { |
347 // if status is OK, there isn't any call to unsuccessful res
ponse handler | 352 // if status is OK, there isn't any call to unsuccessful res
ponse handler |
348 Assert.That(unsuccessfulHandler.Calls, Is.EqualTo(code != Ht
tpStatusCode.OK ? 1 : 0)); | 353 Assert.That(unsuccessfulHandler.Calls, Is.EqualTo(code != Ht
tpStatusCode.OK ? 1 : 0)); |
349 Assert.That(handler.Calls, Is.EqualTo(1)); | 354 Assert.That(handler.Calls, Is.EqualTo(1)); |
350 } | 355 } |
351 } | 356 } |
352 } | 357 } |
353 | 358 |
354 /// <summary> Tests that unsuccessful response handler isn't called when
the response is successful. </summary> | 359 /// <summary>Tests that unsuccessful response handler isn't called when
the response is successful.</summary> |
355 [Test] | 360 [Test] |
356 public void SendAsync_UnsuccessfulReponseHanlder_SuccessfulReponse() | 361 public void SendAsync_UnsuccessfulReponseHanlder_SuccessfulReponse() |
357 { | 362 { |
358 SubtestSendAsyncUnsuccessfulReponseHanlder(HttpStatusCode.OK); | 363 SubtestSendAsyncUnsuccessfulReponseHanlder(HttpStatusCode.OK); |
359 } | 364 } |
360 | 365 |
361 /// <summary> | 366 /// <summary> |
362 /// Tests that unsuccessful response handler is called when the response
is unsuccessful, but the handler can't | 367 /// Tests that unsuccessful response handler is called when the response
is unsuccessful, but the handler can't |
363 /// handle the abnormal response (e.g. different status code). | 368 /// handle the abnormal response (e.g. different status code). |
364 /// </summary> | 369 /// </summary> |
365 [Test] | 370 [Test] |
366 public void SendAsync_UnsuccessfulReponseHanlder_AbnormalResponse_Differ
entStatusCode() | 371 public void SendAsync_UnsuccessfulReponseHanlder_AbnormalResponse_Differ
entStatusCode() |
367 { | 372 { |
368 SubtestSendAsyncUnsuccessfulReponseHanlder(HttpStatusCode.BadGateway
); | 373 SubtestSendAsyncUnsuccessfulReponseHanlder(HttpStatusCode.BadGateway
); |
369 } | 374 } |
370 | 375 |
371 /// <summary> | 376 /// <summary> |
372 /// Tests that unsuccessful response handler is called when the response
is unsuccessful and the handler can· | 377 /// Tests that unsuccessful response handler is called when the response
is unsuccessful and the handler can· |
373 /// handle the abnormal response (e.g. same status code). | 378 /// handle the abnormal response (e.g. same status code). |
374 /// </summary> | 379 /// </summary> |
375 [Test] | 380 [Test] |
376 public void SendAsync_UnsuccessfulReponseHanlder_AbnormalResponse_SameSt
atusCode() | 381 public void SendAsync_UnsuccessfulReponseHanlder_AbnormalResponse_SameSt
atusCode() |
377 { | 382 { |
378 SubtestSendAsyncUnsuccessfulReponseHanlder(HttpStatusCode.ServiceUna
vailable); | 383 SubtestSendAsyncUnsuccessfulReponseHanlder(HttpStatusCode.ServiceUna
vailable); |
379 } | 384 } |
380 | 385 |
381 /// <summary> Tests abnormal response when unsuccessful response handler
isn't plugged. </summary> | 386 /// <summary>Tests abnormal response when unsuccessful response handler
isn't plugged.</summary> |
382 [Test] | 387 [Test] |
383 public void SendAsync_AbnormalResponse_WithoutUnsuccessfulReponseHandler
() | 388 public void SendAsync_AbnormalResponse_WithoutUnsuccessfulReponseHandler
() |
384 { | 389 { |
385 var handler = new UnsuccessfulResponseMessageHandler | 390 var handler = new UnsuccessfulResponseMessageHandler |
386 { | 391 { |
387 ResponseStatusCode = HttpStatusCode.ServiceUnavailable | 392 ResponseStatusCode = HttpStatusCode.ServiceUnavailable |
388 }; | 393 }; |
389 | 394 |
390 var configurableHanlder = new ConfigurableMessageHandler(handler); | 395 var configurableHanlder = new ConfigurableMessageHandler(handler); |
391 using (var client = new HttpClient(configurableHanlder)) | 396 using (var client = new HttpClient(configurableHanlder)) |
392 { | 397 { |
393 var request = new HttpRequestMessage(HttpMethod.Get, "https://te
st-unsuccessful-handler"); | 398 var request = new HttpRequestMessage(HttpMethod.Get, "https://te
st-unsuccessful-handler"); |
394 | 399 |
395 HttpResponseMessage response = client.SendAsync(request).Result; | 400 HttpResponseMessage response = client.SendAsync(request).Result; |
396 Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.Servi
ceUnavailable)); | 401 Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.Servi
ceUnavailable)); |
397 Assert.That(handler.Calls, Is.EqualTo(1)); | 402 Assert.That(handler.Calls, Is.EqualTo(1)); |
398 } | 403 } |
399 } | 404 } |
400 | 405 |
401 #endregion | 406 #endregion |
402 | 407 |
403 #region Exception Handler | 408 #region Exception Handler |
404 | 409 |
405 /// <summary> Mock exception message handler which verifies that excepti
on handler is being called. </summary> | 410 /// <summary>Mock exception message handler which verifies that exceptio
n handler is being called.</summary> |
406 private class ExceptionMessageHandler : CountableMessageHandler | 411 private class ExceptionMessageHandler : CountableMessageHandler |
407 { | 412 { |
408 public ExceptionMessageHandler() | 413 public ExceptionMessageHandler() |
409 { | 414 { |
410 Exception = new Exception(ExceptionMessage); | 415 Exception = new Exception(ExceptionMessage); |
411 } | 416 } |
412 | 417 |
413 /// <summary> Gets or sets indication if exception should be thrown.
</summary> | 418 /// <summary>Gets or sets indication if exception should be thrown.<
/summary> |
414 public bool ThrowException { get; set; } | 419 public bool ThrowException { get; set; } |
415 | 420 |
416 /// <summary> | 421 /// <summary> |
417 /// Gets or sets a specific exception to throw. Default value is <se
ealso cref="System.Exception"/>· | 422 /// Gets or sets a specific exception to throw. Default value is <se
ealso cref="System.Exception"/>· |
418 /// with <see cref="ExceptionMessage"/>. </summary> | 423 /// with <see cref="ExceptionMessage"/>.</summary> |
419 public Exception Exception { get; set; } | 424 public Exception Exception { get; set; } |
420 | 425 |
421 /// <summary> | 426 /// <summary> |
422 /// The exception message which is thrown in case <see cref="ThrowEx
ception"/> is <c>true</c>.· | 427 /// The exception message which is thrown in case <see cref="ThrowEx
ception"/> is <c>true</c>.· |
423 /// </summary> | 428 /// </summary> |
424 public const string ExceptionMessage = "Exception from execute"; | 429 public const string ExceptionMessage = "Exception from execute"; |
425 | 430 |
426 protected override Task<HttpResponseMessage> SendAsyncCore(HttpReque
stMessage request, | 431 protected override Task<HttpResponseMessage> SendAsyncCore(HttpReque
stMessage request, |
427 CancellationToken cancellationToken) | 432 CancellationToken cancellationToken) |
428 { | 433 { |
429 if (ThrowException) | 434 if (ThrowException) |
430 { | 435 { |
431 throw Exception; | 436 throw Exception; |
432 } | 437 } |
433 | 438 |
434 TaskCompletionSource<HttpResponseMessage> tcs = new TaskCompleti
onSource<HttpResponseMessage>(); | 439 TaskCompletionSource<HttpResponseMessage> tcs = new TaskCompleti
onSource<HttpResponseMessage>(); |
435 tcs.SetResult(new HttpResponseMessage()); | 440 tcs.SetResult(new HttpResponseMessage()); |
436 return tcs.Task; | 441 return tcs.Task; |
437 } | 442 } |
438 | 443 |
439 /// <summary> Mock Exception handler which "handles" the exception.
</summary> | 444 /// <summary>Mock Exception handler which "handles" the exception.</
summary> |
440 internal class ExceptionHandler : IHttpExceptionHandler | 445 internal class ExceptionHandler : IHttpExceptionHandler |
441 { | 446 { |
442 public int Calls { get; set; } | 447 public int Calls { get; set; } |
443 public bool Handle { get; set; } | 448 public bool Handle { get; set; } |
444 | 449 |
445 public ExceptionHandler(bool handle = true) | 450 public ExceptionHandler(bool handle = true) |
446 { | 451 { |
447 Handle = handle; | 452 Handle = handle; |
448 } | 453 } |
449 | 454 |
450 public bool HandleException(HandleExceptionArgs args) | 455 public Task<bool> HandleExceptionAsync(HandleExceptionArgs args) |
451 { | 456 { |
452 ++Calls; | 457 ++Calls; |
453 return Handle; | 458 TaskCompletionSource<bool> tcs = new TaskCompletionSource<bo
ol>(); |
| 459 tcs.SetResult(Handle); |
| 460 return tcs.Task; |
454 } | 461 } |
455 } | 462 } |
456 } | 463 } |
457 | 464 |
458 /// <summary> Subtest for exception handler which tests that exception h
andler is invoked. </summary> | 465 /// <summary>Subtest for exception handler which tests that exception ha
ndler is invoked.</summary> |
459 private void SubtestSendAsyncExceptionHandler(bool throwException, bool
handle) | 466 private void SubtestSendAsyncExceptionHandler(bool throwException, bool
handle) |
460 { | 467 { |
461 var handler = new ExceptionMessageHandler { ThrowException = throwEx
ception }; | 468 var handler = new ExceptionMessageHandler { ThrowException = throwEx
ception }; |
462 | 469 |
463 var configurableHanlder = new ConfigurableMessageHandler(handler); | 470 var configurableHanlder = new ConfigurableMessageHandler(handler); |
464 var exceptionHandler = new ExceptionMessageHandler.ExceptionHandler
{ Handle = handle }; | 471 var exceptionHandler = new ExceptionMessageHandler.ExceptionHandler
{ Handle = handle }; |
465 configurableHanlder.ExceptionHandlers.Add(exceptionHandler); | 472 configurableHanlder.ExceptionHandlers.Add(exceptionHandler); |
466 | 473 |
467 using (var client = new HttpClient(configurableHanlder)) | 474 using (var client = new HttpClient(configurableHanlder)) |
468 { | 475 { |
(...skipping 21 matching lines...) Expand all Loading... |
490 else | 497 else |
491 { | 498 { |
492 Assert.That(exceptionHandler.Calls, Is.EqualTo(0)); | 499 Assert.That(exceptionHandler.Calls, Is.EqualTo(0)); |
493 } | 500 } |
494 | 501 |
495 Assert.That(handler.Calls, Is.EqualTo(throwException & handle ?
configurableHanlder.NumTries : 1)); | 502 Assert.That(handler.Calls, Is.EqualTo(throwException & handle ?
configurableHanlder.NumTries : 1)); |
496 } | 503 } |
497 } | 504 } |
498 | 505 |
499 | 506 |
500 /// <summary> Tests that the exception handler isn't called on successfu
l response. </summary> | 507 /// <summary>Tests that the exception handler isn't called on successful
response.</summary> |
501 [Test] | 508 [Test] |
502 public void SendAsync_ExceptionHandler_SuccessReponse() | 509 public void SendAsync_ExceptionHandler_SuccessReponse() |
503 { | 510 { |
504 SubtestSendAsyncExceptionHandler(false, true); | 511 SubtestSendAsyncExceptionHandler(false, true); |
505 } | 512 } |
506 | 513 |
507 /// <summary> | 514 /// <summary> |
508 /// Tests that the exception handler is called when exception is thrown
on execute, but it can't handle the· | 515 /// Tests that the exception handler is called when exception is thrown
on execute, but it can't handle the· |
509 /// exception.· | 516 /// exception.· |
510 /// </summary> | 517 /// </summary> |
511 [Test] | 518 [Test] |
512 public void SendAsync_ExceptionHandler_ThrowException_DontHandle() | 519 public void SendAsync_ExceptionHandler_ThrowException_DontHandle() |
513 { | 520 { |
514 SubtestSendAsyncExceptionHandler(true, false); | 521 SubtestSendAsyncExceptionHandler(true, false); |
515 } | 522 } |
516 | 523 |
517 /// <summary> | 524 /// <summary> |
518 /// Tests that the exception handler is called when exception is thrown
on execute, and it handles the· | 525 /// Tests that the exception handler is called when exception is thrown
on execute, and it handles the· |
519 /// exception.· | 526 /// exception.· |
520 /// </summary> | 527 /// </summary> |
521 [Test] | 528 [Test] |
522 public void SendAsync_ExceptionHandler_ThrowException_Handle() | 529 public void SendAsync_ExceptionHandler_ThrowException_Handle() |
523 { | 530 { |
524 SubtestSendAsyncExceptionHandler(true, true); | 531 SubtestSendAsyncExceptionHandler(true, true); |
525 } | 532 } |
526 | 533 |
527 /// <summary> Tests an exception is thrown on execute and there is no ex
ception handler. </summary> | 534 /// <summary>Tests an exception is thrown on execute and there is no exc
eption handler.</summary> |
528 [Test] | 535 [Test] |
529 public void SendAsync_ThrowException_WithoutExceptionHandler() | 536 public void SendAsync_ThrowException_WithoutExceptionHandler() |
530 { | 537 { |
531 var handler = new ExceptionMessageHandler { ThrowException = true }; | 538 var handler = new ExceptionMessageHandler { ThrowException = true }; |
532 | 539 |
533 var configurableHanlder = new ConfigurableMessageHandler(handler); | 540 var configurableHanlder = new ConfigurableMessageHandler(handler); |
534 | 541 |
535 using (var client = new HttpClient(configurableHanlder)) | 542 using (var client = new HttpClient(configurableHanlder)) |
536 { | 543 { |
537 var request = new HttpRequestMessage(HttpMethod.Get, "https://te
st-exception-handler"); | 544 var request = new HttpRequestMessage(HttpMethod.Get, "https://te
st-exception-handler"); |
(...skipping 13 matching lines...) Expand all Loading... |
551 Assert.That(handler.Calls, Is.EqualTo(1)); | 558 Assert.That(handler.Calls, Is.EqualTo(1)); |
552 } | 559 } |
553 } | 560 } |
554 | 561 |
555 #endregion | 562 #endregion |
556 | 563 |
557 #region Back-off | 564 #region Back-off |
558 | 565 |
559 #region Exception | 566 #region Exception |
560 | 567 |
561 /// <summary> | 568 /// <summary> |
562 /// Tests that back-off handler works as expected when exception is thro
wn.· | 569 /// Tests that back-off handler works as expected when exception is thro
wn.· |
563 /// Use default max time span (2 minutes). | 570 /// Use default max time span (2 minutes). |
564 /// </summary> | 571 /// </summary> |
565 [Test] | 572 [Test] |
566 public void SendAsync_BackOffExceptionHandler_Throw_Max2Minutes() | 573 public void SendAsync_BackOffExceptionHandler_Throw_Max2Minutes() |
567 { | 574 { |
568 // create exponential back-off without delta interval, so expected s
econds are exactly 1, 2, 4, 8, etc. | 575 // create exponential back-off without delta interval, so expected s
econds are exactly 1, 2, 4, 8, etc. |
569 var initializer = new BackOffHandler.Initializer(new ExponentialBack
Off(TimeSpan.Zero)); | 576 var initializer = new BackOffHandler.Initializer(new ExponentialBack
Off(TimeSpan.Zero)); |
570 SubtestSendAsync_BackOffExceptionHandler(true, initializer); | 577 SubtestSendAsync_BackOffExceptionHandler(true, initializer); |
571 } | 578 } |
572 | 579 |
573 /// <summary> | 580 /// <summary> |
574 /// Tests that back-off handler works as expected when exception is thro
wn.· | 581 /// Tests that back-off handler works as expected when exception is thro
wn.· |
575 /// Max time span is set to 200 milliseconds (as a result the back-off h
andler can't handle the exception). | 582 /// Max time span is set to 200 milliseconds (as a result the back-off h
andler can't handle the exception). |
576 /// </summary> | 583 /// </summary> |
577 [Test] | 584 [Test] |
578 public void SendAsync_BackOffExceptionHandler_Throw_Max200Milliseconds() | 585 public void SendAsync_BackOffExceptionHandler_Throw_Max200Milliseconds() |
579 { | 586 { |
580 var initializer = new BackOffHandler.Initializer(new ExponentialBack
Off(TimeSpan.Zero)) | 587 var initializer = new BackOffHandler.Initializer(new ExponentialBack
Off(TimeSpan.Zero)) |
581 { | 588 { |
582 MaxTimeSpan = TimeSpan.FromMilliseconds(200) | 589 MaxTimeSpan = TimeSpan.FromMilliseconds(200) |
583 }; | 590 }; |
584 SubtestSendAsync_BackOffExceptionHandler(true, initializer); | 591 SubtestSendAsync_BackOffExceptionHandler(true, initializer); |
585 } | 592 } |
586 | 593 |
587 /// <summary> | 594 /// <summary> |
588 /// Tests that back-off handler works as expected when exception is thro
wn.· | 595 /// Tests that back-off handler works as expected when exception is thro
wn.· |
589 /// Max time span is set to 1 hour. | 596 /// Max time span is set to 1 hour. |
590 /// </summary> | 597 /// </summary> |
591 [Test] | 598 [Test] |
592 public void SendAsync_BackOffExceptionHandler_Throw_Max1Hour() | 599 public void SendAsync_BackOffExceptionHandler_Throw_Max1Hour() |
593 { | 600 { |
594 var initializer = new BackOffHandler.Initializer(new ExponentialBack
Off(TimeSpan.Zero)) | 601 var initializer = new BackOffHandler.Initializer(new ExponentialBack
Off(TimeSpan.Zero)) |
595 { | 602 { |
596 MaxTimeSpan = TimeSpan.FromHours(1) | 603 MaxTimeSpan = TimeSpan.FromHours(1) |
597 }; | 604 }; |
598 SubtestSendAsync_BackOffExceptionHandler(true, initializer); | 605 SubtestSendAsync_BackOffExceptionHandler(true, initializer); |
599 } | 606 } |
600 | 607 |
601 /// <summary> | 608 /// <summary> |
602 /// Tests that back-off handler works as expected when· | 609 /// Tests that back-off handler works as expected when· |
603 /// <seealso cref="System.Threading.Tasks.TaskCanceledException"/>> is t
hrown.· | 610 /// <seealso cref="System.Threading.Tasks.TaskCanceledException"/>> is t
hrown.· |
604 /// </summary> | 611 /// </summary> |
605 [Test] | 612 [Test] |
606 public void SendAsync_BackOffExceptionHandler_ThrowCanceledException() | 613 public void SendAsync_BackOffExceptionHandler_ThrowCanceledException() |
607 { | 614 { |
608 var initializer = new BackOffHandler.Initializer(new ExponentialBack
Off(TimeSpan.Zero)); | 615 var initializer = new BackOffHandler.Initializer(new ExponentialBack
Off(TimeSpan.Zero)); |
609 SubtestSendAsync_BackOffExceptionHandler(true, initializer, new Task
CanceledException()); | 616 SubtestSendAsync_BackOffExceptionHandler(true, initializer, new Task
CanceledException()); |
610 } | 617 } |
611 | 618 |
612 /// <summary> | 619 /// <summary> |
613 /// Tests that back-off handler works as expected with the not defaulted
exception handler.· | 620 /// Tests that back-off handler works as expected with the not defaulted
exception handler.· |
614 /// </summary> | 621 /// </summary> |
615 [Test] | 622 [Test] |
616 public void SendAsync_BackOffExceptionHandler_DifferentHandler() | 623 public void SendAsync_BackOffExceptionHandler_DifferentHandler() |
617 { | 624 { |
618 var initializer = new BackOffHandler.Initializer(new ExponentialBack
Off(TimeSpan.Zero)); | 625 var initializer = new BackOffHandler.Initializer(new ExponentialBack
Off(TimeSpan.Zero)); |
619 initializer.HandleExceptionFunc = e => (e is InvalidCastException); | 626 initializer.HandleExceptionFunc = e => (e is InvalidCastException); |
620 SubtestSendAsync_BackOffExceptionHandler(true, initializer, new Inva
lidCastException()); | 627 SubtestSendAsync_BackOffExceptionHandler(true, initializer, new Inva
lidCastException()); |
621 | 628 |
622 initializer.HandleExceptionFunc = e => !(e is InvalidCastException); | 629 initializer.HandleExceptionFunc = e => !(e is InvalidCastException); |
623 SubtestSendAsync_BackOffExceptionHandler(true, initializer, new Inva
lidCastException()); | 630 SubtestSendAsync_BackOffExceptionHandler(true, initializer, new Inva
lidCastException()); |
624 } | 631 } |
625 | 632 |
626 /// <summary> Tests that back-off handler works as expected when excepti
on isn't thrown. </summary> | 633 /// <summary>Tests that back-off handler works as expected when exceptio
n isn't thrown.</summary> |
627 [Test] | 634 [Test] |
628 public void SendAsync_BackOffExceptionHandler_DontThrow() | 635 public void SendAsync_BackOffExceptionHandler_DontThrow() |
629 { | 636 { |
630 var initializer = new BackOffHandler.Initializer(new ExponentialBack
Off(TimeSpan.Zero)); | 637 var initializer = new BackOffHandler.Initializer(new ExponentialBack
Off(TimeSpan.Zero)); |
631 SubtestSendAsync_BackOffExceptionHandler(false, initializer); | 638 SubtestSendAsync_BackOffExceptionHandler(false, initializer); |
632 } | 639 } |
633 | 640 |
634 /// <summary> Subtest that back-off handler works as expected when excep
tion is or isn't thrown. </summary> | 641 /// <summary>Subtest that back-off handler works as expected when except
ion is or isn't thrown.</summary> |
635 private void SubtestSendAsync_BackOffExceptionHandler(bool throwExceptio
n, | 642 private void SubtestSendAsync_BackOffExceptionHandler(bool throwExceptio
n, |
636 BackOffHandler.Initializer initializer, Exception exceptionToThrow =
null) | 643 BackOffHandler.Initializer initializer, Exception exceptionToThrow =
null) |
637 { | 644 { |
638 var handler = new ExceptionMessageHandler { ThrowException = throwEx
ception }; | 645 var handler = new ExceptionMessageHandler { ThrowException = throwEx
ception }; |
639 if (exceptionToThrow != null) | 646 if (exceptionToThrow != null) |
640 { | 647 { |
641 handler.Exception = exceptionToThrow; | 648 handler.Exception = exceptionToThrow; |
642 } | 649 } |
643 | 650 |
644 var configurableHanlder = new ConfigurableMessageHandler(handler); | 651 var configurableHanlder = new ConfigurableMessageHandler(handler); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
679 } | 686 } |
680 } | 687 } |
681 Assert.That(handler.Calls, Is.EqualTo(boHandleCount + 1)); | 688 Assert.That(handler.Calls, Is.EqualTo(boHandleCount + 1)); |
682 } | 689 } |
683 } | 690 } |
684 | 691 |
685 #endregion | 692 #endregion |
686 | 693 |
687 #region Unsuccessful Response Handler | 694 #region Unsuccessful Response Handler |
688 | 695 |
689 /// <summary> | 696 /// <summary> |
690 /// Tests that back-off handler works as expected when the server return
s 5xx and the maximum time span is set | 697 /// Tests that back-off handler works as expected when the server return
s 5xx and the maximum time span is set |
691 /// to 5 seconds. | 698 /// to 5 seconds. |
692 /// </summary> | 699 /// </summary> |
693 [Test] | 700 [Test] |
694 public void SendAsync_BackOffUnsuccessfulResponseHandler_ServiceUnavaila
ble_Max5Seconds() | 701 public void SendAsync_BackOffUnsuccessfulResponseHandler_ServiceUnavaila
ble_Max5Seconds() |
695 { | 702 { |
696 var initializer = new BackOffHandler.Initializer(new ExponentialBack
Off(TimeSpan.Zero)) | 703 var initializer = new BackOffHandler.Initializer(new ExponentialBack
Off(TimeSpan.Zero)) |
697 { | 704 { |
698 MaxTimeSpan = TimeSpan.FromSeconds(5) | 705 MaxTimeSpan = TimeSpan.FromSeconds(5) |
699 }; | 706 }; |
700 SubtestSendAsync_BackOffUnsuccessfulResponseHandler(HttpStatusCode.S
erviceUnavailable, initializer); | 707 SubtestSendAsync_BackOffUnsuccessfulResponseHandler(HttpStatusCode.S
erviceUnavailable, initializer); |
701 } | 708 } |
702 | 709 |
703 /// <summary> | 710 /// <summary> |
704 /// Tests that back-off handler works as expected when the server return
s 5xx and the maximum time span is set | 711 /// Tests that back-off handler works as expected when the server return
s 5xx and the maximum time span is set |
705 /// to 10 hours. | 712 /// to 10 hours. |
706 /// </summary> | 713 /// </summary> |
707 [Test] | 714 [Test] |
708 public void SendAsync_BackOffUnsuccessfulResponseHandler_ServiceUnavaila
ble_Max10Hours() | 715 public void SendAsync_BackOffUnsuccessfulResponseHandler_ServiceUnavaila
ble_Max10Hours() |
709 { | 716 { |
710 var initializer = new BackOffHandler.Initializer(new ExponentialBack
Off(TimeSpan.Zero)) | 717 var initializer = new BackOffHandler.Initializer(new ExponentialBack
Off(TimeSpan.Zero)) |
711 { | 718 { |
712 MaxTimeSpan = TimeSpan.FromHours(10) | 719 MaxTimeSpan = TimeSpan.FromHours(10) |
713 }; | 720 }; |
714 SubtestSendAsync_BackOffUnsuccessfulResponseHandler(HttpStatusCode.S
erviceUnavailable, initializer); | 721 SubtestSendAsync_BackOffUnsuccessfulResponseHandler(HttpStatusCode.S
erviceUnavailable, initializer); |
715 } | 722 } |
716 | 723 |
717 /// <summary> | 724 /// <summary> |
718 /// Tests that back-off handler isn't be called when the server returns
a successful response. | 725 /// Tests that back-off handler isn't be called when the server returns
a successful response. |
719 /// </summary> | 726 /// </summary> |
720 [Test] | 727 [Test] |
721 public void SendAsync_BackOffUnsuccessfulResponseHandler_OK() | 728 public void SendAsync_BackOffUnsuccessfulResponseHandler_OK() |
722 { | 729 { |
723 var initializer = new BackOffHandler.Initializer(new ExponentialBack
Off(TimeSpan.Zero)); | 730 var initializer = new BackOffHandler.Initializer(new ExponentialBack
Off(TimeSpan.Zero)); |
724 SubtestSendAsync_BackOffUnsuccessfulResponseHandler(HttpStatusCode.O
K, initializer); | 731 SubtestSendAsync_BackOffUnsuccessfulResponseHandler(HttpStatusCode.O
K, initializer); |
725 } | 732 } |
726 | 733 |
727 /// <summary> Tests that back-off handler is canceled when cancellation
token is used.</summary> | 734 /// <summary>Tests that back-off handler is canceled when cancellation t
oken is used.</summary> |
728 [Test] | 735 [Test] |
729 public void SendAsync_BackOffUnsuccessfulResponseHandler_Cancel() | 736 public void SendAsync_BackOffUnsuccessfulResponseHandler_Cancel() |
730 { | 737 { |
731 // test back-off with maximum 30 minutes per single request | 738 // test back-off with maximum 30 minutes per single request |
732 var initializer = new BackOffHandler.Initializer(new ExponentialBack
Off(TimeSpan.Zero)) | 739 var initializer = new BackOffHandler.Initializer(new ExponentialBack
Off(TimeSpan.Zero)) |
733 { | 740 { |
734 MaxTimeSpan = TimeSpan.FromMinutes(30) | 741 MaxTimeSpan = TimeSpan.FromMinutes(30) |
735 }; | 742 }; |
736 SubtestSendAsync_BackOffUnsuccessfulResponseHandler(HttpStatusCode.S
erviceUnavailable, initializer, 2); | 743 SubtestSendAsync_BackOffUnsuccessfulResponseHandler(HttpStatusCode.S
erviceUnavailable, initializer, 2); |
737 SubtestSendAsync_BackOffUnsuccessfulResponseHandler(HttpStatusCode.S
erviceUnavailable, initializer, 6); | 744 SubtestSendAsync_BackOffUnsuccessfulResponseHandler(HttpStatusCode.S
erviceUnavailable, initializer, 6); |
738 } | 745 } |
739 | 746 |
740 /// <summary> | 747 /// <summary> |
741 /// Subtest that back-off handler works as expected when a successful or
abnormal response is returned. | 748 /// Subtest that back-off handler works as expected when a successful or
abnormal response is returned. |
742 /// For testing the back-off handler in case of a canceled request, set
the <code>cancelRequestNum</code> | 749 /// For testing the back-off handler in case of a canceled request, set
the <code>cancelRequestNum</code> |
743 /// parameter to the index of the request you want to cancel. | 750 /// parameter to the index of the request you want to cancel. |
744 /// </summary> | 751 /// </summary> |
745 private void SubtestSendAsync_BackOffUnsuccessfulResponseHandler(HttpSta
tusCode statusCode, | 752 private void SubtestSendAsync_BackOffUnsuccessfulResponseHandler(HttpSta
tusCode statusCode, |
746 BackOffHandler.Initializer initializer, int cancelRequestNum = 0, in
t numTries = 10) | 753 BackOffHandler.Initializer initializer, int cancelRequestNum = 0, in
t numTries = 10) |
747 { | 754 { |
748 var handler = new UnsuccessfulResponseMessageHandler { ResponseStatu
sCode = statusCode }; | 755 var handler = new UnsuccessfulResponseMessageHandler { ResponseStatu
sCode = statusCode }; |
749 | 756 |
750 CancellationToken cancellationToken = CancellationToken.None; | 757 CancellationToken cancellationToken = CancellationToken.None; |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
806 Assert.That(handler.Calls, Is.EqualTo(boHandleCount + (cancel ?
0 : 1))); | 813 Assert.That(handler.Calls, Is.EqualTo(boHandleCount + (cancel ?
0 : 1))); |
807 } | 814 } |
808 } | 815 } |
809 | 816 |
810 #endregion | 817 #endregion |
811 | 818 |
812 #endregion | 819 #endregion |
813 | 820 |
814 #region Content | 821 #region Content |
815 | 822 |
816 /// <summary> Mock message handler which verifies that the content is co
rrect on retry. </summary> | 823 /// <summary>Mock message handler which verifies that the content is cor
rect on retry.</summary> |
817 private class ContentMessageHandler : CountableMessageHandler | 824 private class ContentMessageHandler : CountableMessageHandler |
818 { | 825 { |
819 public const int NumFails = 4; | 826 public const int NumFails = 4; |
820 public string ReadContent; | 827 public string ReadContent; |
821 | 828 |
822 protected override async Task<HttpResponseMessage> SendAsyncCore(Htt
pRequestMessage request, | 829 protected override async Task<HttpResponseMessage> SendAsyncCore(Htt
pRequestMessage request, |
823 CancellationToken cancellationToken) | 830 CancellationToken cancellationToken) |
824 { | 831 { |
825 if (Calls < NumFails) | 832 if (Calls < NumFails) |
826 { | 833 { |
827 return new HttpResponseMessage() { StatusCode = HttpStatusCo
de.ServiceUnavailable }; | 834 return new HttpResponseMessage() { StatusCode = HttpStatusCo
de.ServiceUnavailable }; |
828 } | 835 } |
829 | 836 |
830 ReadContent = await request.Content.ReadAsStringAsync(); | 837 ReadContent = await request.Content.ReadAsStringAsync(); |
831 return new HttpResponseMessage(); | 838 return new HttpResponseMessage(); |
832 } | 839 } |
833 } | 840 } |
834 | 841 |
835 /// <summary> | 842 /// <summary> |
836 /// Defines the different content types we test in <see cref="SubtestSen
dAsyncRetryContent"/>. | 843 /// Defines the different content types we test in <see cref="SubtestSen
dAsyncRetryContent"/>. |
837 /// </summary> | 844 /// </summary> |
838 private enum ContentType | 845 private enum ContentType |
839 { | 846 { |
840 String, | 847 String, |
841 Stream, | 848 Stream, |
842 ByteArray | 849 ByteArray |
843 } | 850 } |
844 | 851 |
845 /// <summary> Tests that retry works with different kind of contents (St
ring, Stream and ByteArray). </summary> | 852 /// <summary>Tests that retry works with different kind of contents (Str
ing, Stream and ByteArray).</summary> |
846 private void SubtestSendAsyncRetryContent(ContentType type) | 853 private void SubtestSendAsyncRetryContent(ContentType type) |
847 { | 854 { |
848 var content = "test-content"; | 855 var content = "test-content"; |
849 var contentHandler = new ContentMessageHandler(); | 856 var contentHandler = new ContentMessageHandler(); |
850 var configurableHanlder = new ConfigurableMessageHandler(contentHand
ler) | 857 var configurableHanlder = new ConfigurableMessageHandler(contentHand
ler) |
851 { | 858 { |
852 NumTries = 10 | 859 NumTries = 10 |
853 }; | 860 }; |
854 configurableHanlder.UnsuccessfulResponseHandlers.Add(new TrueUnsucce
ssfulResponseHandler()); | 861 configurableHanlder.UnsuccessfulResponseHandlers.Add(new TrueUnsucce
ssfulResponseHandler()); |
855 using (var client = new HttpClient(configurableHanlder)) | 862 using (var client = new HttpClient(configurableHanlder)) |
(...skipping 19 matching lines...) Expand all Loading... |
875 break; | 882 break; |
876 } | 883 } |
877 | 884 |
878 HttpResponseMessage response = client.SendAsync(request).Result; | 885 HttpResponseMessage response = client.SendAsync(request).Result; |
879 Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK)); | 886 Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK)); |
880 Assert.That(contentHandler.Calls, Is.EqualTo(ContentMessageHandl
er.NumFails)); | 887 Assert.That(contentHandler.Calls, Is.EqualTo(ContentMessageHandl
er.NumFails)); |
881 Assert.That(contentHandler.ReadContent, Is.EqualTo(content)); | 888 Assert.That(contentHandler.ReadContent, Is.EqualTo(content)); |
882 } | 889 } |
883 } | 890 } |
884 | 891 |
885 /// <summary> Tests that a string content works as expected on retry. </
summary> | 892 /// <summary>Tests that a string content works as expected on retry.</su
mmary> |
886 [Test] | 893 [Test] |
887 public void SendAsync_Retry_CorrectStringContent() | 894 public void SendAsync_Retry_CorrectStringContent() |
888 { | 895 { |
889 SubtestSendAsyncRetryContent(ContentType.String); | 896 SubtestSendAsyncRetryContent(ContentType.String); |
890 } | 897 } |
891 | 898 |
892 /// <summary> Tests that a stream content works as expected on retry. </
summary> | 899 /// <summary>Tests that a stream content works as expected on retry.</su
mmary> |
893 [Test] | 900 [Test] |
894 public void SendAsync_Retry_CorrectStreamContent() | 901 public void SendAsync_Retry_CorrectStreamContent() |
895 { | 902 { |
896 SubtestSendAsyncRetryContent(ContentType.Stream); | 903 SubtestSendAsyncRetryContent(ContentType.Stream); |
897 } | 904 } |
898 | 905 |
899 /// <summary> Tests that a byte array content works as expected on retry
. </summary> | 906 /// <summary>Tests that a byte array content works as expected on retry.
</summary> |
900 [Test] | 907 [Test] |
901 public void SendAsync_Retry_CorrectByteArrayContent() | 908 public void SendAsync_Retry_CorrectByteArrayContent() |
902 { | 909 { |
903 SubtestSendAsyncRetryContent(ContentType.ByteArray); | 910 SubtestSendAsyncRetryContent(ContentType.ByteArray); |
904 } | 911 } |
905 | 912 |
906 #endregion | 913 #endregion |
907 | 914 |
908 /// <summary> Tests setting number of tries. </summary> | 915 /// <summary>Tests setting number of tries.</summary> |
909 [Test] | 916 [Test] |
910 public void NumTries_Setter() | 917 public void NumTries_Setter() |
911 { | 918 { |
912 var configurableHanlder = new ConfigurableMessageHandler(new HttpCli
entHandler()); | 919 var configurableHanlder = new ConfigurableMessageHandler(new HttpCli
entHandler()); |
913 | 920 |
914 // valid values | 921 // valid values |
915 configurableHanlder.NumTries = ConfigurableMessageHandler.MaxAllowed
NumTries; | 922 configurableHanlder.NumTries = ConfigurableMessageHandler.MaxAllowed
NumTries; |
916 configurableHanlder.NumTries = ConfigurableMessageHandler.MaxAllowed
NumTries - 1; | 923 configurableHanlder.NumTries = ConfigurableMessageHandler.MaxAllowed
NumTries - 1; |
917 configurableHanlder.NumTries = 1; | 924 configurableHanlder.NumTries = 1; |
918 | 925 |
(...skipping 20 matching lines...) Expand all Loading... |
939 { | 946 { |
940 configurableHanlder.NumTries = -2; | 947 configurableHanlder.NumTries = -2; |
941 Assert.Fail(); | 948 Assert.Fail(); |
942 } | 949 } |
943 catch (ArgumentOutOfRangeException ex) | 950 catch (ArgumentOutOfRangeException ex) |
944 { | 951 { |
945 Assert.True(ex.Message.Contains("Parameter name: NumTries")); | 952 Assert.True(ex.Message.Contains("Parameter name: NumTries")); |
946 } | 953 } |
947 } | 954 } |
948 | 955 |
949 /// <summary> | 956 /// <summary> |
950 /// Tests the number of tries in case of unsuccessful response when unsu
ccessful response handler is plugged to· | 957 /// Tests the number of tries in case of unsuccessful response when unsu
ccessful response handler is plugged to· |
951 /// the message handler.· | 958 /// the message handler.· |
952 /// </summary> | 959 /// </summary> |
953 [Test] | 960 [Test] |
954 public void SendAsync_NumTries() | 961 public void SendAsync_NumTries() |
955 { | 962 { |
956 SubtestSendAsyncNumTries(5, false); | 963 SubtestSendAsyncNumTries(5, false); |
957 SubtestSendAsyncNumTries(5); | 964 SubtestSendAsyncNumTries(5); |
958 SubtestSendAsyncNumTries(1); | 965 SubtestSendAsyncNumTries(1); |
959 SubtestSendAsyncNumTries(1, false); | 966 SubtestSendAsyncNumTries(1, false); |
(...skipping 23 matching lines...) Expand all Loading... |
983 configurableHanlder.UnsuccessfulResponseHandlers.Add(unsuccessfu
lHandler); | 990 configurableHanlder.UnsuccessfulResponseHandlers.Add(unsuccessfu
lHandler); |
984 } | 991 } |
985 | 992 |
986 using (var client = new HttpClient(configurableHanlder)) | 993 using (var client = new HttpClient(configurableHanlder)) |
987 { | 994 { |
988 client.GetAsync("http://num-retres"); | 995 client.GetAsync("http://num-retres"); |
989 Assert.That(handler.Calls, Is.EqualTo(handle ? numTries : 1)); | 996 Assert.That(handler.Calls, Is.EqualTo(handle ? numTries : 1)); |
990 } | 997 } |
991 } | 998 } |
992 | 999 |
993 /// <summary> Tests that the configurable message handler sets the User-
Agent header. </summary> | 1000 /// <summary>Tests that the configurable message handler sets the User-A
gent header.</summary> |
994 [Test] | 1001 [Test] |
995 public void SendAsync_UserAgent() | 1002 public void SendAsync_UserAgent() |
996 { | 1003 { |
997 var apiVersion = string.Format("google-api-dotnet-client/{0} (gzip)"
, Utilities.GetLibraryVersion()); | 1004 var apiVersion = string.Format("google-api-dotnet-client/{0} (gzip)"
, Utilities.GetLibraryVersion()); |
998 const string applicationName = "NO NAME"; | 1005 const string applicationName = "NO NAME"; |
999 | 1006 |
1000 var handler = new MockMessageHandler(); | 1007 var handler = new MockMessageHandler(); |
1001 var configurableHanlder = new ConfigurableMessageHandler(handler); | 1008 var configurableHanlder = new ConfigurableMessageHandler(handler); |
1002 | 1009 |
1003 using (var client = new HttpClient(configurableHanlder)) | 1010 using (var client = new HttpClient(configurableHanlder)) |
1004 { | 1011 { |
1005 // without application name | 1012 // without application name |
1006 var request = new HttpRequestMessage(HttpMethod.Get, "https://te
st-user-agent"); | 1013 var request = new HttpRequestMessage(HttpMethod.Get, "https://te
st-user-agent"); |
1007 HttpResponseMessage response = client.SendAsync(request).Result; | 1014 HttpResponseMessage response = client.SendAsync(request).Result; |
1008 var userAgent = string.Join(" ", request.Headers.GetValues("User
-Agent").ToArray()); | 1015 var userAgent = string.Join(" ", request.Headers.GetValues("User
-Agent").ToArray()); |
1009 Assert.That(userAgent, Is.EqualTo(apiVersion)); | 1016 Assert.That(userAgent, Is.EqualTo(apiVersion)); |
1010 | 1017 |
1011 // with application name | 1018 // with application name |
1012 configurableHanlder.ApplicationName = applicationName; | 1019 configurableHanlder.ApplicationName = applicationName; |
1013 request = new HttpRequestMessage(HttpMethod.Get, "https://test-u
ser-agent"); | 1020 request = new HttpRequestMessage(HttpMethod.Get, "https://test-u
ser-agent"); |
1014 response = client.SendAsync(request).Result; | 1021 response = client.SendAsync(request).Result; |
1015 userAgent = string.Join(" ", request.Headers.GetValues("User-Age
nt").ToArray()); | 1022 userAgent = string.Join(" ", request.Headers.GetValues("User-Age
nt").ToArray()); |
1016 Assert.That(userAgent, Is.EqualTo(applicationName + " " + apiVer
sion)); | 1023 Assert.That(userAgent, Is.EqualTo(applicationName + " " + apiVer
sion)); |
1017 } | 1024 } |
1018 } | 1025 } |
1019 } | 1026 } |
1020 } | 1027 } |
OLD | NEW |