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

Serialization: Fixes call to CosmosSerializer.FromStream on Gateway mode when EnableContentResponseOnWrite is false #3814

Merged
5 commits merged into from Apr 25, 2023
Merged
Show file tree
Hide file tree
Changes from 3 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
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 @@ -10,6 +10,7 @@ namespace Microsoft.Azure.Cosmos.Core.Tests
using System.Linq;
using System.Net;
using System.Text;
using Castle.Core.Internal;
ealsur marked this conversation as resolved.
Show resolved Hide resolved
using Microsoft.Azure.Cosmos.CosmosElements;
using Microsoft.Azure.Cosmos.Query.Core;
using Microsoft.Azure.Cosmos.Scripts;
Expand All @@ -19,15 +20,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 +42,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 +144,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 +176,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 +250,27 @@ public void ValidateResponseFactoryJsonSerializer()
cosmosResponseFactory.CreateUserDefinedFunctionResponse(udfResponse);
}

[TestMethod]
public void ValidateResponseFactoryJsonSerializerWithContent()
ealsur marked this conversation as resolved.
Show resolved Hide resolved
{
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 +357,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 +414,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")]
ealsur marked this conversation as resolved.
Show resolved Hide resolved
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; }
}
}
}