From ca2b7393e4e255bf86b05e4e0fb6bee4dbdad8d3 Mon Sep 17 00:00:00 2001 From: Baltima <130716409+Baltima@users.noreply.github.com> Date: Mon, 17 Apr 2023 21:46:08 +0300 Subject: [PATCH 1/4] Do not call serializer if ResponseMessage.Content is empty. --- .../src/Resource/CosmosResponseFactoryCore.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Microsoft.Azure.Cosmos/src/Resource/CosmosResponseFactoryCore.cs b/Microsoft.Azure.Cosmos/src/Resource/CosmosResponseFactoryCore.cs index 7d9e609ba3..6f8fa9f356 100644 --- a/Microsoft.Azure.Cosmos/src/Resource/CosmosResponseFactoryCore.cs +++ b/Microsoft.Azure.Cosmos/src/Resource/CosmosResponseFactoryCore.cs @@ -271,7 +271,7 @@ public T ProcessMessage(ResponseMessage responseMessage, Func(ResponseMessage responseMessage) { - if (responseMessage.Content == null) + if (responseMessage.Content == null || responseMessage.Content.Length == 0) { return default; } From 649ed7704032c495b9398526dcd812fc7828dcca Mon Sep 17 00:00:00 2001 From: Baltima <130716409+Baltima@users.noreply.github.com> Date: Tue, 18 Apr 2023 13:11:30 +0300 Subject: [PATCH 2/4] Add unit test --- .../src/Resource/CosmosResponseFactoryCore.cs | 8 +- ...ts.cs => CosmosJsonSerializerUnitTests.cs} | 87 ++++++++++++------- 2 files changed, 65 insertions(+), 30 deletions(-) rename Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/{CosmosJsonSeriliazerUnitTests.cs => CosmosJsonSerializerUnitTests.cs} (85%) diff --git a/Microsoft.Azure.Cosmos/src/Resource/CosmosResponseFactoryCore.cs b/Microsoft.Azure.Cosmos/src/Resource/CosmosResponseFactoryCore.cs index 6f8fa9f356..14d405ffc6 100644 --- a/Microsoft.Azure.Cosmos/src/Resource/CosmosResponseFactoryCore.cs +++ b/Microsoft.Azure.Cosmos/src/Resource/CosmosResponseFactoryCore.cs @@ -271,11 +271,17 @@ public T ProcessMessage(ResponseMessage responseMessage, Func(ResponseMessage responseMessage) { - if (responseMessage.Content == null || responseMessage.Content.Length == 0) + if (responseMessage.Content == null) { return default; } + if (responseMessage.Content.Length == 0) + { + responseMessage.Content.Dispose(); + return default; + } + return this.serializerCore.FromStream(responseMessage.Content); } } diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosJsonSeriliazerUnitTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosJsonSerializerUnitTests.cs similarity index 85% rename from Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosJsonSeriliazerUnitTests.cs rename to Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosJsonSerializerUnitTests.cs index 3ff401269b..48d894ecdd 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosJsonSeriliazerUnitTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosJsonSerializerUnitTests.cs @@ -19,15 +19,15 @@ namespace Microsoft.Azure.Cosmos.Core.Tests using Newtonsoft.Json; [TestClass] - public class CosmosJsonSeriliazerUnitTests + public class CosmosJsonSerializerUnitTests { private readonly ToDoActivity toDoActivity = new ToDoActivity() { - id = "c1d433c1-369d-430e-91e5-14e3ce588f71", - taskNum = 42, - cost = double.MaxValue, - description = "cosmos json serializer", - status = "TBD" + Id = "c1d433c1-369d-430e-91e5-14e3ce588f71", + TaskNum = 42, + Cost = double.MaxValue, + Description = "cosmos json serializer", + Status = "TBD" }; private readonly string toDoActivityJson = @"{""id"":""c1d433c1-369d-430e-91e5-14e3ce588f71"",""taskNum"":42,""cost"":1.7976931348623157E+308,""description"":""cosmos json serializer"",""status"":""TBD""}"; @@ -41,11 +41,11 @@ public void ValidateSerializer() Assert.IsNotNull(stream); ToDoActivity result = cosmosDefaultJsonSerializer.FromStream(stream); Assert.IsNotNull(result); - Assert.AreEqual(this.toDoActivity.id, result.id); - Assert.AreEqual(this.toDoActivity.taskNum, result.taskNum); - Assert.AreEqual(this.toDoActivity.cost, result.cost); - Assert.AreEqual(this.toDoActivity.description, result.description); - Assert.AreEqual(this.toDoActivity.status, result.status); + Assert.AreEqual(this.toDoActivity.Id, result.Id); + Assert.AreEqual(this.toDoActivity.TaskNum, result.TaskNum); + Assert.AreEqual(this.toDoActivity.Cost, result.Cost); + Assert.AreEqual(this.toDoActivity.Description, result.Description); + Assert.AreEqual(this.toDoActivity.Status, result.Status); } } @@ -143,11 +143,11 @@ public void ValidateCustomSerializerSettings() ToDoActivity toDoActivityNoDescription = new ToDoActivity() { - id = "c1d433c1-369d-430e-91e5-14e3ce588f71", - taskNum = 42, - cost = double.MaxValue, - description = null, - status = "TBD" + Id = "c1d433c1-369d-430e-91e5-14e3ce588f71", + TaskNum = 42, + Cost = double.MaxValue, + Description = null, + Status = "TBD" }; string toDoActivityJson = @"{""id"":""c1d433c1-369d-430e-91e5-14e3ce588f71"",""taskNum"":42,""cost"":1.7976931348623157E+308,""status"":""TBD""}"; @@ -175,15 +175,9 @@ public void ValidateResponseFactoryJsonSerializer() ResponseMessage udfResponse = this.CreateResponse(); ResponseMessage itemResponse = this.CreateResponse(); - Mock mockUserJsonSerializer = new Mock(); CosmosSerializerCore serializerCore = new CosmosSerializerCore(mockUserJsonSerializer.Object); - CosmosResponseFactoryInternal cosmosResponseFactory = new CosmosResponseFactoryCore( - serializerCore); - - // Test the user specified response - mockUserJsonSerializer.Setup(x => x.FromStream(itemResponse.Content)).Callback(input => input.Dispose()).Returns(new ToDoActivity()); - mockUserJsonSerializer.Setup(x => x.FromStream(storedProcedureExecuteResponse.Content)).Callback(input => input.Dispose()).Returns(new ToDoActivity()); + CosmosResponseFactoryInternal cosmosResponseFactory = new CosmosResponseFactoryCore(serializerCore); // Verify all the user types use the user specified version ItemResponse itemResponseFromFactory = cosmosResponseFactory.CreateItemResponse(itemResponse); @@ -253,6 +247,27 @@ public void ValidateResponseFactoryJsonSerializer() cosmosResponseFactory.CreateUserDefinedFunctionResponse(udfResponse); } + [TestMethod] + public void ValidateResponseFactoryJsonSerializerWithContent() + { + ResponseMessage itemResponse = this.CreateResponseWithContent(); + + Mock mockUserJsonSerializer = new Mock(); + CosmosSerializerCore serializerCore = new CosmosSerializerCore(mockUserJsonSerializer.Object); + CosmosResponseFactoryInternal cosmosResponseFactory = new CosmosResponseFactoryCore(serializerCore); + + mockUserJsonSerializer.Setup(x => x.FromStream(itemResponse.Content)).Callback(input => input.Dispose()).Returns(new ToDoActivity()); + + // Verify all the user types use the user specified version + ItemResponse itemResponseFromFactory = cosmosResponseFactory.CreateItemResponse(itemResponse); + Assert.IsNotNull(itemResponseFromFactory.Diagnostics); + Assert.IsNotNull(itemResponseFromFactory.Resource); + Assert.AreEqual(HttpStatusCode.OK, itemResponseFromFactory.StatusCode); + + // Throw if the setups were not called + mockUserJsonSerializer.VerifyAll(); + } + [TestMethod] public void ValidateSqlQuerySpecSerializer() { @@ -339,6 +354,15 @@ private ResponseMessage CreateResponse() return cosmosResponse; } + private ResponseMessage CreateResponseWithContent() + { + ResponseMessage cosmosResponse = new ResponseMessage(statusCode: HttpStatusCode.OK) + { + Content = new MemoryStream(Encoding.UTF8.GetBytes(this.toDoActivityJson)) + }; + return cosmosResponse; + } + private ResponseMessage CreateQueryResponse() { List cosmosElements = new List(); @@ -387,13 +411,18 @@ private string GetSerializedToDoActivity() return @"{""id"":""c1d433c1-369d-430e-91e5-14e3ce588f71"",""taskNum"":42,""cost"":1.7976931348623157E+308,""status"":""TBD""}"; } - public class ToDoActivity + private class ToDoActivity { - public string id { get; set; } - public int taskNum { get; set; } - public double cost { get; set; } - public string description { get; set; } - public string status { get; set; } + [JsonProperty("id")] + public string Id { get; set; } + [JsonProperty("taskNum")] + public int TaskNum { get; set; } + [JsonProperty("cost")] + public double Cost { get; set; } + [JsonProperty("description")] + public string Description { get; set; } + [JsonProperty("status")] + public string Status { get; set; } } } } From 17454ce25a2dd43f5bf3d0b55ecf41bdd5f1911e Mon Sep 17 00:00:00 2001 From: Baltima <130716409+Baltima@users.noreply.github.com> Date: Tue, 18 Apr 2023 19:59:44 +0300 Subject: [PATCH 3/4] Update unit tests --- .../CosmosJsonSerializerUnitTests.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosJsonSerializerUnitTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosJsonSerializerUnitTests.cs index 48d894ecdd..9d559e1c22 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosJsonSerializerUnitTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosJsonSerializerUnitTests.cs @@ -10,6 +10,7 @@ namespace Microsoft.Azure.Cosmos.Core.Tests using System.Linq; using System.Net; using System.Text; + using Castle.Core.Internal; using Microsoft.Azure.Cosmos.CosmosElements; using Microsoft.Azure.Cosmos.Query.Core; using Microsoft.Azure.Cosmos.Scripts; @@ -182,6 +183,8 @@ public void ValidateResponseFactoryJsonSerializer() // Verify all the user types use the user specified version ItemResponse itemResponseFromFactory = cosmosResponseFactory.CreateItemResponse(itemResponse); Assert.IsNotNull(itemResponseFromFactory.Diagnostics); + // Verify that FromStream is not called as the stream is empty + mockUserJsonSerializer.Verify(x => x.FromStream(itemResponse.Content), Times.Never); cosmosResponseFactory.CreateStoredProcedureExecuteResponse(storedProcedureExecuteResponse); // Throw if the setups were not called From 47fd44945585644c9186ba5144a8ecafe611ef08 Mon Sep 17 00:00:00 2001 From: Baltima <130716409+Baltima@users.noreply.github.com> Date: Tue, 18 Apr 2023 20:03:51 +0300 Subject: [PATCH 4/4] Remove unused usings --- .../CosmosJsonSerializerUnitTests.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosJsonSerializerUnitTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosJsonSerializerUnitTests.cs index 9d559e1c22..8b318ad09e 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosJsonSerializerUnitTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosJsonSerializerUnitTests.cs @@ -7,10 +7,8 @@ namespace Microsoft.Azure.Cosmos.Core.Tests using System; using System.Collections.Generic; using System.IO; - using System.Linq; using System.Net; using System.Text; - using Castle.Core.Internal; using Microsoft.Azure.Cosmos.CosmosElements; using Microsoft.Azure.Cosmos.Query.Core; using Microsoft.Azure.Cosmos.Scripts;