Skip to content

Commit

Permalink
Add Silo.CreateGrainAsync<T>() support and tests (#43)
Browse files Browse the repository at this point in the history
* Add Silo.CreateGrainAsync<T>() support and tests

* CreateGrain -> CreateGrainAsync

* Trigger[Start|Stop] -> ...Async

* Updated version and Copyright year
  • Loading branch information
el2iot2 authored and dsarfati committed Jun 30, 2018
1 parent 7ad47a1 commit b534978
Show file tree
Hide file tree
Showing 17 changed files with 122 additions and 120 deletions.
4 changes: 2 additions & 2 deletions src/OrleansTestKit/OrleansTestKit.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
<Company>OrleansContrib</Company>
<Product>OrleansTestKit</Product>
<Description>A testing framework for Microsoft Orleans that does not use a real silo</Description>
<Copyright>Copyright © 2017</Copyright>
<Version>2.0.0</Version>
<Copyright>Copyright © 2018</Copyright>
<Version>2.1.0</Version>
</PropertyGroup>

<ItemGroup>
Expand Down
10 changes: 4 additions & 6 deletions src/OrleansTestKit/TestGrainLifecycle.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,16 @@ public IDisposable Subscribe(string observerName, int stage, ILifecycleObserver
});
}

public void TriggerStart()
public Task TriggerStartAsync()
{
var tasks = observers.OrderBy(x => x.Item1).Select(x => x.Item2.OnStart(CancellationToken.None));

Task.WaitAll(tasks.ToArray(), 1000);
return Task.WhenAll(tasks.ToArray());
}

public void TriggerStop()
public Task TriggerStopAsync()
{
var tasks = observers.Select(x => x.Item2.OnStop(CancellationToken.None));

Task.WaitAll(tasks.ToArray(), 1000);
return Task.WhenAll(tasks.ToArray());
}
}
}
34 changes: 16 additions & 18 deletions src/OrleansTestKit/TestKitSilo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -92,24 +92,23 @@ public TestKitSilo()
_grainCreator = new TestGrainCreator(_grainRuntime, ServiceProvider);
}

#region CreateGrains
#region CreateGrains
public Task<T> CreateGrainAsync<T>(long id) where T : Grain, IGrainWithIntegerKey
=> CreateGrainAsync<T>(new TestGrainIdentity(id));

public T CreateGrain<T>(long id) where T : Grain, IGrainWithIntegerKey
=> CreateGrain<T>(new TestGrainIdentity(id));
public Task<T> CreateGrainAsync<T>(Guid id) where T : Grain, IGrainWithGuidKey
=> CreateGrainAsync<T>(new TestGrainIdentity(id));

public T CreateGrain<T>(Guid id) where T : Grain, IGrainWithGuidKey
=> CreateGrain<T>(new TestGrainIdentity(id));
public Task<T> CreateGrainAsync<T>(string id) where T : Grain, IGrainWithStringKey
=> CreateGrainAsync<T>(new TestGrainIdentity(id));

public T CreateGrain<T>(string id) where T : Grain, IGrainWithStringKey
=> CreateGrain<T>(new TestGrainIdentity(id));
public Task<T> CreateGrainAsync<T>(Guid id, string keyExtension) where T : Grain, IGrainWithGuidCompoundKey
=> CreateGrainAsync<T>(new TestGrainIdentity(id, keyExtension));

public T CreateGrain<T>(Guid id, string keyExtension) where T : Grain, IGrainWithGuidCompoundKey
=> CreateGrain<T>(new TestGrainIdentity(id, keyExtension));
public Task<T> CreateGrainAsync<T>(long id, string keyExtension) where T : Grain, IGrainWithIntegerCompoundKey
=> CreateGrainAsync<T>(new TestGrainIdentity(id, keyExtension));

public T CreateGrain<T>(long id, string keyExtension) where T : Grain, IGrainWithIntegerCompoundKey
=> CreateGrain<T>(new TestGrainIdentity(id, keyExtension));

private T CreateGrain<T>(IGrainIdentity identity) where T : Grain
private async Task<T> CreateGrainAsync<T>(IGrainIdentity identity) where T : Grain
{
if (_isGrainCreated)
throw new Exception(
Expand Down Expand Up @@ -141,12 +140,11 @@ private T CreateGrain<T>(IGrainIdentity identity) where T : Grain
ReminderRegistry.SetGrainTarget(remindable);

//Trigger the lifecycle hook that will get the grain's state from the runtime
_grainLifecycle.TriggerStart();
await _grainLifecycle.TriggerStartAsync();

return grain as T;
}

#endregion CreateGrains
#endregion

#region Verifies

Expand All @@ -161,9 +159,9 @@ public void VerifyRuntime(Expression<Action<IGrainRuntime>> expression, Func<Tim
/// Deactivate the given <see cref="Grain"/>
/// </summary>
/// <param name="grain">Grain to Deactivate</param>
public void Deactivate(Grain grain)
public Task DeactivateAsync(Grain grain)
{
_grainLifecycle.TriggerStop();
return _grainLifecycle.TriggerStopAsync();
}
}
}
3 changes: 2 additions & 1 deletion test/OrleansTestKit.Tests/Grains/StatefulActivationGrain.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@ public sealed class StatefulActivationGrain : Grain<StatefulActivationGrainState
{
private int _activationValue;

public override async Task OnActivateAsync()
public override Task OnActivateAsync()
{
_activationValue = this.State.Value;
return Task.CompletedTask;
}

public Task<int> GetStateValue() => Task.FromResult(State.Value);
Expand Down
2 changes: 1 addition & 1 deletion test/OrleansTestKit.Tests/Tests/ActivationGrainTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public async Task ShouldActivateWithValidState()


// Act
var grain = Silo.CreateGrain<StatefulActivationGrain>(0);
var grain = await Silo.CreateGrainAsync<StatefulActivationGrain>(0);
var value = await grain.GetActivationValue();

// Assert
Expand Down
35 changes: 18 additions & 17 deletions test/OrleansTestKit.Tests/Tests/BasicGrainTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public async Task SiloSayHelloTest()
long id = new Random().Next();
const string greeting = "Bonjour";

IHello grain = Silo.CreateGrain<HelloGrain>(id);
IHello grain = await Silo.CreateGrainAsync<HelloGrain>(id);

// This will create and call a Hello grain with specified 'id' in one of the test silos.
string reply = await grain.SayHello(greeting);
Expand All @@ -25,29 +25,30 @@ public async Task SiloSayHelloTest()
}

[Fact]
public void GrainActivation()
public async Task GrainActivation()
{
var grain = Silo.CreateGrain<LifecycleGrain>(new Random().Next());
var grain = await Silo.CreateGrainAsync<LifecycleGrain>(new Random().Next());

grain.ActivateCount.Should().Be(1);
}

[Fact]
public void SecondGrainCreated()
public async Task SecondGrainCreated()
{
Silo.CreateGrain<LifecycleGrain>(new Random().Next());
await Silo.CreateGrainAsync<LifecycleGrain>(new Random().Next());

Silo.Invoking(s => s.CreateGrain<LifecycleGrain>(new Random().Next())).ShouldThrow<Exception>();
Func<Task> creatingSecondGrainAsync = async () => await Silo.CreateGrainAsync<LifecycleGrain>(new Random().Next());
creatingSecondGrainAsync.ShouldThrow<Exception>();
}

[Fact]
public void GrainDeactivation()
public async Task GrainDeactivation()
{
var grain = Silo.CreateGrain<LifecycleGrain>(new Random().Next());
var grain = await Silo.CreateGrainAsync<LifecycleGrain>(new Random().Next());

grain.DeactivateCount.Should().Be(0);

Silo.Deactivate(grain);
await Silo.DeactivateAsync(grain);

grain.DeactivateCount.Should().Be(1);
}
Expand All @@ -57,7 +58,7 @@ public async Task IntegerKeyGrain()
{
const int id = int.MaxValue;

var grain = Silo.CreateGrain<IntegerKeyGrain>(id);
var grain = await Silo.CreateGrainAsync<IntegerKeyGrain>(id);

var key = await grain.GetKey();

Expand All @@ -70,7 +71,7 @@ public async Task IntegerCompoundKeyGrain()
const int id = int.MaxValue;
var ext = "Thing";

var grain = Silo.CreateGrain<IntegerCompoundKeyGrain>(id, ext);
var grain = await Silo.CreateGrainAsync<IntegerCompoundKeyGrain>(id, ext);

var key = await grain.GetKey();

Expand All @@ -83,7 +84,7 @@ public async Task GuidKeyGrain()
{
var id = Guid.NewGuid();

var grain = Silo.CreateGrain<GuidKeyGrain>(id);
var grain = await Silo.CreateGrainAsync<GuidKeyGrain>(id);

var key = await grain.GetKey();

Expand All @@ -96,7 +97,7 @@ public async Task GuidCompoundKeyGrain()
var id = Guid.NewGuid();
var ext = "Thing";

var grain = Silo.CreateGrain<GuidCompoundKeyGrain>(id, ext);
var grain = await Silo.CreateGrainAsync<GuidCompoundKeyGrain>(id, ext);

var key = await grain.GetKey();

Expand All @@ -109,7 +110,7 @@ public async Task StringKeyGrain()
{
const string id = "TestId";

var grain = Silo.CreateGrain<StringKeyGrain>(id);
var grain = await Silo.CreateGrainAsync<StringKeyGrain>(id);

var key = await grain.GetKey();

Expand All @@ -121,7 +122,7 @@ public async Task StatefulIntegerKeyGrain()
{
const int id = int.MaxValue;

var grain = Silo.CreateGrain<StatefulIntegerKeyGrain>(id);
var grain = await Silo.CreateGrainAsync<StatefulIntegerKeyGrain>(id);

var key = await grain.GetKey();

Expand All @@ -133,7 +134,7 @@ public async Task StatefulGuidKeyGrain()
{
var id = Guid.NewGuid();

var grain = Silo.CreateGrain<StatefulGuidKeyGrain>(id);
var grain = await Silo.CreateGrainAsync<StatefulGuidKeyGrain>(id);

var key = await grain.GetKey();

Expand All @@ -145,7 +146,7 @@ public async Task StatefulStringKeyGrain()
{
const string id = "TestId";

var grain = Silo.CreateGrain<StatefulStringKeyGrain>(id);
var grain = await Silo.CreateGrainAsync<StatefulStringKeyGrain>(id);

var key = await grain.GetKey();

Expand Down
22 changes: 12 additions & 10 deletions test/OrleansTestKit.Tests/Tests/DIGrainTests.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using System;
using System.Threading.Tasks;
using FluentAssertions;
using Moq;
using Moq;
using TestGrains;
using TestInterfaces;
using Xunit;
Expand All @@ -11,24 +11,26 @@ namespace Orleans.TestKit.Tests
public class DIGrainTests : TestKitBase
{
[Fact]
public void CreateGrainWithService()
public async Task CreateGrainWithService()
{
var grain = Silo.CreateGrain<DIGrain>(Guid.NewGuid());
var grain = await Silo.CreateGrainAsync<DIGrain>(Guid.NewGuid());

grain.Service.Should().NotBeNull();
}

}



[Fact]
public void SetupGrainService()
public async Task SetupGrainService()
{
var mockSvc = new Mock<IDIService>();
mockSvc.Setup(x => x.GetValue()).Returns(true);

Silo.ServiceProvider.AddServiceProbe(mockSvc);
var grain = Silo.CreateGrain<DIGrain>(Guid.NewGuid());
var grain = await Silo.CreateGrainAsync<DIGrain>(Guid.NewGuid());

grain.GetServiceValue().Should().BeTrue();
mockSvc.Verify(x => x.GetValue(), Times.Once);
}
}
}
}
}
}
4 changes: 2 additions & 2 deletions test/OrleansTestKit.Tests/Tests/DeactivationGrainTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public class DeactivationGrainTests : TestKitBase
public async Task ShouldCallDeactivateOnIdle()
{
// Arrange
var grain = Silo.CreateGrain<DeactivationGrain>(0);
var grain = await Silo.CreateGrainAsync<DeactivationGrain>(0);

// Act
await grain.DeactivateOnIdle();
Expand All @@ -25,7 +25,7 @@ public async Task ShouldCallDeactivateOnIdle()
public async Task ShouldCallDelayDeactivation()
{
// Arrange
var grain = Silo.CreateGrain<DeactivationGrain>(0);
var grain = await Silo.CreateGrainAsync<DeactivationGrain>(0);
var timeSpan = TimeSpan.FromSeconds(5);

// Act
Expand Down
20 changes: 10 additions & 10 deletions test/OrleansTestKit.Tests/Tests/GrainProbeTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public class GrainProbeTests : TestKitBase
[Fact]
public async Task SetupProbe()
{
IPing grain = Silo.CreateGrain<PingGrain>(1);
IPing grain = await Silo.CreateGrainAsync<PingGrain>(1);

var pong = Silo.AddProbe<IPong>(22);

Expand All @@ -26,7 +26,7 @@ public async Task SetupProbe()
[Fact]
public async Task SetupCompoundProbe()
{
IPing grain = Silo.CreateGrain<PingGrain>(1);
IPing grain = await Silo.CreateGrainAsync<PingGrain>(1);

var pong = Silo.AddProbe<IPongCompound>(44, keyExtension: "Test");

Expand All @@ -36,18 +36,18 @@ public async Task SetupCompoundProbe()
}

[Fact]
public void MissingProbe()
public async Task MissingProbe()
{
IPing grain = Silo.CreateGrain<PingGrain>(1);
IPing grain = await Silo.CreateGrainAsync<PingGrain>(1);

//There should not be an exception, since we are using loose grain generation
grain.Invoking(p => p.Ping()).ShouldNotThrow();
}

[Fact]
public void InvalidProbe()
public async Task InvalidProbe()
{
IPing grain = Silo.CreateGrain<PingGrain>(1);
IPing grain = await Silo.CreateGrainAsync<PingGrain>(1);

//This uses the wrong id for the IPong since this is hard coded within PingGrain
var pong = Silo.AddProbe<IPong>(0);
Expand All @@ -58,9 +58,9 @@ public void InvalidProbe()
}

[Fact]
public void InvalidProbeType()
public async Task InvalidProbeType()
{
IPing grain = Silo.CreateGrain<PingGrain>(1);
IPing grain = await Silo.CreateGrainAsync<PingGrain>(1);

//This correct id, but a different grain type
var pong = Silo.AddProbe<IPong2>(22);
Expand Down Expand Up @@ -135,7 +135,7 @@ public async Task FactoryProbe()

this.Silo.AddProbe<IPong>(identity => pong);

var grain = this.Silo.CreateGrain<PingGrain>(1);
var grain = await this.Silo.CreateGrainAsync<PingGrain>(1);

await grain.Ping();

Expand All @@ -148,7 +148,7 @@ public async Task ProbeWithClassPrefix()
Silo.AddProbe<IDevice>("Android", "TestGrains.DeviceAndroidGrain");
Silo.AddProbe<IDevice>("IOS", "TestGrains.DeviceIosGrain");

var managerGrain = this.Silo.CreateGrain<DeviceManagerGrain>(0);
var managerGrain = await this.Silo.CreateGrainAsync<DeviceManagerGrain>(0);
var iosGrain = await managerGrain.GetDeviceGrain("IOS");
var androidGrain = await managerGrain.GetDeviceGrain("Android");

Expand Down
Loading

0 comments on commit b534978

Please sign in to comment.