Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
21 changes: 20 additions & 1 deletion src/Orleans.Core.Abstractions/IDs/GrainId.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.Serialization;
using System.Text;
using System.Text.Json;
Expand Down Expand Up @@ -222,8 +223,19 @@ public override GrainId Read(ref Utf8JsonReader reader, Type typeToConvert, Json
return GrainId.Parse(buf);
}

/// <inheritdoc />
public override GrainId ReadAsPropertyName(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
=> Read(ref reader, typeToConvert, options);

/// <inheritdoc />
public override void Write(Utf8JsonWriter writer, GrainId value, JsonSerializerOptions options)
=> WriteGrainId(writer, value, isPropertyName: false);

/// <inheritdoc />
public override void WriteAsPropertyName(Utf8JsonWriter writer, [DisallowNull] GrainId value, JsonSerializerOptions options)
=> WriteGrainId(writer, value, isPropertyName: true);

private static void WriteGrainId(Utf8JsonWriter writer, GrainId value, bool isPropertyName)
{
var type = value.Type.AsSpan();
var key = value.Key.AsSpan();
Expand All @@ -233,7 +245,14 @@ public override void Write(Utf8JsonWriter writer, GrainId value, JsonSerializerO
buf[type.Length] = (byte)'/';
key.CopyTo(buf[(type.Length + 1)..]);

writer.WriteStringValue(buf);
if (isPropertyName)
{
writer.WritePropertyName(buf);
}
else
{
writer.WriteStringValue(buf);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TestExtensions;
using UnitTests.GrainInterfaces;
using Xunit;

namespace DefaultCluster.Tests;

[TestCategory("Serialization"), TestCategory("BVT")]
public class JsonSerializerTests : HostedTestClusterEnsureDefaultStarted
{
public JsonSerializerTests(DefaultClusterFixture fixture) : base(fixture)
{
}

[Fact, TestCategory("BVT"), TestCategory("Serialization")]
public void Serialization_GrainId_RoundTrip()
{
var grainId = GrainId.Create("type", "key");
var copy = HostedCluster.RoundTripSystemTextJsonSerialization(grainId);

Assert.IsAssignableFrom<GrainId>(copy);
Assert.Equal(grainId, copy);
}

[Fact, TestCategory("BVT"), TestCategory("Serialization")]
public void Serialization_WithGrainIdType_RoundTrip()
{
var grainId = GrainId.Create("type", "key");
WithGrainIdType data = new(grainId);

var copy = HostedCluster.RoundTripSystemTextJsonSerialization(data);

Assert.IsAssignableFrom<WithGrainIdType>(copy);
Assert.Equal(grainId, copy.GrainId);
}

[Fact, TestCategory("BVT"), TestCategory("Serialization")]
public void Serialization_WithGrainIdMapType_RoundTrip()
{
var grainId1 = GrainId.Create("type1", "key1");
var grainId2 = GrainId.Create("type2", "key2");

var map = new Dictionary<GrainId, int>();
map.Add(grainId1, 1);
map.Add(grainId2, 2);

WithGrainIdMapType data = new(map);

var copy = HostedCluster.RoundTripSystemTextJsonSerialization(data);

Assert.IsAssignableFrom<WithGrainIdMapType>(copy);
Assert.Equal(map, copy.Map);
}

[Fact, TestCategory("BVT"), TestCategory("Serialization")]
public void Serialization_WithGrainIdConcurrentDictionaryType_RoundTrip()
{
var grainId = GrainId.Create("type", "key");
var map = new ConcurrentDictionary<GrainId, int>();
map.TryAdd(grainId, 1);

WithGrainIdMapType data = new(map);

var copy = HostedCluster.RoundTripSystemTextJsonSerialization(data);

Assert.IsAssignableFrom<WithGrainIdMapType>(copy);
Assert.Equal(map, copy.Map);
}

[Fact, TestCategory("BVT"), TestCategory("Serialization")]
public void Serialization_WithGrainIdHashSetType_RoundTrip()
{
var grainId = GrainId.Create("type", "key");
var set = new HashSet<GrainId>();
set.Add(grainId);

WithGrainIdSetType data = new(set);

var copy = HostedCluster.RoundTripSystemTextJsonSerialization(data);

Assert.IsAssignableFrom<WithGrainIdSetType>(copy);
Assert.Equal(set, copy.Set);
}
}
32 changes: 31 additions & 1 deletion test/Grains/TestGrainInterfaces/IValueTypeTestGrain.cs
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,36 @@ public DefaultActivatorValueTypeWithRequiredField(int value)
}
}

public struct WithGrainIdType
{
public GrainId GrainId { get; set; }

public WithGrainIdType(GrainId grainId)
{
GrainId = grainId;
}
}

public struct WithGrainIdMapType
{
public IDictionary<GrainId, int> Map { get; set; }

public WithGrainIdMapType(IDictionary<GrainId, int> map)
{
Map = map;
}
}

public struct WithGrainIdSetType
{
public ISet<GrainId> Set { get; set; }

public WithGrainIdSetType(ISet<GrainId> set)
{
Set = set;
}
}

[UseActivator]
[Serializable]
[GenerateSerializer]
Expand All @@ -240,4 +270,4 @@ public DefaultActivatorValueTypeWithUseActivator()
Value = 4;
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Text.Json;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Orleans.Serialization;
Expand Down Expand Up @@ -28,6 +29,12 @@ protected HostedTestClusterEnsureDefaultStarted(DefaultClusterFixture fixture)

public static class TestClusterExtensions
{
public static T RoundTripSystemTextJsonSerialization<T>(this TestCluster cluster, T value)
{
var serialized = JsonSerializer.Serialize<T>(value);
return JsonSerializer.Deserialize<T>(serialized);
}

public static T RoundTripSerializationForTesting<T>(this TestCluster cluster, T value)
{
var serializer = cluster.ServiceProvider.GetRequiredService<Serializer>();
Expand Down