Skip to content

Commit

Permalink
Add RequestId to request and response and use it in EventSource (Azur…
Browse files Browse the repository at this point in the history
  • Loading branch information
pakrym committed Mar 27, 2019
1 parent e51c306 commit 1028dd7
Show file tree
Hide file tree
Showing 11 changed files with 332 additions and 87 deletions.
81 changes: 63 additions & 18 deletions src/SDKs/Azure.Base/data-plane/Azure.Base.Tests/EventSourceTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ namespace Azure.Base.Tests
{
// Avoid running these tests in parallel with anything else that's sharing the event source
[NonParallelizable]
public class EventSourceTests
public class EventSourceTests: PipelineTestBase
{
private readonly TestEventListener _listener = new TestEventListener();

Expand All @@ -43,47 +43,92 @@ public void MatchesNameAndGuid()
[Test]
public async Task SendingRequestProducesEvents()
{
var options = new HttpPipelineOptions(new HttpClientTransport(new HttpClient(new MockHttpMessageHandler())));
options.LoggingPolicy = LoggingPolicy.Shared;
var handler = new MockHttpClientHandler(httpRequestMessage => {
var response = new HttpResponseMessage((HttpStatusCode)500);
response.Content = new ByteArrayContent(new byte[] {6, 7, 8, 9, 0});
response.Headers.Add("Custom-Response-Header", "Improved value");
return Task.FromResult(response);
});
var transport = new HttpClientTransport(new HttpClient(handler));
var options = new HttpPipelineOptions(transport)
{
LoggingPolicy = LoggingPolicy.Shared
};

var pipeline = options.Build("test", "1.0.0");
string requestId;

using (var request = pipeline.CreateRequest())
{
request.SetRequestLine(HttpVerb.Get, new Uri("https://contoso.a.io"));
request.AddHeader("Date", "3/26/2019");
request.AddHeader("Custom-Header", "Value");
request.Content = HttpPipelineRequestContent.Create(new byte[] {1, 2, 3, 4, 5});
requestId = request.RequestId;

var response = await pipeline.SendRequestAsync(request, CancellationToken.None);

Assert.AreEqual(500, response.Status);
}

Assert.True(_listener.EventData.Any(e =>
e.EventId == 3 &&
e.EventName == "ProcessingRequest" &&
GetStringProperty(e, "request").Contains("https://contoso.a.io")));
e.EventId == 1 &&
e.Level == EventLevel.Informational &&
e.EventName == "Request" &&
GetStringProperty(e, "requestId").Equals(requestId) &&
GetStringProperty(e, "uri").Equals("https://contoso.a.io/") &&
GetStringProperty(e, "method").Equals("GET") &&
GetStringProperty(e, "headers").Contains($"Date:3/26/2019{Environment.NewLine}") &&
GetStringProperty(e, "headers").Contains($"Custom-Header:Value{Environment.NewLine}")
));

Assert.True(_listener.EventData.Any(e =>
e.EventId == 2 &&
e.Level == EventLevel.Verbose &&
e.EventName == "RequestContent" &&
GetStringProperty(e, "requestId").Equals(requestId) &&
((byte[])GetProperty(e, "content")).SequenceEqual(new byte[] {1, 2 , 3, 4, 5}))
);

Assert.True(_listener.EventData.Any(e =>
e.EventId == 4 &&
e.EventName == "ProcessingResponse" &&
GetStringProperty(e, "response").Contains("500")));
e.EventId == 5 &&
e.Level == EventLevel.Informational &&
e.EventName == "Response" &&
GetStringProperty(e, "requestId").Equals(requestId) &&
(int)GetProperty(e, "status") == 500 &&
GetStringProperty(e, "headers").Contains($"Custom-Response-Header:Improved value{Environment.NewLine}")
));

Assert.True(_listener.EventData.Any(e =>
e.EventId == 6 &&
e.Level == EventLevel.Verbose &&
e.EventName == "ResponseContent" &&
GetStringProperty(e, "requestId").Equals(requestId) &&
((byte[])GetProperty(e, "content")).SequenceEqual(new byte[] {6, 7, 8, 9, 0}))
);

Assert.True(_listener.EventData.Any(e =>
e.EventId == 8 &&
e.Level == EventLevel.Error &&
e.EventName == "ErrorResponse" &&
(int)GetProperty(e, "status") == 500));
GetStringProperty(e, "requestId").Equals(requestId) &&
(int)GetProperty(e, "status") == 500 &&
GetStringProperty(e, "headers").Contains($"Custom-Response-Header:Improved value{Environment.NewLine}")
));

Assert.True(_listener.EventData.Any(e =>
e.EventId == 9 &&
e.Level == EventLevel.Informational &&
e.EventName == "ErrorResponseContent" &&
GetStringProperty(e, "requestId").Equals(requestId) &&
((byte[])GetProperty(e, "content")).SequenceEqual(new byte[] {6, 7, 8, 9, 0}))
);
}

private object GetProperty(EventWrittenEventArgs data, string propName)
=> data.Payload[data.PayloadNames.IndexOf(propName)];

private string GetStringProperty(EventWrittenEventArgs data, string propName)
=> data.Payload[data.PayloadNames.IndexOf(propName)] as string;

private class MockHttpMessageHandler: HttpMessageHandler
{
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
return Task.FromResult(new HttpResponseMessage(HttpStatusCode.InternalServerError));
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,14 @@
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Azure.Base.Http;
using Azure.Base.Http.Pipeline;
using NUnit.Framework;

namespace Azure.Base.Tests
{
public class HttpClientTransportTests
public class HttpClientTransportTests: PipelineTestBase
{
public static object[] ContentWithLength =>
new object[]
Expand Down Expand Up @@ -277,41 +276,34 @@ public async Task SettingContentHeaderDoesNotSetContent(string headerName, strin
Assert.Null(httpMessageContent);
}

private static async Task<HttpPipelineResponse> ExecuteRequest(HttpPipelineRequest request, HttpClientTransport transport)
[Test]
public async Task RequestAndResponseHasRequestId()
{
using (var message = new HttpPipelineMessage(CancellationToken.None)
{
Request = request
})
{
await transport.ProcessAsync(message);
return message.Response;
}
var mockHandler = new MockHttpClientHandler(httpRequestMessage => { });

var transport = new HttpClientTransport(new HttpClient(mockHandler));
var request = transport.CreateRequest(null);
Assert.IsNotEmpty(request.RequestId);
Assert.True(Guid.TryParse(request.RequestId, out _));
request.SetRequestLine(HttpVerb.Get, new Uri("http://example.com:340"));

var response = await ExecuteRequest(request, transport);
Assert.AreEqual(request.RequestId, response.RequestId);
}

private class MockHttpClientHandler : HttpMessageHandler
[Test]
public async Task RequestIdCanBeOverriden()
{
private readonly Func<HttpRequestMessage, Task<HttpResponseMessage>> _onSend;

public MockHttpClientHandler(Action<HttpRequestMessage> onSend)
{
_onSend = req => {
onSend(req);
return Task.FromResult<HttpResponseMessage>(null);
};
}
var mockHandler = new MockHttpClientHandler(httpRequestMessage => { });

public MockHttpClientHandler(Func<HttpRequestMessage, Task<HttpResponseMessage>> onSend)
{
_onSend = onSend;
}
var transport = new HttpClientTransport(new HttpClient(mockHandler));
var request = transport.CreateRequest(null);

protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
var response = await _onSend(request);
request.RequestId = "123";
request.SetRequestLine(HttpVerb.Get, new Uri("http://example.com:340"));

return response ?? new HttpResponseMessage((HttpStatusCode)200);
}
var response = await ExecuteRequest(request, transport);
Assert.AreEqual(request.RequestId, response.RequestId);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;

namespace Azure.Base.Tests
{
internal class MockHttpClientHandler : HttpMessageHandler
{
private readonly Func<HttpRequestMessage, Task<HttpResponseMessage>> _onSend;

public MockHttpClientHandler(Action<HttpRequestMessage> onSend)
{
_onSend = req => {
onSend(req);
return Task.FromResult<HttpResponseMessage>(null);
};
}

public MockHttpClientHandler(Func<HttpRequestMessage, Task<HttpResponseMessage>> onSend)
{
_onSend = onSend;
}

protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
var response = await _onSend(request);

return response ?? new HttpResponseMessage((HttpStatusCode)200);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System.Threading;
using System.Threading.Tasks;
using Azure.Base.Http;
using Azure.Base.Http.Pipeline;

namespace Azure.Base.Tests
{
public class PipelineTestBase
{
protected static async Task<HttpPipelineResponse> ExecuteRequest(HttpPipelineRequest request, HttpClientTransport transport)
{
using (var message = new HttpPipelineMessage(CancellationToken.None)
{
Request = request
})
{
await transport.ProcessAsync(message);
return message.Response;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ public override IEnumerable<HttpHeader> Headers
}
}

public override string RequestId { get; set; }

public override void Dispose()
{
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ public override IEnumerable<HttpHeader> Headers
}
}

public override string RequestId { get; set; }

public override string ToString() => $"{Method} {Uri}";

public override void Dispose()
Expand All @@ -105,6 +107,8 @@ public PipelineResponse(HttpVerb method, Uri uri)

public override Stream ResponseContentStream => throw new NotImplementedException();

public override string RequestId { get; set; }

public void SetStatus(int status) => _status = status;

public override string ToString() => $"{_method} {_uri}";
Expand Down
Loading

0 comments on commit 1028dd7

Please sign in to comment.