Skip to content

Commit

Permalink
Serialization: Fixes call to CosmosSerializer.FromStream on Gateway m…
Browse files Browse the repository at this point in the history
…ode when EnableContentResponseOnWrite is false (#3814)

* Do not call serializer if ResponseMessage.Content is empty.

* Add unit test

* Update unit tests

* Remove unused usings

---------

Co-authored-by: Matias Quaranta <ealsur@users.noreply.github.com>
  • Loading branch information
Baltima and ealsur committed Apr 25, 2023
1 parent fb80ba8 commit 5d4f7c1
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,12 @@ public T ToObjectpublic<T>(ResponseMessage responseMessage)
return default;
}

if (responseMessage.Content.Length == 0)
{
responseMessage.Content.Dispose();
return default;
}

return this.serializerCore.FromStream<T>(responseMessage.Content);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ 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 Microsoft.Azure.Cosmos.CosmosElements;
Expand All @@ -19,15 +18,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""}";
Expand All @@ -41,11 +40,11 @@ public void ValidateSerializer()
Assert.IsNotNull(stream);
ToDoActivity result = cosmosDefaultJsonSerializer.FromStream<ToDoActivity>(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);
}
}

Expand Down Expand Up @@ -143,11 +142,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""}";
Expand Down Expand Up @@ -175,19 +174,15 @@ public void ValidateResponseFactoryJsonSerializer()
ResponseMessage udfResponse = this.CreateResponse();
ResponseMessage itemResponse = this.CreateResponse();


Mock<CosmosSerializer> mockUserJsonSerializer = new Mock<CosmosSerializer>();
CosmosSerializerCore serializerCore = new CosmosSerializerCore(mockUserJsonSerializer.Object);
CosmosResponseFactoryInternal cosmosResponseFactory = new CosmosResponseFactoryCore(
serializerCore);

// Test the user specified response
mockUserJsonSerializer.Setup(x => x.FromStream<ToDoActivity>(itemResponse.Content)).Callback<Stream>(input => input.Dispose()).Returns(new ToDoActivity());
mockUserJsonSerializer.Setup(x => x.FromStream<ToDoActivity>(storedProcedureExecuteResponse.Content)).Callback<Stream>(input => input.Dispose()).Returns(new ToDoActivity());
CosmosResponseFactoryInternal cosmosResponseFactory = new CosmosResponseFactoryCore(serializerCore);

// Verify all the user types use the user specified version
ItemResponse<ToDoActivity> itemResponseFromFactory = cosmosResponseFactory.CreateItemResponse<ToDoActivity>(itemResponse);
Assert.IsNotNull(itemResponseFromFactory.Diagnostics);
// Verify that FromStream is not called as the stream is empty
mockUserJsonSerializer.Verify(x => x.FromStream<ToDoActivity>(itemResponse.Content), Times.Never);
cosmosResponseFactory.CreateStoredProcedureExecuteResponse<ToDoActivity>(storedProcedureExecuteResponse);

// Throw if the setups were not called
Expand Down Expand Up @@ -253,6 +248,27 @@ public void ValidateResponseFactoryJsonSerializer()
cosmosResponseFactory.CreateUserDefinedFunctionResponse(udfResponse);
}

[TestMethod]
public void ValidateResponseFactoryJsonSerializerWithContent()
{
ResponseMessage itemResponse = this.CreateResponseWithContent();

Mock<CosmosSerializer> mockUserJsonSerializer = new Mock<CosmosSerializer>();
CosmosSerializerCore serializerCore = new CosmosSerializerCore(mockUserJsonSerializer.Object);
CosmosResponseFactoryInternal cosmosResponseFactory = new CosmosResponseFactoryCore(serializerCore);

mockUserJsonSerializer.Setup(x => x.FromStream<ToDoActivity>(itemResponse.Content)).Callback<Stream>(input => input.Dispose()).Returns(new ToDoActivity());

// Verify all the user types use the user specified version
ItemResponse<ToDoActivity> itemResponseFromFactory = cosmosResponseFactory.CreateItemResponse<ToDoActivity>(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()
{
Expand Down Expand Up @@ -339,6 +355,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<CosmosElement> cosmosElements = new List<CosmosElement>();
Expand Down Expand Up @@ -387,13 +412,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; }
}
}
}

0 comments on commit 5d4f7c1

Please sign in to comment.