I am trying to follow their tutorial for tests: Link to Orleans test docs
But the configuration shown is pretty simplistic:
var builder = new TestClusterBuilder();
var cluster = builder.Build();
cluster.Deploy();
And does not show how to add SMSProvider.
Let's say that I have the following test:
[Fact]
public async Task SaysHelloCorrectly()
{
var hello = _cluster.GrainFactory.GetGrain<ISomeGrain>(Guid.NewGuid(), "<Some stream ID>", "Some.Class.Path");
var guid = Guid.NewGuid();
var streamProvider = _cluster.Client.GetStreamProvider("SMSProvider");
var photoStream = streamProvider.GetStream<string>(guid, "<Some stream ID>");
await photoStream.OnNextAsync("Hi");
Assert.Equal("Hello, World", "Hello, World");
}
Then I get an error in line:
var streamProvider = _cluster.Client.GetStreamProvider("SMSProvider");
Such as:
[xUnit.net 00:00:02.02] Tests.SaysHelloCorrectly [FAIL]
Failed Tests.FilterTests.SaysHelloCorrectly [8 ms]
Error Message:
System.Collections.Generic.KeyNotFoundException : SMSProvider
I think that configuring the ClusterFixture correctly would be part of the solution or maybe the way I am getting the StreamProvider in the unit test is not correct.
All of the code looks like the following:
ClusterCollection:
using System;
using Orleans.TestingHost;
using Xunit;
namespace Tests {
[CollectionDefinition(ClusterCollection.Name)]
public class ClusterCollection : ICollectionFixture<ClusterFixture>
{
public const string Name = "ClusterCollection";
}
}
ClusterFixture:
public class ClusterFixture : IDisposable
{
private sealed class Configurator : ISiloBuilderConfigurator
{
public void Configure(ISiloHostBuilder siloBuilder)
{
siloBuilder.AddSimpleMessageStreamProvider("SMSProvider");
siloBuilder.AddMemoryGrainStorage("PubSubStore");
}
}
public ClusterFixture()
{
var builder = new TestClusterBuilder();
builder.AddSiloBuilderConfigurator<Configurator>();
this.Cluster = builder.Build();
this.Cluster.Deploy();
}
public void Dispose()
{
this.Cluster.StopAllSilos();
}
public TestCluster Cluster { get; private set; }
}
SomeTests:
[Collection(ClusterCollection.Name)]
public class SomeTests
{
private readonly TestCluster _cluster;
public SomeTests(ClusterFixture fixture)
{
_cluster = fixture.Cluster;
}
[Fact]
public async Task SaysHelloCorrectly()
{
var hello = _cluster.GrainFactory.GetGrain<ISomeGrain>(Guid.NewGuid(), "<Some stream ID>", "Some.Class.Path");
var guid = Guid.NewGuid();
var streamProvider = _cluster.Client.GetStreamProvider("SMSProvider");
var photoStream = streamProvider.GetStream<string>(guid, "<Some stream ID>");
await photoStream.OnNextAsync("Hi");
Assert.Equal("Hello, World", "Hello, World");
}
}
The setup needs to be improved. You can check this sample from the official Orleans GitHub page: https://github.com/dotnet/orleans/blob/main/test/TesterInternal/StreamingTests/SMSStreamingTests.cs
So, in your ClusterFixture
class you should add the SiloConfigurator
:
private class SiloConfigurator : ISiloConfigurator
{
public void Configure(ISiloBuilder hostBuilder) =>
hostBuilder.AddSimpleMessageStreamProvider("SMSProvider")
.AddMemoryGrainStorage("PubSubStore");
}
and the ClientConfiguretor
:
private class ClientConfiguretor : IClientBuilderConfigurator
{
public void Configure(IConfiguration configuration, IClientBuilder clientBuilder) =>
clientBuilder.AddSimpleMessageStreamProvider("SMSProvider");
}
And then in your ClusterFixture
constructor:
public ClusterFixture()
{
var builder = new TestClusterBuilder();
builder.AddSiloBuilderConfigurator<SiloConfigurator>();
builder.AddClientBuilderConfigurator<ClientConfiguretor>();
this.Cluster = builder.Build();
this.Cluster.Deploy();
}