diff --git a/src/Orleans.Core/Core/GrainInterfaceTypeToGrainTypeResolver.cs b/src/Orleans.Core/Core/GrainInterfaceTypeToGrainTypeResolver.cs
index 416ba6d5f2..121749be45 100644
--- a/src/Orleans.Core/Core/GrainInterfaceTypeToGrainTypeResolver.cs
+++ b/src/Orleans.Core/Core/GrainInterfaceTypeToGrainTypeResolver.cs
@@ -86,7 +86,7 @@ public GrainType GetGrainType(GrainInterfaceType interfaceType, string prefix)
if (GenericGrainType.TryParse(result, out var genericGrainType) && !genericGrainType.IsConstructed)
{
- result = genericGrainType.GrainType.GetConstructed(genericInterface.Value);
+ result = genericGrainType.GetConstructed(genericInterface);
}
return result;
@@ -149,7 +149,7 @@ public bool TryGetGrainType(GrainInterfaceType interfaceType, out GrainType resu
}
else
{
- result = genericGrainType.GrainType.GetConstructed(genericInterface.Value);
+ result = genericGrainType.GetConstructed(genericInterface);
}
}
else
diff --git a/src/Orleans.Core/IDs/GenericGrainInterfaceType.cs b/src/Orleans.Core/IDs/GenericGrainInterfaceType.cs
index 52a413c702..189b7052cd 100644
--- a/src/Orleans.Core/IDs/GenericGrainInterfaceType.cs
+++ b/src/Orleans.Core/IDs/GenericGrainInterfaceType.cs
@@ -1,4 +1,5 @@
using System;
+using System.Diagnostics.CodeAnalysis;
using Orleans.Serialization.TypeSystem;
using Orleans.Utilities;
@@ -14,9 +15,10 @@ public readonly struct GenericGrainInterfaceType
/// Initializes a new instance of the struct.
///
/// The underlying grain interface type.
- private GenericGrainInterfaceType(GrainInterfaceType value)
+ private GenericGrainInterfaceType(GrainInterfaceType value, int arity)
{
Value = value;
+ Arity = arity;
}
///
@@ -24,6 +26,11 @@ private GenericGrainInterfaceType(GrainInterfaceType value)
///
public GrainInterfaceType Value { get; }
+ ///
+ /// The arity of the generic type.
+ ///
+ public int Arity { get; }
+
///
/// Returns if this instance contains concrete type parameters.
///
@@ -34,9 +41,16 @@ private GenericGrainInterfaceType(GrainInterfaceType value)
///
public static bool TryParse(GrainInterfaceType grainType, out GenericGrainInterfaceType result)
{
- if (!grainType.IsDefault && TypeConverterExtensions.IsGenericType(grainType.Value))
+ if (grainType.IsDefault)
+ {
+ result = default;
+ return false;
+ }
+
+ var arity = TypeConverterExtensions.GetGenericTypeArity(grainType.Value);
+ if (arity > 0)
{
- result = new GenericGrainInterfaceType(grainType);
+ result = new GenericGrainInterfaceType(grainType, arity);
return true;
}
@@ -50,7 +64,7 @@ public static bool TryParse(GrainInterfaceType grainType, out GenericGrainInterf
public GenericGrainInterfaceType GetGenericGrainType()
{
var generic = TypeConverterExtensions.GetDeconstructed(Value.Value);
- return new GenericGrainInterfaceType(new GrainInterfaceType(generic));
+ return new GenericGrainInterfaceType(new GrainInterfaceType(generic), Arity);
}
///
@@ -58,8 +72,13 @@ public GenericGrainInterfaceType GetGenericGrainType()
///
public GenericGrainInterfaceType Construct(TypeConverter formatter, params Type[] typeArguments)
{
+ if (Arity != typeArguments.Length)
+ {
+ ThrowIncorrectArgumentLength(typeArguments);
+ }
+
var constructed = formatter.GetConstructed(this.Value.Value, typeArguments);
- return new GenericGrainInterfaceType(new GrainInterfaceType(constructed));
+ return new GenericGrainInterfaceType(new GrainInterfaceType(constructed), Arity);
}
///
@@ -71,5 +90,8 @@ public GenericGrainInterfaceType Construct(TypeConverter formatter, params Type[
/// Returns a UTF8 interpretation of the current instance.
///
public override string ToString() => Value.ToString();
+
+ [DoesNotReturn]
+ private void ThrowIncorrectArgumentLength(Type[] typeArguments) => throw new ArgumentException($"Incorrect number of type arguments, {typeArguments.Length}, to construct a generic grain type with arity {Arity}.", nameof(typeArguments));
}
}
diff --git a/src/Orleans.Core/IDs/GenericGrainType.cs b/src/Orleans.Core/IDs/GenericGrainType.cs
index 93b8d3dde7..c57a353fab 100644
--- a/src/Orleans.Core/IDs/GenericGrainType.cs
+++ b/src/Orleans.Core/IDs/GenericGrainType.cs
@@ -1,4 +1,6 @@
using System;
+using System.Diagnostics.CodeAnalysis;
+using System.Runtime.InteropServices;
using Orleans.Serialization.TypeSystem;
using Orleans.Utilities;
@@ -14,9 +16,11 @@ namespace Orleans.Runtime
/// Initializes a new instance of the struct.
///
/// The underlying grain type.
- private GenericGrainType(GrainType grainType)
+ /// The generic arity of the grain type.
+ private GenericGrainType(GrainType grainType, int arity)
{
GrainType = grainType;
+ Arity = arity;
}
///
@@ -24,6 +28,11 @@ private GenericGrainType(GrainType grainType)
///
public GrainType GrainType { get; }
+ ///
+ /// The generic arity of the grain type.
+ ///
+ public int Arity { get; }
+
///
/// Returns if this instance contains concrete type parameters.
///
@@ -34,9 +43,10 @@ private GenericGrainType(GrainType grainType)
///
public static bool TryParse(GrainType grainType, out GenericGrainType result)
{
- if (TypeConverterExtensions.IsGenericType(grainType.Value))
+ var arity = TypeConverterExtensions.GetGenericTypeArity(grainType.Value);
+ if (arity > 0)
{
- result = new GenericGrainType(grainType);
+ result = new GenericGrainType(grainType, arity);
return true;
}
@@ -50,7 +60,7 @@ public static bool TryParse(GrainType grainType, out GenericGrainType result)
public GenericGrainType GetUnconstructedGrainType()
{
var generic = TypeConverterExtensions.GetDeconstructed(GrainType.Value);
- return new GenericGrainType(new GrainType(generic));
+ return new GenericGrainType(new GrainType(generic), Arity);
}
///
@@ -58,13 +68,21 @@ public GenericGrainType GetUnconstructedGrainType()
///
public GenericGrainType Construct(TypeConverter formatter, params Type[] typeArguments)
{
+ if (Arity != typeArguments.Length)
+ {
+ ThrowIncorrectArgumentLength(typeArguments);
+ }
+
var constructed = formatter.GetConstructed(this.GrainType.Value, typeArguments);
- return new GenericGrainType(new GrainType(constructed));
+ return new GenericGrainType(new GrainType(constructed), Arity);
}
+
///
- /// Returns the type arguments which this instance was constructed with.
+ /// Gets the type arguments using the provided type converter.
///
- public Type[] GetArguments(TypeConverter formatter) => formatter.GetArguments(this.GrainType.Value);
+ /// The type converter
+ /// The type arguments.
+ public Type[] GetArguments(TypeConverter converter) => converter.GetArguments(this.GrainType.Value);
///
public override string ToString() => this.GrainType.ToString();
@@ -77,5 +95,8 @@ public GenericGrainType Construct(TypeConverter formatter, params Type[] typeArg
///
public override int GetHashCode() => this.GrainType.GetHashCode();
+
+ [DoesNotReturn]
+ private void ThrowIncorrectArgumentLength(Type[] typeArguments) => throw new ArgumentException($"Incorrect number of type arguments, {typeArguments.Length}, to construct a generic grain type with arity {Arity}.", nameof(typeArguments));
}
}
diff --git a/src/Orleans.Core/Manifest/GrainTypeResolver.cs b/src/Orleans.Core/Manifest/GrainTypeResolver.cs
index 8a01c56d6b..72624e7a9d 100644
--- a/src/Orleans.Core/Manifest/GrainTypeResolver.cs
+++ b/src/Orleans.Core/Manifest/GrainTypeResolver.cs
@@ -95,7 +95,8 @@ private GrainType AddGenericParameters(GrainType grainType, Type type)
&& !type.ContainsGenericParameters
&& !genericGrainType.IsConstructed)
{
- grainType = genericGrainType.Construct(_typeConverter, type.GetGenericArguments()).GrainType;
+ var typeArguments = type.GetGenericArguments();
+ grainType = genericGrainType.Construct(_typeConverter, typeArguments).GrainType;
}
return grainType;
diff --git a/src/Orleans.Core/Utils/TypeConverterExtensions.cs b/src/Orleans.Core/Utils/TypeConverterExtensions.cs
index 6d9f67f06a..026e72e573 100644
--- a/src/Orleans.Core/Utils/TypeConverterExtensions.cs
+++ b/src/Orleans.Core/Utils/TypeConverterExtensions.cs
@@ -1,5 +1,6 @@
using System;
using System.Buffers.Text;
+using System.Diagnostics.CodeAnalysis;
using System.Text;
using Orleans.Runtime;
using Orleans.Serialization.TypeSystem;
@@ -19,6 +20,36 @@ internal static class TypeConverterExtensions
///
public static bool IsGenericType(IdSpan type) => type.AsSpan().IndexOf((byte)GenericTypeIndicator) >= 0;
+ ///
+ /// Returns the generic arity of the specified grain type.
+ ///
+ public static int GetGenericTypeArity(IdSpan type)
+ {
+ var typeSpan = type.AsSpan();
+ var startIndex = typeSpan.IndexOf((byte)GenericTypeIndicator) + 1;
+ if (startIndex <= 0 || startIndex >= typeSpan.Length)
+ {
+ return 0;
+ }
+
+ int endIndex;
+ for (endIndex = startIndex; endIndex < typeSpan.Length; endIndex++)
+ {
+ var c = typeSpan[endIndex];
+ if (c is < ((byte)'0') or > ((byte)'9'))
+ {
+ break;
+ }
+ }
+
+ if (endIndex > startIndex && Utf8Parser.TryParse(typeSpan[startIndex..endIndex], out int arity, out _))
+ {
+ return arity;
+ }
+
+ throw new InvalidOperationException($"Unable to parse arity from type \"{type}\"");
+ }
+
///
/// Returns true if the provided type string is a constructed generic type.
///
@@ -65,8 +96,15 @@ public static IdSpan GetConstructed(this TypeConverter formatter, IdSpan unconst
///
/// Returns the constructed form of the provided generic grain type using the type arguments from the provided constructed interface type.
///
- public static GrainType GetConstructed(this GrainType grainType, GrainInterfaceType typeArguments)
+ public static GrainType GetConstructed(this GenericGrainType genericGrainType, GenericGrainInterfaceType genericGrainInterfaceType)
{
+ if (genericGrainType.Arity != genericGrainInterfaceType.Arity)
+ {
+ ThrowGenericArityMismatch(genericGrainType, genericGrainInterfaceType);
+ }
+
+ var grainType = genericGrainType.GrainType;
+ var typeArguments = genericGrainInterfaceType.Value;
var args = typeArguments.Value.AsSpan();
var index = args.IndexOf((byte)StartArgument);
if (index <= 0) return grainType; // if no type arguments are provided, then the current logic expects the unconstructed form (but the grain call is going to fail later anyway...)
@@ -112,5 +150,9 @@ public static Type[] GetArguments(this TypeConverter formatter, IdSpan construct
return result;
}
+
+ [DoesNotReturn]
+ private static void ThrowGenericArityMismatch(GenericGrainType genericGrainType, GenericGrainInterfaceType genericInterfaceType)
+ => throw new ArgumentException($"Cannot construct generic grain \"{genericGrainType.GrainType}\" using arguments from generic interface \"{genericInterfaceType}\" because the generic arities are not equal: {genericGrainType.Arity} is not equal to {genericInterfaceType.Arity}.");
}
}
diff --git a/test/DefaultCluster.Tests/GenericGrainTests.cs b/test/DefaultCluster.Tests/GenericGrainTests.cs
index e00abd5b3b..1db9272514 100644
--- a/test/DefaultCluster.Tests/GenericGrainTests.cs
+++ b/test/DefaultCluster.Tests/GenericGrainTests.cs
@@ -11,6 +11,7 @@ namespace DefaultCluster.Tests.General
///
/// Unit tests for grains implementing generic interfaces
///
+ [TestCategory("BVT"), TestCategory("Generics")]
public class GenericGrainTests : HostedTestClusterEnsureDefaultStarted
{
private static int grainId = 0;
@@ -21,17 +22,17 @@ public GenericGrainTests(DefaultClusterFixture fixture) : base(fixture)
public TGrainInterface GetGrain(long i) where TGrainInterface : IGrainWithIntegerKey
{
- return this.GrainFactory.GetGrain(i);
+ return this.GrainFactory.GetGrain(i);
}
public TGrainInterface GetGrain() where TGrainInterface : IGrainWithIntegerKey
{
- return this.GrainFactory.GetGrain(GetRandomGrainId());
+ return this.GrainFactory.GetGrain(GetRandomGrainId());
}
/// Can instantiate multiple concrete grain types that implement
/// different specializations of the same generic interface
- [Fact, TestCategory("BVT"), TestCategory("Generics")]
+ [Fact]
public async Task GenericGrainTests_ConcreteGrainWithGenericInterfaceGetGrain()
{
var grainOfIntFloat1 = GetGrain>();
@@ -52,7 +53,7 @@ public async Task GenericGrainTests_ConcreteGrainWithGenericInterfaceGetGrain()
}
/// Multiple GetGrain requests with the same id return the same concrete grain
- [Fact, TestCategory("BVT"), TestCategory("Generics")]
+ [Fact]
public async Task GenericGrainTests_ConcreteGrainWithGenericInterfaceMultiplicity()
{
var grainId = GetRandomGrainId();
@@ -67,7 +68,7 @@ public async Task GenericGrainTests_ConcreteGrainWithGenericInterfaceMultiplicit
}
/// Can instantiate generic grain specializations
- [Theory, TestCategory("BVT"), TestCategory("Generics")]
+ [Theory]
[InlineData(1.2f)]
[InlineData(3.4f)]
[InlineData("5.6")]
@@ -80,13 +81,13 @@ public async Task GenericGrainTests_SimpleGenericGrainGetGrain(T setValue)
// generic grain implementation does not change the set value:
await grain.Transform();
-
+
T result = await grain.Get();
-
- Assert.Equal(setValue, result);
+
+ Assert.Equal(setValue, result);
}
- [Fact, TestCategory("BVT"), TestCategory("Generics")]
+ [Fact]
public async Task GenericGrainTests_SimpleGenericGrainGetGrain_ArrayTypeParameter()
{
var grain = GetGrain>();
@@ -96,13 +97,13 @@ public async Task GenericGrainTests_SimpleGenericGrainGetGrain_ArrayTypeParamete
// generic grain implementation does not change the set value:
await grain.Transform();
-
+
var result = await grain.Get();
-
- Assert.Equal(expected, result);
+
+ Assert.Equal(expected, result);
}
- [Fact, TestCategory("BVT"), TestCategory("Generics")]
+ [Fact]
public async Task GenericGrainTests_GenericGrainInheritingArray()
{
var grain = GetGrain>();
@@ -111,12 +112,12 @@ public async Task GenericGrainTests_GenericGrainInheritingArray()
await grain.Set(expected);
var result = await grain.Get();
-
- Assert.Equal(expected, result);
+
+ Assert.Equal(expected, result);
}
/// Can instantiate grains that implement generic interfaces with generic type parameters
- [Fact, TestCategory("BVT"), TestCategory("Generics")]
+ [Fact]
public async Task GenericGrainTests_GenericInterfaceWithGenericParametersGetGrain()
{
@@ -133,7 +134,7 @@ public async Task GenericGrainTests_GenericInterfaceWithGenericParametersGetGrai
/// Multiple GetGrain requests with the same id return the same generic grain specialization
- [Fact, TestCategory("BVT"), TestCategory("Generics")]
+ [Fact]
public async Task GenericGrainTests_SimpleGenericGrainMultiplicity()
{
var grainId = GetRandomGrainId();
@@ -150,7 +151,7 @@ public async Task GenericGrainTests_SimpleGenericGrainMultiplicity()
/// If both a concrete implementation and a generic implementation of a
/// generic interface exist, prefer the concrete implementation.
- [Fact, TestCategory("BVT"), TestCategory("Generics")]
+ [Fact]
public async Task GenericGrainTests_PreferConcreteGrainImplementationOfGenericInterface()
{
var grainOfDouble1 = GetGrain>();
@@ -171,7 +172,7 @@ public async Task GenericGrainTests_PreferConcreteGrainImplementationOfGenericIn
}
/// Multiple GetGrain requests with the same id return the same concrete grain implementation
- [Fact, TestCategory("BVT"), TestCategory("Generics")]
+ [Fact]
public async Task GenericGrainTests_PreferConcreteGrainImplementationOfGenericInterfaceMultiplicity()
{
var grainId = GetRandomGrainId();
@@ -189,7 +190,7 @@ public async Task GenericGrainTests_PreferConcreteGrainImplementationOfGenericIn
}
/// Can instantiate concrete grains that implement multiple generic interfaces
- [Fact, TestCategory("BVT"), TestCategory("Generics")]
+ [Fact]
public async Task GenericGrainTests_ConcreteGrainWithMultipleGenericInterfacesGetGrain()
{
var grain1 = GetGrain>();
@@ -210,7 +211,7 @@ public async Task GenericGrainTests_ConcreteGrainWithMultipleGenericInterfacesGe
}
/// Multiple GetGrain requests with the same id and interface return the same concrete grain implementation
- [Fact, TestCategory("BVT"), TestCategory("Generics")]
+ [Fact]
public async Task GenericGrainTests_ConcreteGrainWithMultipleGenericInterfacesMultiplicity1()
{
var grainId = GetRandomGrainId();
@@ -230,7 +231,7 @@ public async Task GenericGrainTests_ConcreteGrainWithMultipleGenericInterfacesMu
}
/// Multiple GetGrain requests with the same id and different interfaces return the same concrete grain implementation
- [Fact, TestCategory("BVT"), TestCategory("Generics")]
+ [Fact]
public async Task GenericGrainTests_ConcreteGrainWithMultipleGenericInterfacesMultiplicity2()
{
var grainId = GetRandomGrainId();
@@ -248,7 +249,7 @@ public async Task GenericGrainTests_ConcreteGrainWithMultipleGenericInterfacesMu
Assert.Equal("100", floatResult);
}
- [Fact, TestCategory("BVT"), TestCategory("Generics")]
+ [Fact]
public async Task GenericGrainTests_UseGenericFactoryInsideGrain()
{
var grainId = GetRandomGrainId();
@@ -259,21 +260,21 @@ public async Task GenericGrainTests_UseGenericFactoryInsideGrain()
}
- [Fact, TestCategory("BVT"), TestCategory("Generics")]
+ [Fact]
public async Task Generic_SimpleGrain_GetGrain()
{
- var grain = this.GrainFactory.GetGrain>(grainId++);
+ var grain = this.GrainFactory.GetGrain>(grainId++);
await grain.GetA();
}
- [Fact, TestCategory("BVT"), TestCategory("Generics")]
+ [Fact]
public async Task Generic_SimpleGrainControlFlow()
{
var a = Random.Shared.Next(100);
var b = a + 1;
var expected = a + "x" + b;
- var grain = this.GrainFactory.GetGrain>(grainId++);
+ var grain = this.GrainFactory.GetGrain>(grainId++);
await grain.SetA(a);
@@ -283,14 +284,14 @@ public async Task Generic_SimpleGrainControlFlow()
Assert.Equal(expected, stringPromise.Result);
}
- [Fact, TestCategory("BVT"), TestCategory("Generics")]
+ [Fact]
public void Generic_SimpleGrainControlFlow_Blocking()
{
var a = Random.Shared.Next(100);
var b = a + 1;
var expected = a + "x" + b;
- var grain = this.GrainFactory.GetGrain>(grainId++);
+ var grain = this.GrainFactory.GetGrain>(grainId++);
// explicitly use .Wait() and .Result to make sure the client does not deadlock in these cases.
grain.SetA(a).Wait();
@@ -301,14 +302,14 @@ public void Generic_SimpleGrainControlFlow_Blocking()
Assert.Equal(expected, stringPromise.Result);
}
- [Fact, TestCategory("BVT"), TestCategory("Generics")]
+ [Fact]
public async Task Generic_SimpleGrainDataFlow()
{
var a = Random.Shared.Next(100);
var b = a + 1;
var expected = a + "x" + b;
- var grain = this.GrainFactory.GetGrain>(grainId++);
+ var grain = this.GrainFactory.GetGrain>(grainId++);
var setAPromise = grain.SetA(a);
var setBPromise = grain.SetB(b);
@@ -318,34 +319,34 @@ public async Task Generic_SimpleGrainDataFlow()
Assert.Equal(expected, x);
}
- [Fact, TestCategory("BVT"), TestCategory("Generics")]
+ [Fact]
public async Task Generic_SimpleGrain2_GetGrain()
{
- var g1 = this.GrainFactory.GetGrain>(grainId++);
- var g2 = this.GrainFactory.GetGrain>(grainId++);
- var g3 = this.GrainFactory.GetGrain>(grainId++);
+ var g1 = this.GrainFactory.GetGrain>(grainId++);
+ var g2 = this.GrainFactory.GetGrain>(grainId++);
+ var g3 = this.GrainFactory.GetGrain>(grainId++);
await g1.GetA();
await g2.GetA();
await g3.GetA();
}
- [Fact, TestCategory("BVT"), TestCategory("Generics")]
+ [Fact]
public async Task Generic_SimpleGrainGenericParameterWithMultipleArguments_GetGrain()
{
- var g1 = this.GrainFactory.GetGrain>>(GetRandomGrainId());
+ var g1 = this.GrainFactory.GetGrain>>(GetRandomGrainId());
await g1.GetA();
}
- [Fact, TestCategory("BVT"), TestCategory("Generics")]
+ [Fact]
public async Task Generic_SimpleGrainControlFlow2_GetAB()
{
var a = Random.Shared.Next(100);
var b = a + 1;
var expected = a + "x" + b;
- var g1 = this.GrainFactory.GetGrain>(grainId++);
- var g2 = this.GrainFactory.GetGrain>(grainId++);
- var g3 = this.GrainFactory.GetGrain>(grainId++);
+ var g1 = this.GrainFactory.GetGrain>(grainId++);
+ var g2 = this.GrainFactory.GetGrain>(grainId++);
+ var g3 = this.GrainFactory.GetGrain>(grainId++);
string r1 = await g1.GetAxB(a, b);
string r2 = await g2.GetAxB(a, b);
@@ -355,31 +356,31 @@ public async Task Generic_SimpleGrainControlFlow2_GetAB()
Assert.Equal(expected, r3);
}
- [Fact, TestCategory("BVT"), TestCategory("Generics")]
+ [Fact]
public async Task Generic_SimpleGrainControlFlow3()
{
- ISimpleGenericGrain2 g = this.GrainFactory.GetGrain>(grainId++);
+ ISimpleGenericGrain2 g = this.GrainFactory.GetGrain>(grainId++);
await g.SetA(3);
await g.SetB(1.25f);
Assert.Equal("3x1.25", await g.GetAxB());
}
- [Fact, TestCategory("BVT"), TestCategory("Generics")]
+ [Fact]
public async Task Generic_BasicGrainControlFlow()
{
- IBasicGenericGrain g = this.GrainFactory.GetGrain>(0);
+ IBasicGenericGrain g = this.GrainFactory.GetGrain>(0);
await g.SetA(3);
await g.SetB(1.25f);
Assert.Equal("3x1.25", await g.GetAxB());
}
- [Fact, TestCategory("BVT"), TestCategory("Generics")]
+ [Fact]
public async Task GrainWithListFields()
{
string a = Random.Shared.Next(100).ToString(CultureInfo.InvariantCulture);
string b = Random.Shared.Next(100).ToString(CultureInfo.InvariantCulture);
- var g1 = this.GrainFactory.GetGrain(grainId++);
+ var g1 = this.GrainFactory.GetGrain(grainId++);
var p1 = g1.AddItem(a);
var p2 = g1.AddItem(b);
@@ -392,14 +393,14 @@ public async Task GrainWithListFields()
string.Format("Result: r[0]={0}, r[1]={1}", r1[0], r1[1]));
}
- [Fact, TestCategory("BVT"), TestCategory("Generics")]
+ [Fact]
public async Task Generic_GrainWithListFields()
{
int a = Random.Shared.Next(100);
int b = Random.Shared.Next(100);
- var g1 = this.GrainFactory.GetGrain>(grainId++);
+ var g1 = this.GrainFactory.GetGrain>(grainId++);
var p1 = g1.AddItem(a);
var p2 = g1.AddItem(b);
@@ -412,20 +413,20 @@ public async Task Generic_GrainWithListFields()
string.Format("Result: r[0]={0}, r[1]={1}", r1[0], r1[1]));
}
- [Fact, TestCategory("BVT"), TestCategory("Generics")]
+ [Fact]
public async Task Generic_GrainWithNoProperties_ControlFlow()
{
int a = Random.Shared.Next(100);
int b = Random.Shared.Next(100);
string expected = a + "x" + b;
- var g1 = this.GrainFactory.GetGrain>(grainId++);
+ var g1 = this.GrainFactory.GetGrain>(grainId++);
string r1 = await g1.GetAxB(a, b);
Assert.Equal(expected, r1);
}
- [Fact, TestCategory("BVT"), TestCategory("Generics")]
+ [Fact]
public async Task GrainWithNoProperties_ControlFlow()
{
int a = Random.Shared.Next(100);
@@ -433,29 +434,29 @@ public async Task GrainWithNoProperties_ControlFlow()
string expected = a + "x" + b;
long grainId = GetRandomGrainId();
- var g1 = this.GrainFactory.GetGrain(grainId);
+ var g1 = this.GrainFactory.GetGrain(grainId);
string r1 = await g1.GetAxB(a, b);
Assert.Equal(expected, r1);
}
- [Fact, TestCategory("BVT"), TestCategory("Generics")]
+ [Fact]
public async Task Generic_ReaderWriterGrain1()
{
int a = Random.Shared.Next(100);
- var g = this.GrainFactory.GetGrain>(grainId++);
+ var g = this.GrainFactory.GetGrain>(grainId++);
await g.SetValue(a);
var res = await g.GetValue();
Assert.Equal(a, res);
}
- [Fact, TestCategory("BVT"), TestCategory("Generics")]
+ [Fact]
public async Task Generic_ReaderWriterGrain2()
{
int a = Random.Shared.Next(100);
string b = "bbbbb";
- var g = this.GrainFactory.GetGrain>(grainId++);
+ var g = this.GrainFactory.GetGrain>(grainId++);
await g.SetValue1(a);
await g.SetValue2(b);
var r1 = await g.GetValue1();
@@ -464,14 +465,14 @@ public async Task Generic_ReaderWriterGrain2()
Assert.Equal(b, r2);
}
- [Fact, TestCategory("BVT"), TestCategory("Generics")]
+ [Fact]
public async Task Generic_ReaderWriterGrain3()
{
int a = Random.Shared.Next(100);
string b = "bbbbb";
double c = 3.145;
- var g = this.GrainFactory.GetGrain>(grainId++);
+ var g = this.GrainFactory.GetGrain>(grainId++);
await g.SetValue1(a);
await g.SetValue2(b);
await g.SetValue3(c);
@@ -483,12 +484,12 @@ public async Task Generic_ReaderWriterGrain3()
Assert.Equal(c, r3);
}
- [Fact, TestCategory("BVT"), TestCategory("Generics")]
+ [Fact]
public async Task Generic_Non_Primitive_Type_Argument()
{
- IEchoHubGrain g1 = this.GrainFactory.GetGrain>(1);
- IEchoHubGrain g2 = this.GrainFactory.GetGrain>(1);
- IEchoHubGrain g3 = this.GrainFactory.GetGrain>(1);
+ IEchoHubGrain g1 = this.GrainFactory.GetGrain>(1);
+ IEchoHubGrain g2 = this.GrainFactory.GetGrain>(1);
+ IEchoHubGrain g3 = this.GrainFactory.GetGrain>(1);
Assert.NotEqual((GrainReference)g1, (GrainReference)g2);
Assert.NotEqual((GrainReference)g1, (GrainReference)g3);
@@ -503,40 +504,40 @@ public async Task Generic_Non_Primitive_Type_Argument()
Assert.Equal(3m, await g3.GetX());
}
- [Fact, TestCategory("BVT"), TestCategory("Generics")]
+ [Fact]
public async Task Generic_Echo_Chain_1()
{
const string msg1 = "Hello from EchoGenericChainGrain-1";
- IEchoGenericChainGrain g1 = this.GrainFactory.GetGrain>(GetRandomGrainId());
+ IEchoGenericChainGrain g1 = this.GrainFactory.GetGrain>(GetRandomGrainId());
string received = await g1.Echo(msg1);
Assert.Equal(msg1, received);
}
- [Fact, TestCategory("BVT"), TestCategory("Generics")]
+ [Fact]
public async Task Generic_Echo_Chain_2()
{
const string msg2 = "Hello from EchoGenericChainGrain-2";
- IEchoGenericChainGrain g2 = this.GrainFactory.GetGrain>(GetRandomGrainId());
+ IEchoGenericChainGrain g2 = this.GrainFactory.GetGrain>(GetRandomGrainId());
string received = await g2.Echo2(msg2);
Assert.Equal(msg2, received);
}
- [Fact, TestCategory("BVT"), TestCategory("Generics")]
+ [Fact]
public async Task Generic_Echo_Chain_3()
{
const string msg3 = "Hello from EchoGenericChainGrain-3";
- IEchoGenericChainGrain g3 = this.GrainFactory.GetGrain>(GetRandomGrainId());
+ IEchoGenericChainGrain g3 = this.GrainFactory.GetGrain>(GetRandomGrainId());
string received = await g3.Echo3(msg3);
Assert.Equal(msg3, received);
}
- [Fact, TestCategory("BVT"), TestCategory("Generics")]
+ [Fact]
public async Task Generic_Echo_Chain_4()
{
const string msg4 = "Hello from EchoGenericChainGrain-4";
@@ -547,7 +548,7 @@ public async Task Generic_Echo_Chain_4()
Assert.Equal(msg4, received);
}
- [Fact, TestCategory("BVT"), TestCategory("Generics")]
+ [Fact]
public async Task Generic_Echo_Chain_5()
{
const string msg5 = "Hello from EchoGenericChainGrain-5";
@@ -558,7 +559,7 @@ public async Task Generic_Echo_Chain_5()
Assert.Equal(msg5, received);
}
- [Fact, TestCategory("BVT"), TestCategory("Generics")]
+ [Fact]
public async Task Generic_Echo_Chain_6()
{
const string msg6 = "Hello from EchoGenericChainGrain-6";
@@ -570,108 +571,84 @@ public async Task Generic_Echo_Chain_6()
}
- [Fact, TestCategory("BVT"), TestCategory("Generics")]
+ [Fact]
public async Task Generic_1Argument_GenericCallOnly()
{
- var grain = this.GrainFactory.GetGrain>(Guid.NewGuid(), "UnitTests.Grains.Generic1ArgumentGrain");
+ var grain = this.GrainFactory.GetGrain>(Guid.NewGuid(), "UnitTests.Grains.Generic1ArgumentGrain");
var s1 = Guid.NewGuid().ToString();
var s2 = await grain.Ping(s1);
Assert.Equal(s1, s2);
}
- [Fact, TestCategory("BVT"), TestCategory("Generics")]
- public async Task Generic_1Argument_NonGenericCallFirst()
+ [Fact]
+ public void Generic_1Argument_NonGenericCallFirst()
{
-
- var id = Guid.NewGuid();
- var nonGenericFacet = this.GrainFactory.GetGrain(id, "UnitTests.Grains.Generic1ArgumentGrain");
- await Assert.ThrowsAsync(async () =>
- {
- try
- {
- await nonGenericFacet.Ping();
- }
- catch (AggregateException exc)
- {
- throw exc.GetBaseException();
- }
- });
+ Assert.Throws(() => this.GrainFactory.GetGrain(Guid.NewGuid(), "UnitTests.Grains.Generic1ArgumentGrain"));
}
- [Fact, TestCategory("BVT"), TestCategory("Generics")]
+ [Fact]
public async Task Generic_1Argument_GenericCallFirst()
{
var id = Guid.NewGuid();
- var grain = this.GrainFactory.GetGrain>(id, "UnitTests.Grains.Generic1ArgumentGrain");
+ var grain = this.GrainFactory.GetGrain>(id, "UnitTests.Grains.Generic1ArgumentGrain");
var s1 = Guid.NewGuid().ToString();
var s2 = await grain.Ping(s1);
Assert.Equal(s1, s2);
- var nonGenericFacet = this.GrainFactory.GetGrain(id, "UnitTests.Grains.Generic1ArgumentGrain");
- await Assert.ThrowsAsync(async () =>
- {
- try
- {
- await nonGenericFacet.Ping();
- }
- catch (AggregateException exc)
- {
- throw exc.GetBaseException();
- }
- });
+ Assert.Throws(() => this.GrainFactory.GetGrain(id, "UnitTests.Grains.Generic1ArgumentGrain"));
}
- [Fact, TestCategory("BVT"), TestCategory("Generics")]
+ [Fact]
public async Task DifferentTypeArgsProduceIndependentActivations()
{
- var grain1 = this.GrainFactory.GetGrain>(0);
+ var grain1 = this.GrainFactory.GetGrain>(0);
await grain1.SetValue(123);
- var grain2 = this.GrainFactory.GetGrain>(0);
+ var grain2 = this.GrainFactory.GetGrain>(0);
var v = await grain2.GetValue();
Assert.Null(v);
}
- [Fact, TestCategory("BVT"), TestCategory("Generics"), TestCategory("Echo")]
+ [Fact, TestCategory("Echo")]
public async Task Generic_PingSelf()
{
var id = Guid.NewGuid();
- var grain = this.GrainFactory.GetGrain>(id);
+ var grain = this.GrainFactory.GetGrain>(id);
var s1 = Guid.NewGuid().ToString();
var s2 = await grain.PingSelf(s1);
Assert.Equal(s1, s2);
}
- [Fact, TestCategory("BVT"), TestCategory("Generics"), TestCategory("Echo")]
+ [Fact, TestCategory("Echo")]
public async Task Generic_PingOther()
{
var id = Guid.NewGuid();
var targetId = Guid.NewGuid();
- var grain = this.GrainFactory.GetGrain>(id);
- var target = this.GrainFactory.GetGrain>(targetId);
+ var grain = this.GrainFactory.GetGrain>(id);
+ var target = this.GrainFactory.GetGrain>(targetId);
var s1 = Guid.NewGuid().ToString();
var s2 = await grain.PingOther(target, s1);
Assert.Equal(s1, s2);
}
- [Fact, TestCategory("BVT"), TestCategory("Generics"), TestCategory("Echo")]
+ [Fact, TestCategory("Echo")]
public async Task Generic_PingSelfThroughOther()
{
var id = Guid.NewGuid();
var targetId = Guid.NewGuid();
- var grain = this.GrainFactory.GetGrain>(id);
- var target = this.GrainFactory.GetGrain>(targetId);
+ var grain = this.GrainFactory.GetGrain>(id);
+ var target = this.GrainFactory.GetGrain>(targetId);
var s1 = Guid.NewGuid().ToString();
var s2 = await grain.PingSelfThroughOther(target, s1);
Assert.Equal(s1, s2);
}
- [Fact, TestCategory("BVT"), TestCategory("Generics"), TestCategory("ActivateDeactivate")]
+ [Fact, TestCategory("ActivateDeactivate")]
public async Task Generic_ScheduleDelayedPingAndDeactivate()
{
var id = Guid.NewGuid();
var targetId = Guid.NewGuid();
- var grain = this.GrainFactory.GetGrain>(id);
- var target = this.GrainFactory.GetGrain>(targetId);
+ var grain = this.GrainFactory.GetGrain>(id);
+ var target = this.GrainFactory.GetGrain>(targetId);
var s1 = Guid.NewGuid().ToString();
await grain.ScheduleDelayedPingToSelfAndDeactivate(target, s1, TimeSpan.FromSeconds(5));
await Task.Delay(TimeSpan.FromSeconds(6));
@@ -679,19 +656,19 @@ public async Task Generic_ScheduleDelayedPingAndDeactivate()
Assert.Equal(s1, s2);
}
- [Fact, TestCategory("BVT"), TestCategory("Generics"), TestCategory("Serialization")]
+ [Fact, TestCategory("Serialization")]
public async Task SerializationTests_Generic_CircularReferenceTest()
{
var grainId = Guid.NewGuid();
- var grain = this.GrainFactory.GetGrain(primaryKey: grainId, keyExtension: grainId.ToString("N"));
+ var grain = this.GrainFactory.GetGrain(primaryKey: grainId, keyExtension: grainId.ToString("N"));
_ = await grain.GetState();
}
-
- [Fact, TestCategory("BVT"), TestCategory("Generics")]
+
+ [Fact]
public async Task Generic_GrainWithTypeConstraints()
{
var grainId = Guid.NewGuid().ToString();
- var grain = this.GrainFactory.GetGrain, int, string>>(grainId);
+ var grain = this.GrainFactory.GetGrain, int, string>>(grainId);
var result = await grain.GetCount();
Assert.Equal(0, result);
await grain.Add(42);
@@ -715,7 +692,7 @@ public async Task Generic_GrainWithTypeConstraints()
}
}
- [Fact, TestCategory("BVT"), TestCategory("Persistence")]
+ [Fact, TestCategory("Persistence")]
public async Task Generic_GrainWithValueTypeState()
{
Guid id = Guid.NewGuid();
@@ -731,10 +708,10 @@ public async Task Generic_GrainWithValueTypeState()
Assert.Equal(expectedValue, await grain.GetStateData());
}
- [Fact(Skip = "https://github.com/dotnet/orleans/issues/1655 Casting from non-generic to generic interface fails with an obscure error message"), TestCategory("Functional"), TestCategory("Cast"), TestCategory("Generics")]
- public async Task Generic_CastToGenericInterfaceAfterActivation()
+ [Fact, TestCategory("Cast")]
+ public async Task Generic_CastToGenericInterfaceAfterActivation()
{
- var grain = this.GrainFactory.GetGrain(Guid.NewGuid());
+ var grain = this.GrainFactory.GetGrain(Guid.NewGuid());
await grain.DoSomething(); //activates original grain type here
var castRef = grain.AsReference>();
@@ -744,9 +721,10 @@ public async Task Generic_CastToGenericInterfaceAfterActivation()
Assert.Equal("Hello!", result);
}
- [Fact(Skip= "https://github.com/dotnet/orleans/issues/1655 Casting from non-generic to generic interface fails with an obscure error message"), TestCategory("Functional"), TestCategory("Cast"), TestCategory("Generics")]
- public async Task Generic_CastToDifferentlyConcretizedGenericInterfaceBeforeActivation() {
- var grain = this.GrainFactory.GetGrain(Guid.NewGuid());
+ [Fact, TestCategory("Cast")]
+ public async Task Generic_CastToDifferentlyConcretizedGenericInterfaceBeforeActivation()
+ {
+ var grain = this.GrainFactory.GetGrain(Guid.NewGuid());
var castRef = grain.AsReference>();
@@ -754,10 +732,11 @@ public async Task Generic_CastToDifferentlyConcretizedGenericInterfaceBeforeActi
Assert.Equal("Hello!", result);
}
-
- [Fact, TestCategory("BVT"), TestCategory("Cast")]
- public async Task Generic_CastToDifferentlyConcretizedInterfaceBeforeActivation() {
- var grain = this.GrainFactory.GetGrain(Guid.NewGuid());
+
+ [Fact, TestCategory("Cast")]
+ public async Task Generic_CastToDifferentlyConcretizedInterfaceBeforeActivation()
+ {
+ var grain = this.GrainFactory.GetGrain(Guid.NewGuid());
var castRef = grain.AsReference();
@@ -765,10 +744,11 @@ public async Task Generic_CastToDifferentlyConcretizedInterfaceBeforeActivation(
Assert.Equal("Hello!", result);
}
-
- [Fact, TestCategory("BVT"), TestCategory("Cast"), TestCategory("Generics")]
- public async Task Generic_CastGenericInterfaceToNonGenericInterfaceBeforeActivation() {
- var grain = this.GrainFactory.GetGrain>(Guid.NewGuid());
+
+ [Fact, TestCategory("Cast")]
+ public async Task Generic_CastGenericInterfaceToNonGenericInterfaceBeforeActivation()
+ {
+ var grain = this.GrainFactory.GetGrain>(Guid.NewGuid());
var castRef = grain.AsReference();
@@ -776,13 +756,13 @@ public async Task Generic_CastGenericInterfaceToNonGenericInterfaceBeforeActivat
Assert.Equal("Hello!", result);
}
-
+
///
/// Tests that generic grains can have generic state and that the parameters to the Grain{TState}
/// class do not have to match the parameters to the grain class itself.
///
///
- [Fact, TestCategory("BVT"), TestCategory("Generics")]
+ [Fact]
public async Task GenericGrainStateParameterMismatchTest()
{
var grain = this.GrainFactory.GetGrain, string>>(Guid.NewGuid());
@@ -794,288 +774,198 @@ public async Task GenericGrainStateParameterMismatchTest()
namespace Generic.EdgeCases
{
using UnitTests.GrainInterfaces.Generic.EdgeCases;
+ using UnitTests.Grains.Generic.EdgeCases;
-
+ [TestCategory("BVT"), TestCategory("Generics")]
public class GenericEdgeCaseTests : HostedTestClusterEnsureDefaultStarted
{
public GenericEdgeCaseTests(DefaultClusterFixture fixture) : base(fixture)
{
}
- private static async Task GetConcreteGenArgs(IBasicGrain @this) {
+ private static async Task GetConcreteGenArgs(IBasicGrain @this)
+ {
var genArgTypeNames = await @this.ConcreteGenArgTypeNames();
-
- return genArgTypeNames.Select(n => Type.GetType(n))
- .ToArray();
+ return genArgTypeNames.Select(Type.GetType).ToArray();
}
-
-
- [Fact(Skip = "Currently unsupported"), TestCategory("Generics")]
- public async Task Generic_PartiallySpecifyingGenericGrainFulfilsInterface() {
- var grain = this.GrainFactory.GetGrain>(Guid.NewGuid());
+ [Fact(Skip = "Currently unsupported")]
+ public async Task Generic_PartiallySpecifyingGenericGrainFulfilsInterface()
+ {
+ var grain = this.GrainFactory.GetGrain>(Guid.NewGuid());
var concreteGenArgs = await GetConcreteGenArgs(grain);
-
- Assert.True(
- concreteGenArgs.SequenceEqual(new[] { typeof(int) })
- );
+ Assert.True(concreteGenArgs.SequenceEqual(new[] { typeof(int) }));
}
-
-
- [Fact(Skip = "Currently unsupported"), TestCategory("Generics")]
- public async Task Generic_GenericGrainCanReuseOwnGenArgRepeatedly() {
- //resolves correctly but can't be activated: too many gen args supplied for concrete class
-
- var grain = this.GrainFactory.GetGrain>(Guid.NewGuid());
+ [Fact(Skip = "Currently unsupported")]
+ public async Task Generic_GenericGrainCanReuseOwnGenArgRepeatedly()
+ {
+ // Resolves correctly but can't be activated: too many gen args supplied for concrete class
+ var grain = this.GrainFactory.GetGrain>(Guid.NewGuid());
var concreteGenArgs = await GetConcreteGenArgs(grain);
-
- Assert.True(
- concreteGenArgs.SequenceEqual(new[] { typeof(int) })
- );
+ Assert.True(concreteGenArgs.SequenceEqual(new[] { typeof(int) }));
}
-
- [Fact(Skip = "Currently unsupported"), TestCategory("Generics")]
- public async Task Generic_PartiallySpecifyingGenericInterfaceIsCastable() {
- var grain = this.GrainFactory.GetGrain>(Guid.NewGuid());
-
+ [Fact]
+ public async Task Generic_PartiallySpecifyingGenericInterfaceIsCastable()
+ {
+ var grain = this.GrainFactory.GetGrain>(Guid.NewGuid());
await grain.Hello();
-
var castRef = grain.AsReference>();
-
var response = await castRef.Hello();
-
Assert.Equal("Hello!", response);
}
-
- [Fact(Skip = "Currently unsupported"), TestCategory("Generics")]
- public async Task Generic_PartiallySpecifyingGenericInterfaceIsCastable_Activating() {
- var grain = this.GrainFactory.GetGrain>(Guid.NewGuid());
-
+ [Fact]
+ public async Task Generic_PartiallySpecifyingGenericInterfaceIsCastable_Activating()
+ {
+ var grain = this.GrainFactory.GetGrain>(Guid.NewGuid());
var castRef = grain.AsReference>();
-
var response = await castRef.Hello();
-
Assert.Equal("Hello!", response);
}
-
-
- [Fact(Skip = "Currently unsupported"), TestCategory("Generics")]
- public async Task Generic_RepeatedRearrangedGenArgsResolved() {
- //again resolves to the correct generic type definition, but fails on activation as too many args
- //gen args aren't being properly inferred from matched concrete type
- var grain = this.GrainFactory.GetGrain>(Guid.NewGuid());
+ [Fact(Skip = "Currently unsupported")]
+ public async Task Generic_RepeatedRearrangedGenArgsResolved()
+ {
+ // Again resolves to the correct generic type definition, but fails on activation as too many args
+ // gen args aren't being properly inferred from matched concrete type
+ var grain = this.GrainFactory.GetGrain>(Guid.NewGuid());
var concreteGenArgs = await GetConcreteGenArgs(grain);
-
- Assert.True(
- concreteGenArgs.SequenceEqual(new[] { typeof(string), typeof(int) })
- );
+ Assert.True(concreteGenArgs.SequenceEqual(new[] { typeof(string), typeof(int) }));
}
-
-
- [Fact(Skip = "Currently unsupported"), TestCategory("Generics")]
- public async Task Generic_RepeatedGenArgsWorkAmongstInterfacesInTypeResolution() {
- var grain = this.GrainFactory.GetGrain>(Guid.NewGuid());
+ [Fact]
+ public async Task Generic_RepeatedGenArgsWorkAmongstInterfacesInTypeResolution()
+ {
+ var grain = this.GrainFactory.GetGrain>(Guid.NewGuid());
var concreteGenArgs = await GetConcreteGenArgs(grain);
-
- Assert.True(
- concreteGenArgs.SequenceEqual(Enumerable.Empty())
- );
+ Assert.True(concreteGenArgs.SequenceEqual(Enumerable.Empty()));
}
-
- [Fact(Skip = "Currently unsupported"), TestCategory("Generics")]
- public async Task Generic_RepeatedGenArgsWorkAmongstInterfacesInCasting() {
- var grain = this.GrainFactory.GetGrain>(Guid.NewGuid());
-
+ [Fact]
+ public async Task Generic_RepeatedGenArgsWorkAmongstInterfacesInCasting()
+ {
+ var grain = this.GrainFactory.GetGrain>(Guid.NewGuid());
await grain.Hello();
-
var castRef = grain.AsReference>();
-
var response = await castRef.Hello();
-
Assert.Equal("Hello!", response);
}
-
- [Fact(Skip = "Currently unsupported"), TestCategory("Generics")]
- public async Task Generic_RepeatedGenArgsWorkAmongstInterfacesInCasting_Activating() {
- //Only errors on invocation: wrong arity again
-
- var grain = this.GrainFactory.GetGrain>(Guid.NewGuid());
-
+ [Fact]
+ public async Task Generic_RepeatedGenArgsWorkAmongstInterfacesInCasting_Activating()
+ {
+ var grain = this.GrainFactory.GetGrain>(Guid.NewGuid());
var castRef = grain.AsReference>();
-
var response = await castRef.Hello();
-
Assert.Equal("Hello!", response);
}
-
-
- [Fact(Skip = "Currently unsupported"), TestCategory("Generics")]
- public async Task Generic_RearrangedGenArgsOfCorrectArityAreResolved() {
- var grain = this.GrainFactory.GetGrain>(Guid.NewGuid());
+ [Fact(Skip = "Currently unsupported")]
+ public async Task Generic_RearrangedGenArgsOfCorrectArityAreResolved()
+ {
+ var grain = this.GrainFactory.GetGrain>(Guid.NewGuid());
var concreteGenArgs = await GetConcreteGenArgs(grain);
-
- Assert.True(
- concreteGenArgs.SequenceEqual(new[] { typeof(long), typeof(int) })
- );
+ Assert.True(concreteGenArgs.SequenceEqual(new[] { typeof(long), typeof(int) }));
}
-
-
- [Fact(Skip = "Currently unsupported"), TestCategory("Generics")]
- public async Task Generic_RearrangedGenArgsOfCorrectNumberAreCastable() {
- var grain = this.GrainFactory.GetGrain>(Guid.NewGuid());
+ [Fact]
+ public async Task Generic_RearrangedGenArgsOfCorrectNumberAreCastable()
+ {
+ var grain = this.GrainFactory.GetGrain>(Guid.NewGuid());
await grain.Hello();
-
var castRef = grain.AsReference>();
-
var response = await castRef.Hello();
-
Assert.Equal("Hello!", response);
}
-
- [Fact(Skip = "Currently unsupported"), TestCategory("Generics")]
- public async Task Generic_RearrangedGenArgsOfCorrectNumberAreCastable_Activating() {
- var grain = this.GrainFactory.GetGrain>(Guid.NewGuid());
-
+ [Fact]
+ public async Task Generic_RearrangedGenArgsOfCorrectNumberAreCastable_Activating()
+ {
+ var grain = this.GrainFactory.GetGrain>(Guid.NewGuid());
var castRef = grain.AsReference>();
-
var response = await castRef.Hello();
-
Assert.Equal("Hello!", response);
}
+ public interface IFullySpecifiedGenericInterface : IBasicGrain
+ { }
+ public interface IDerivedFromMultipleSpecializationsOfSameInterface : IFullySpecifiedGenericInterface, IFullySpecifiedGenericInterface
+ { }
- //**************************************************************************************************************
- //**************************************************************************************************************
-
- //Below must be commented out, as supplying multiple fully-specified generic interfaces
- //to a class causes the codegen to fall over, stopping all other tests from working.
-
- //See new test here of the bit causing the issue - type info conflation:
- //UnitTests.CodeGeneration.CodeGeneratorTests.CodeGen_EncounteredFullySpecifiedInterfacesAreEncodedDistinctly()
-
-
- //public interface IFullySpecifiedGenericInterface : IBasicGrain
- //{ }
-
- //public interface IDerivedFromMultipleSpecializationsOfSameInterface : IFullySpecifiedGenericInterface, IFullySpecifiedGenericInterface
- //{ }
-
- //public class GrainFulfillingMultipleSpecializationsOfSameInterfaceViaIntermediate : BasicGrain, IDerivedFromMultipleSpecializationsOfSameInterface
- //{ }
-
-
- //[Fact, TestCategory("Generics")]
- //public async Task CastingBetweenFullySpecifiedGenericInterfaces()
- //{
- // //Is this legitimate? Solely in the realm of virtual grain interfaces - no special knowledge of implementation implicated, only of interface hierarchy
-
- // //codegen falling over: duplicate key when both specializations are matched to same concrete type
-
- // var grain = this.GrainFactory.GetGrain(Guid.NewGuid());
-
- // await grain.Hello();
-
- // var castRef = grain.AsReference>();
-
- // await castRef.Hello();
-
- // var castRef2 = castRef.AsReference>();
-
- // await castRef2.Hello();
- //}
-
- //*******************************************************************************************************
-
-
- [Fact(Skip = "Currently unsupported"), TestCategory("Generics")]
- public async Task Generic_CanCastToFullySpecifiedInterfaceUnrelatedToConcreteGenArgs() {
- var grain = this.GrainFactory.GetGrain>(Guid.NewGuid());
+ public class GrainFulfillingMultipleSpecializationsOfSameInterfaceViaIntermediate : BasicGrain, IDerivedFromMultipleSpecializationsOfSameInterface
+ { }
+ [Fact]
+ public async Task CastingBetweenFullySpecifiedGenericInterfaces()
+ {
+ var grain = this.GrainFactory.GetGrain(Guid.NewGuid());
await grain.Hello();
+ var castRef = grain.AsReference>();
+ await castRef.Hello();
+ var castRef2 = castRef.AsReference>();
+ await castRef2.Hello();
+ }
+ [Fact]
+ public async Task Generic_CanCastToFullySpecifiedInterfaceUnrelatedToConcreteGenArgs()
+ {
+ var grain = this.GrainFactory.GetGrain>(Guid.NewGuid());
+ await grain.Hello();
_ = grain.AsReference>();
-
var response = await grain.Hello();
-
Assert.Equal("Hello!", response);
}
- [Fact(Skip = "Currently unsupported"), TestCategory("Generics")]
- public async Task Generic_CanCastToFullySpecifiedInterfaceUnrelatedToConcreteGenArgs_Activating() {
- var grain = this.GrainFactory.GetGrain>(Guid.NewGuid());
-
+ [Fact]
+ public async Task Generic_CanCastToFullySpecifiedInterfaceUnrelatedToConcreteGenArgs_Activating()
+ {
+ var grain = this.GrainFactory.GetGrain>(Guid.NewGuid());
_ = grain.AsReference>();
-
var response = await grain.Hello();
-
Assert.Equal("Hello!", response);
}
-
-
- [Fact(Skip = "Currently unsupported"), TestCategory("Generics")]
- public async Task Generic_GenArgsCanBeFurtherSpecialized() {
- var grain = this.GrainFactory.GetGrain>>(Guid.NewGuid());
+ [Fact(Skip = "Currently unsupported")]
+ public async Task Generic_GenArgsCanBeFurtherSpecialized()
+ {
+ var grain = this.GrainFactory.GetGrain>>(Guid.NewGuid());
var concreteGenArgs = await GetConcreteGenArgs(grain);
-
- Assert.True(
- concreteGenArgs.SequenceEqual(new[] { typeof(int) })
- );
+ Assert.True(concreteGenArgs.SequenceEqual(new[] { typeof(int) }));
}
-
- [Fact(Skip = "Currently unsupported"), TestCategory("Generics")]
- public async Task Generic_GenArgsCanBeFurtherSpecializedIntoArrays() {
- var grain = this.GrainFactory.GetGrain>(Guid.NewGuid());
-
+ [Fact(Skip = "Currently unsupported")]
+ public async Task Generic_GenArgsCanBeFurtherSpecializedIntoArrays()
+ {
+ var grain = this.GrainFactory.GetGrain>(Guid.NewGuid());
var concreteGenArgs = await GetConcreteGenArgs(grain);
-
- Assert.True(
- concreteGenArgs.SequenceEqual(new[] { typeof(long) })
- );
+ Assert.True(concreteGenArgs.SequenceEqual(new[] { typeof(long) }));
}
-
-
- [Fact(Skip = "Currently unsupported"), TestCategory("Generics")]
- public async Task Generic_CanCastBetweenInterfacesWithFurtherSpecializedGenArgs() {
- var grain = this.GrainFactory.GetGrain>>(Guid.NewGuid());
+ [Fact(Skip = "Currently unsupported")]
+ public async Task Generic_CanCastBetweenInterfacesWithFurtherSpecializedGenArgs()
+ {
+ var grain = this.GrainFactory.GetGrain>>(Guid.NewGuid());
await grain.Hello();
_ = grain.AsReference>();
-
var response = await grain.Hello();
-
Assert.Equal("Hello!", response);
}
-
- [Fact(Skip = "Currently unsupported"), TestCategory("Generics")]
- public async Task Generic_CanCastBetweenInterfacesWithFurtherSpecializedGenArgs_Activating() {
- var grain = this.GrainFactory.GetGrain>>(Guid.NewGuid());
+ [Fact(Skip = "Currently unsupported")]
+ public async Task Generic_CanCastBetweenInterfacesWithFurtherSpecializedGenArgs_Activating()
+ {
+ var grain = this.GrainFactory.GetGrain>>(Guid.NewGuid());
_ = grain.AsReference>();
var response = await grain.Hello();
Assert.Equal("Hello!", response);
}
-
}
-
-
}
-
-
}
\ No newline at end of file
diff --git a/test/Grains/TestGrains/GenericGrains.cs b/test/Grains/TestGrains/GenericGrains.cs
index 7907c624a8..04a7a51999 100644
--- a/test/Grains/TestGrains/GenericGrains.cs
+++ b/test/Grains/TestGrains/GenericGrains.cs
@@ -742,7 +742,6 @@ public Task RoundTrip(C value)
}
}
-
public class NonGenericCastableGrain : Grain, INonGenericCastableGrain, ISomeGenericGrain, IIndependentlyConcretizedGenericGrain, IIndependentlyConcretizedGrain
{
public Task DoSomething() {
@@ -754,7 +753,6 @@ public Task Hello() {
}
}
-
public class GenericCastableGrain : Grain, IGenericCastableGrain, INonGenericCastGrain
{
public Task Hello() {
@@ -773,11 +771,9 @@ public Task Set(T[] value)
}
}
- public class IndepedentlyConcretizedGenericGrain : Grain, IIndependentlyConcretizedGenericGrain, IIndependentlyConcretizedGrain
+ public class IndependentlyConcretizedGenericGrain : Grain, IIndependentlyConcretizedGenericGrain, IIndependentlyConcretizedGrain
{
- public Task Hello() {
- return Task.FromResult("I have been independently concretized!");
- }
+ public Task Hello() => Task.FromResult("I have been independently concretized!");
}
public interface IReducer
@@ -785,7 +781,6 @@ public interface IReducer
Task Handle(TState prevState, TAction act);
}
-
[Serializable]
[GenerateSerializer]
public class Reducer1Action { }
@@ -842,25 +837,23 @@ namespace Generic.EdgeCases
using System.Linq;
using UnitTests.GrainInterfaces.Generic.EdgeCases;
-
public abstract class BasicGrain : Grain
{
- public Task Hello() {
+ public Task Hello()
+ {
return Task.FromResult("Hello!");
}
- public Task ConcreteGenArgTypeNames() {
+ public Task ConcreteGenArgTypeNames()
+ {
var grainType = GetImmediateSubclass(this.GetType());
-
- return Task.FromResult(
- grainType.GetGenericArguments()
- .Select(t => t.FullName)
- .ToArray()
- );
+ return Task.FromResult(grainType.GetGenericArguments().Select(t => t.FullName).ToArray());
}
- private Type GetImmediateSubclass(Type subject) {
- if(subject.BaseType == typeof(BasicGrain)) {
+ private Type GetImmediateSubclass(Type subject)
+ {
+ if(subject.BaseType == typeof(BasicGrain))
+ {
return subject;
}
@@ -868,39 +861,30 @@ private Type GetImmediateSubclass(Type subject) {
}
}
-
-
public class PartiallySpecifyingGrain : BasicGrain, IGrainWithTwoGenArgs
{ }
-
public class GrainWithPartiallySpecifyingInterface : BasicGrain, IPartiallySpecifyingInterface
{ }
-
public class GrainSpecifyingSameGenArgTwice : BasicGrain, IGrainReceivingRepeatedGenArgs
{ }
-
public class SpecifyingRepeatedGenArgsAmongstOthers : BasicGrain, IReceivingRepeatedGenArgsAmongstOthers
{ }
public class GrainForTestingCastingBetweenInterfacesWithReusedGenArgs : BasicGrain, ISpecifyingGenArgsRepeatedlyToParentInterface
{ }
-
public class SpecifyingSameGenArgsButRearranged : BasicGrain, IReceivingRearrangedGenArgs
{ }
-
public class GrainForTestingCastingWithRearrangedGenArgs : BasicGrain, ISpecifyingRearrangedGenArgsToParentInterface
{ }
-
public class GrainWithGenArgsUnrelatedToFullySpecifiedGenericInterface : BasicGrain, IArbitraryInterface, IInterfaceUnrelatedToConcreteGenArgs
{ }
-
public class GrainSupplyingFurtherSpecializedGenArg : BasicGrain, IInterfaceTakingFurtherSpecializedGenArg>
{ }
@@ -910,8 +894,5 @@ public class GrainSupplyingGenArgSpecializedIntoArray : BasicGrain, IInterfac
public class GrainForCastingBetweenInterfacesOfFurtherSpecializedGenArgs
: BasicGrain, IAnotherReceivingFurtherSpecializedGenArg>, IYetOneMoreReceivingFurtherSpecializedGenArg
{ }
-
-
}
-
}