Skip to content

Commit

Permalink
first cut, time to test
Browse files Browse the repository at this point in the history
  • Loading branch information
scbedd committed Aug 20, 2024
1 parent 2eaf22b commit 4347902
Show file tree
Hide file tree
Showing 3 changed files with 133 additions and 6 deletions.
107 changes: 107 additions & 0 deletions tools/test-proxy/Azure.Sdk.Tools.TestProxy/Common/JsonComparer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
using System.Collections.Generic;
using System.Text.Json;

namespace Azure.Sdk.Tools.TestProxy.Common
{
public class JsonComparer
{
public static List<string> CompareJson(byte[] json1, byte[] json2)
{
// Deserialize the byte arrays to JsonDocument
JsonDocument doc1 = JsonDocument.Parse(json1);
JsonDocument doc2 = JsonDocument.Parse(json2);

// Compare the JSON objects
var differences = new List<string>();
CompareElements(doc1.RootElement, doc2.RootElement, differences, "");

return differences;
}

private static void CompareElements(JsonElement element1, JsonElement element2, List<string> differences, string path)
{
if (element1.ValueKind != element2.ValueKind)
{
differences.Add($"{path}: Request and record have different types.");
return;
}

switch (element1.ValueKind)
{
case JsonValueKind.Object:
{
var properties1 = element1.EnumerateObject();
var properties2 = element2.EnumerateObject();

var propDict1 = new Dictionary<string, JsonElement>();
var propDict2 = new Dictionary<string, JsonElement>();

foreach (var prop in properties1)
propDict1[prop.Name] = prop.Value;

foreach (var prop in properties2)
propDict2[prop.Name] = prop.Value;

foreach (var key in propDict1.Keys)
{
if (propDict2.ContainsKey(key))
{
CompareElements(propDict1[key], propDict2[key], differences, $"{path}.{key}");
}
else
{
differences.Add($"{path}.{key}: Missing in request JSON");
}
}

foreach (var key in propDict2.Keys)
{
if (!propDict1.ContainsKey(key))
{
differences.Add($"{path}.{key}: Missing in record JSON");
}
}

break;
}
case JsonValueKind.Array:
{
var array1 = element1.EnumerateArray();
var array2 = element2.EnumerateArray();

int index = 0;
var enum1 = array1.GetEnumerator();
var enum2 = array2.GetEnumerator();

while (enum1.MoveNext() && enum2.MoveNext())
{
CompareElements(enum1.Current, enum2.Current, differences, $"{path}[{index}]");
index++;
}

while (enum1.MoveNext())
{
differences.Add($"{path}[{index}]: Extra element in request JSON");
index++;
}

while (enum2.MoveNext())
{
differences.Add($"{path}[{index}]: Extra element in record JSON");
index++;
}

break;
}
default:
{
if (!element1.Equals(element2))
{
differences.Add($"{path}: {element1} != {element2}");
}
break;
}
}
}
}
}
29 changes: 26 additions & 3 deletions tools/test-proxy/Azure.Sdk.Tools.TestProxy/Common/RecordMatcher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Net.Mime;
using System.Text;
using System.Web;

Expand Down Expand Up @@ -112,7 +113,10 @@ public virtual RecordEntry FindMatch(RecordEntry request, IList<RecordEntry> ent
if (!entry.IsTrack1Recording)
{
score += CompareHeaderDictionaries(request.Request.Headers, entry.Request.Headers, IgnoredHeaders, ExcludeHeaders);
score += CompareBodies(request.Request.Body, entry.Request.Body);

request.Request.TryGetContentType(out var contentType);

score += CompareBodies(request.Request.Body, entry.Request.Body, descriptionBuilder: null, contentType: contentType);
}

if (score == 0)
Expand All @@ -130,7 +134,7 @@ public virtual RecordEntry FindMatch(RecordEntry request, IList<RecordEntry> ent
throw new TestRecordingMismatchException(GenerateException(request, bestScoreEntry, entries));
}

public virtual int CompareBodies(byte[] requestBody, byte[] recordBody, StringBuilder descriptionBuilder = null)
public virtual int CompareBodies(byte[] requestBody, byte[] recordBody, string contentType, StringBuilder descriptionBuilder = null)
{
if (!_compareBodies)
{
Expand All @@ -154,7 +158,26 @@ public virtual int CompareBodies(byte[] requestBody, byte[] recordBody, StringBu
return 1;
}

if (!requestBody.SequenceEqual(recordBody))
if (!string.IsNullOrWhiteSpace(contentType) && contentType.Contains("json"))
{
var jsonDifferences = JsonComparer.CompareJson(requestBody, recordBody);

if (jsonDifferences.Count > 0)
{

if (descriptionBuilder != null)
{
descriptionBuilder.AppendLine($"There are differences between request and recordentry bodies:");
foreach (var jsonDifference in jsonDifferences)
{
descriptionBuilder.AppendLine(jsonDifference);
}
}

return 1;
}
}
else if (!requestBody.SequenceEqual(recordBody))
{
if (descriptionBuilder != null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,6 @@ public RecordEntry Lookup(RecordEntry requestEntry, RecordMatcher matcher, IEnum
{
sanitizer.Sanitize(requestEntry);
}
// normalize request body with STJ using relaxed escaping to match behavior when Deserializing from session files
RecordEntry.NormalizeJsonBody(requestEntry.Request);


RecordEntry entry = matcher.FindMatch(requestEntry, Entries);
if (remove)
Expand Down

0 comments on commit 4347902

Please sign in to comment.