From 684d78b2bf395d1c18f7fefdd388147e2aef16f1 Mon Sep 17 00:00:00 2001 From: Scott Beddall <45376673+scbedd@users.noreply.github.com> Date: Wed, 1 Feb 2023 17:09:29 -0800 Subject: [PATCH] [Test-Proxy] During recording, re-use existing request body (#5304) * during recording, replay the body as it is exactly * add test to ensure CompressionUtilities.DecompressBinary doesn't have a secondary affect on the input array Co-authored-by: JoshLove-msft <54595583+JoshLove-msft@users.noreply.github.com> --- .../CompressionTests.cs | 41 +++++++++++++++++++ .../RecordingHandlerTests.cs | 2 +- .../RecordingHandler.cs | 10 ++--- 3 files changed, 47 insertions(+), 6 deletions(-) create mode 100644 tools/test-proxy/Azure.Sdk.Tools.TestProxy.Tests/CompressionTests.cs diff --git a/tools/test-proxy/Azure.Sdk.Tools.TestProxy.Tests/CompressionTests.cs b/tools/test-proxy/Azure.Sdk.Tools.TestProxy.Tests/CompressionTests.cs new file mode 100644 index 00000000000..f85d569bafa --- /dev/null +++ b/tools/test-proxy/Azure.Sdk.Tools.TestProxy.Tests/CompressionTests.cs @@ -0,0 +1,41 @@ +using Azure.Sdk.Tools.TestProxy.Common; +using Azure.Sdk.Tools.TestProxy.Models; +using Azure.Sdk.Tools.TestProxy.Sanitizers; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; +using Xunit; + +namespace Azure.Sdk.Tools.TestProxy.Tests +{ + public class CompressionUtilityTests + { + [Fact] + public void EnsureDecompressionPristineBytes() + { + // generate + byte[] uncompressedBody = Encoding.UTF8.GetBytes("\"{\\u0022TableName\\u0022: \\u0022listtable09bf2a3d\\u0022}\""); + byte[] compressedBody = CompressionUtilities.CompressBodyCore(uncompressedBody, new string[] { "gzip" }); + + byte[] savedCompressedBody = new byte[compressedBody.Length]; + compressedBody.CopyTo(savedCompressedBody, 0); + + var headerDict = new HeaderDictionary(); + headerDict.Add("Content-Encoding", new string[1] { "gzip" }); + + // intentionally testing DecompressBody vs DecompressBodyCore, as that is where the header values are intercepted and treated differently + byte[] decompressedResult = CompressionUtilities.DecompressBody(compressedBody, headerDict); + + + Assert.Equal(compressedBody, savedCompressedBody); + Assert.NotEqual(decompressedResult, compressedBody); + } + + } +} diff --git a/tools/test-proxy/Azure.Sdk.Tools.TestProxy.Tests/RecordingHandlerTests.cs b/tools/test-proxy/Azure.Sdk.Tools.TestProxy.Tests/RecordingHandlerTests.cs index b08ea728633..ecb358b91c5 100644 --- a/tools/test-proxy/Azure.Sdk.Tools.TestProxy.Tests/RecordingHandlerTests.cs +++ b/tools/test-proxy/Azure.Sdk.Tools.TestProxy.Tests/RecordingHandlerTests.cs @@ -618,7 +618,7 @@ public async Task CreateEntryUsesAbsoluteUri() request.Path = uri.PathAndQuery; request.Headers["x-recording-upstream-base-uri"] = uri.AbsoluteUri; - var entry = await RecordingHandler.CreateEntryAsync(request); + var entry = (await RecordingHandler.CreateEntryAsync(request)).Item1; Assert.Equal(uri.AbsoluteUri, entry.RequestUri); } diff --git a/tools/test-proxy/Azure.Sdk.Tools.TestProxy/RecordingHandler.cs b/tools/test-proxy/Azure.Sdk.Tools.TestProxy/RecordingHandler.cs index 0206a7ad844..7544c55114c 100644 --- a/tools/test-proxy/Azure.Sdk.Tools.TestProxy/RecordingHandler.cs +++ b/tools/test-proxy/Azure.Sdk.Tools.TestProxy/RecordingHandler.cs @@ -194,9 +194,9 @@ public async Task HandleRecordRequestAsync(string recordingId, HttpRequest incom throw new HttpException(HttpStatusCode.BadRequest, $"There is no active recording session under id {recordingId}."); } - var entry = await CreateEntryAsync(incomingRequest).ConfigureAwait(false); + (RecordEntry entry, byte[] requestBody) = await CreateEntryAsync(incomingRequest).ConfigureAwait(false); - var upstreamRequest = CreateUpstreamRequest(incomingRequest, CompressionUtilities.CompressBody(entry.Request.Body, entry.Request.Headers)); + var upstreamRequest = CreateUpstreamRequest(incomingRequest, requestBody); HttpResponseMessage upstreamResponse = null; @@ -432,7 +432,7 @@ public async Task HandlePlaybackRequest(string recordingId, HttpRequest incoming throw new HttpException(HttpStatusCode.BadRequest, $"There is no active playback session under recording id {recordingId}."); } - var entry = await CreateEntryAsync(incomingRequest).ConfigureAwait(false); + var entry = (await CreateEntryAsync(incomingRequest).ConfigureAwait(false)).Item1; // If request contains "x-recording-remove: false", then request is not removed from session after playback. // Used by perf tests to play back the same request multiple times. @@ -470,7 +470,7 @@ public async Task HandlePlaybackRequest(string recordingId, HttpRequest incoming } } - public static async Task CreateEntryAsync(HttpRequest request) + public static async Task<(RecordEntry, byte[])> CreateEntryAsync(HttpRequest request) { var entry = new RecordEntry(); entry.RequestUri = GetRequestUri(request).AbsoluteUri; @@ -487,7 +487,7 @@ public static async Task CreateEntryAsync(HttpRequest request) byte[] bytes = await ReadAllBytes(request.Body).ConfigureAwait(false); entry.Request.Body = CompressionUtilities.DecompressBody(bytes, request.Headers); - return entry; + return (entry, bytes); } #endregion