Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Default to more Newtonsoft-like response encoding in TestFramework #12482

Merged
merged 4 commits into from
Jun 3, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 19 additions & 9 deletions sdk/core/Azure.Core.TestFramework/src/RecordEntry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,23 @@
using System.IO;
using System.Linq;
using System.Text;
using System.Text.Encodings.Web;
using System.Text.Json;
using Azure.Core.Pipeline;

namespace Azure.Core.TestFramework
{
public class RecordEntry
{
private static readonly JsonWriterOptions RequestWriterOptions = new JsonWriterOptions();
// Responses are usually formatted using Newtonsoft.Json that has more relaxed encoding rules
// To enable us to store more responses as JSON instead of string in Recording files use
// relaxed settings for roundrip
private static readonly JsonWriterOptions ResponseWriterOptions = new JsonWriterOptions()
{
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
};

public RecordEntryMessage Request { get; } = new RecordEntryMessage();

public RecordEntryMessage Response { get; } = new RecordEntryMessage();
Expand Down Expand Up @@ -51,7 +61,7 @@ public static RecordEntry Deserialize(JsonElement element)

if (element.TryGetProperty("RequestBody", out property))
{
record.Request.Body = DeserializeBody(record.Request.Headers, property);
record.Request.Body = DeserializeBody(record.Request.Headers, property, RequestWriterOptions);
}

if (element.TryGetProperty(nameof(StatusCode), out property) &&
Expand All @@ -67,13 +77,13 @@ public static RecordEntry Deserialize(JsonElement element)

if (element.TryGetProperty("ResponseBody", out property))
{
record.Response.Body = DeserializeBody(record.Response.Headers, property);
record.Response.Body = DeserializeBody(record.Response.Headers, property, ResponseWriterOptions);
}

return record;
}

private static byte[] DeserializeBody(IDictionary<string, string[]> headers, in JsonElement property)
private static byte[] DeserializeBody(IDictionary<string, string[]> headers, in JsonElement property, JsonWriterOptions writerOptions)
{
if (property.ValueKind == JsonValueKind.Null)
{
Expand All @@ -85,7 +95,7 @@ private static byte[] DeserializeBody(IDictionary<string, string[]> headers, in
if (property.ValueKind == JsonValueKind.Object)
{
using var memoryStream = new MemoryStream();
using var writer = new Utf8JsonWriter(memoryStream);
using var writer = new Utf8JsonWriter(memoryStream, writerOptions);
property.WriteTo(writer);
writer.Flush();
return memoryStream.ToArray();
Expand Down Expand Up @@ -146,19 +156,19 @@ public void Serialize(Utf8JsonWriter jsonWriter)
SerializeHeaders(jsonWriter, Request.Headers);
jsonWriter.WriteEndObject();

SerializeBody(jsonWriter, "RequestBody", Request.Body, Request.Headers);
SerializeBody(jsonWriter, "RequestBody", Request.Body, Request.Headers, RequestWriterOptions);

jsonWriter.WriteNumber(nameof(StatusCode), StatusCode);

jsonWriter.WriteStartObject("ResponseHeaders");
SerializeHeaders(jsonWriter, Response.Headers);
jsonWriter.WriteEndObject();

SerializeBody(jsonWriter, "ResponseBody", Response.Body, Response.Headers);
SerializeBody(jsonWriter, "ResponseBody", Response.Body, Response.Headers, ResponseWriterOptions);
jsonWriter.WriteEndObject();
}

private void SerializeBody(Utf8JsonWriter jsonWriter, string name, byte[] requestBody, IDictionary<string, string[]> headers)
private void SerializeBody(Utf8JsonWriter jsonWriter, string name, byte[] requestBody, IDictionary<string, string[]> headers, JsonWriterOptions writerOptions)
{
if (requestBody == null)
{
Expand All @@ -184,9 +194,9 @@ private void SerializeBody(Utf8JsonWriter jsonWriter, string name, byte[] reques
// Make sure we can replay JSON is exactly the same as the source
// for the case where service response was pre-formatted
// fallback to generic string writing
var memoryStream = new MemoryStream();
using var memoryStream = new MemoryStream();
// Settings of this writer should be in sync with the one used in deserialiation
using (var reformattedWriter = new Utf8JsonWriter(memoryStream))
using (var reformattedWriter = new Utf8JsonWriter(memoryStream, writerOptions))
{
document.RootElement.WriteTo(reformattedWriter);
}
Expand Down
2 changes: 2 additions & 0 deletions sdk/core/Azure.Core/tests/RecordSessionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.IO;
using System.Linq;
using System.Text;
using System.Text.Encodings.Web;
using System.Text.Json;
using Azure.Core.Pipeline;
using Azure.Core.TestFramework;
Expand All @@ -16,6 +17,7 @@ namespace Azure.Core.Tests
public class RecordSessionTests
{
[TestCase("{\"json\":\"value\"}", "application/json")]
[TestCase("{\"json\":\"\\\"value\\\"\"}", "application/json")]
[TestCase("{\"json\":{\"json\":\"value\"}}", "application/json")]
[TestCase("{\"json\"\n:\"value\"}", "application/json")]
[TestCase("{\"json\" :\"value\"}", "application/json")]
Expand Down