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

Add orleans testing cluster test #77

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Orleans.Runtime" Version="7.2.0" />
<PackageReference Include="Microsoft.Orleans.Runtime" Version="7.2.1" />
</ItemGroup>

<ItemGroup>
Expand Down
26 changes: 26 additions & 0 deletions Tests/Orleans.StorageProviderInterceptors.Test/BasicTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
namespace Orleans.StorageProviderInterceptors.Test;

using Xunit;
using Xunit.Abstractions;

[Collection(TestClusterCollection.Name)]
public class BasicTests

Check failure on line 7 in Tests/Orleans.StorageProviderInterceptors.Test/BasicTests.cs

View workflow job for this annotation

GitHub Actions / Build-ubuntu-latest

Missing XML comment for publicly visible type or member 'BasicTests'
{
private readonly TestClusterFixture fixture;
private readonly ITestOutputHelper helper;

public BasicTests(TestClusterFixture fixture, ITestOutputHelper helper)

Check failure on line 12 in Tests/Orleans.StorageProviderInterceptors.Test/BasicTests.cs

View workflow job for this annotation

GitHub Actions / Build-ubuntu-latest

Missing XML comment for publicly visible type or member 'BasicTests.BasicTests(TestClusterFixture, ITestOutputHelper)'
{
this.fixture = fixture;
this.helper = helper;
}

[Fact]
public async Task Validate_SecretStorageGrain_ReadWrite()

Check failure on line 19 in Tests/Orleans.StorageProviderInterceptors.Test/BasicTests.cs

View workflow job for this annotation

GitHub Actions / Build-ubuntu-latest

Missing XML comment for publicly visible type or member 'BasicTests.Validate_SecretStorageGrain_ReadWrite()'
{
var grain = this.fixture.Cluster.GrainFactory.GetGrain<ISecretStorageGrain>("foo");
await grain.AddOrUpdateSecret("bar", "meh");
var secret = await grain.GetSecret("bar");
Assert.Equal("meh", secret);
}
}
15 changes: 0 additions & 15 deletions Tests/Orleans.StorageProviderInterceptors.Test/Class1Test.cs

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace Orleans.StorageProviderInterceptors.Test;

internal interface ISecretStorageGrain : IGrainWithStringKey
{
Task AddOrUpdateSecret(string name, string value);
Task<string> GetSecret(string name);
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@
<TargetFramework>net7.0</TargetFramework>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>

<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<NoWarn>1701;1702;NU5105;1591</NoWarn>
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
</PropertyGroup>

<ItemGroup Label="Project References">
<ProjectReference Include="..\..\Source\Orleans.StorageProviderInterceptors\Orleans.StorageProviderInterceptors.csproj" />
Expand All @@ -27,6 +32,8 @@
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Orleans.TestingHost" Version="7.2.1" />
<PackageReference Include="OrleansTestKit" Version="4.0.0-beta.3" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
namespace Orleans.StorageProviderInterceptors.Test;

using Abstractions;
using Runtime;

internal sealed class SecretStorageGrain : Grain, ISecretStorageGrain
{
private readonly IPersistentState<Dictionary<string, string>> secrets;

public SecretStorageGrain(
[StorageInterceptor(
TestSiloConfigurations.StorageName, "secretsState")]
IPersistentState<Dictionary<string, string>> state) => this.secrets = state;

public async Task AddOrUpdateSecret(string name, string value)
{
this.secrets.State[name] = value;
await this.secrets.WriteStateAsync();
}

public Task<string> GetSecret(string name) => Task.FromResult(this.secrets.State[name]);
}
36 changes: 36 additions & 0 deletions Tests/Orleans.StorageProviderInterceptors.Test/TestCluster.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
namespace Orleans.StorageProviderInterceptors.Test;

using System;
using Microsoft.Extensions.Configuration;
using Orleans;
using Orleans.TestingHost;

public sealed class TestClusterFixture : IDisposable

Check failure on line 8 in Tests/Orleans.StorageProviderInterceptors.Test/TestCluster.cs

View workflow job for this annotation

GitHub Actions / Build-ubuntu-latest

Missing XML comment for publicly visible type or member 'TestClusterFixture'
{
public string TestClusterId = new Guid().ToString();

Check failure on line 10 in Tests/Orleans.StorageProviderInterceptors.Test/TestCluster.cs

View workflow job for this annotation

GitHub Actions / Build-ubuntu-latest

Missing XML comment for publicly visible type or member 'TestClusterFixture.TestClusterId'

public Orleans.TestingHost.TestCluster Cluster { get; }

Check failure on line 12 in Tests/Orleans.StorageProviderInterceptors.Test/TestCluster.cs

View workflow job for this annotation

GitHub Actions / Build-ubuntu-latest

Missing XML comment for publicly visible type or member 'TestClusterFixture.Cluster'

public IClusterClient? ClusterClient { get; }

Check failure on line 14 in Tests/Orleans.StorageProviderInterceptors.Test/TestCluster.cs

View workflow job for this annotation

GitHub Actions / Build-ubuntu-latest

Missing XML comment for publicly visible type or member 'TestClusterFixture.ClusterClient'


public TestClusterFixture()

Check failure on line 17 in Tests/Orleans.StorageProviderInterceptors.Test/TestCluster.cs

View workflow job for this annotation

GitHub Actions / Build-ubuntu-latest

Missing XML comment for publicly visible type or member 'TestClusterFixture.TestClusterFixture()'
{
var builder = new TestClusterBuilder();

builder.ConfigureHostConfiguration(config => config.AddInMemoryCollection(
new Dictionary<string, string>
{
{ nameof(this.TestClusterId), this.TestClusterId }
}!));

builder.AddSiloBuilderConfigurator<TestSiloConfigurations>();

this.Cluster = builder.Build();
this.Cluster.Deploy();

this.ClusterClient = (IClusterClient)this.Cluster.ServiceProvider.GetService(typeof(IClusterClient))!;
}

public void Dispose() => this.Cluster.StopAllSilos();

Check failure on line 35 in Tests/Orleans.StorageProviderInterceptors.Test/TestCluster.cs

View workflow job for this annotation

GitHub Actions / Build-ubuntu-latest

Missing XML comment for publicly visible type or member 'TestClusterFixture.Dispose()'
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace Orleans.StorageProviderInterceptors.Test;

using Xunit;

// Important note: Fixtures can be shared across assemblies, but collection definitions must be in the same assembly as the test that uses them.
// https://xunit.net/docs/shared-context
[CollectionDefinition(Name)]
public class TestClusterCollection : ICollectionFixture<TestClusterFixture>

Check failure on line 8 in Tests/Orleans.StorageProviderInterceptors.Test/TestClusterCollection.cs

View workflow job for this annotation

GitHub Actions / Build-ubuntu-latest

Missing XML comment for publicly visible type or member 'TestClusterCollection'
{
public const string Name = "TestClusterCollection";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
namespace Orleans.StorageProviderInterceptors.Test;

using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Orleans.Streams;
using Orleans.TestingHost;

/// <inheritdoc />
public class TestSiloConfigurations : ISiloConfigurator, IHostConfigurator
{
internal const string StorageName = "SecretsStorage";

/// <inheritdoc />
public void Configure(ISiloBuilder siloBuilder)
{
siloBuilder.UseInMemoryReminderService();
siloBuilder.AddMemoryStreams("Default", config =>
{
config.ConfigureStreamPubSub(StreamPubSubType.ImplicitOnly);
config.ConfigureCacheEviction(builder => builder.Configure(options =>
{
options.DataMinTimeInCache = TimeSpan.FromMinutes(2);
options.DataMaxAgeInCache = TimeSpan.FromMinutes(10);
options.MetadataMinTimeInCache = TimeSpan.FromMinutes(60);
}));
});
siloBuilder
.AddStorageInterceptors()
.AddMemoryGrainStorage(StorageName)
.AddStorageInterceptors()
.UseGenericStorageInterceptor<Dictionary<string, string>>(
StorageName, "secretsState", c =>
{
c.OnBeforeWriteStateFunc = (grainActivationContext, currentState) =>
{
var unencryptedValues = new Dictionary<string, string>(currentState.State.Count);
Console.WriteLine(
$"OnBeforeWriteState: {grainActivationContext}: Count Is {currentState.State.Count}");
foreach (var (key, value) in currentState.State)
{
Console.WriteLine($"Intercepted: {key}: {value}");

// Save the original state to return to the grain
unencryptedValues.Add(key, value);

// Encrypt the data
currentState.State[key] = currentState.State[key].Replace('e', '3');
}

return ValueTask.FromResult((false, (object?)unencryptedValues));
};

c.OnAfterWriteStateFunc = (grainActivationContext, currentState, sharedState) =>
{
var unencryptedValues = (Dictionary<string, string>)sharedState!;
Console.WriteLine(
$"OnAfterWriteState: {grainActivationContext}: Count Is {currentState.State.Count}");
foreach (var (key, value) in currentState.State)
{
Console.WriteLine($"What was actually persisted: {key}: {value}");

currentState.State[key] = unencryptedValues[key];
Console.WriteLine($"What will be returned to grain: {key}: {unencryptedValues[key]}");
}

return ValueTask.CompletedTask;
};

c.OnBeforeReadStateAsync = (grainActivationContext, currentState) =>
{
Console.WriteLine(
$"OnBeforeReadState: {grainActivationContext}: Count Is {currentState.State.Count}");

var unencryptedValues = new Dictionary<string, string>(currentState.State.Count);
foreach (var (key, value) in currentState.State)
{
Console.WriteLine($"Unencrypted Values: {key}: {value}");

// Save the original state to return to the grain
unencryptedValues.Add(key, value);
}

return ValueTask.FromResult((false, (object?)unencryptedValues));
};

c.OnAfterReadStateFunc = (grainActivationContext, currentState, sharedState) =>
{
var unencryptedValues = (Dictionary<string, string>)sharedState!;
if (!currentState.RecordExists)
{
return ValueTask.CompletedTask;
}

var list = sharedState as List<string>;
Console.WriteLine(
$"OnAfterReadState: {grainActivationContext}: Count Is {currentState.State.Count}");

foreach (var (key, value) in currentState.State)
{
Console.WriteLine($"Encrypted Values: {key}: {value}");

// Decrypt the data
currentState.State[key] = currentState.State[key].Replace('3', 'e');
}

return ValueTask.CompletedTask;
};
});
}

/// <inheritdoc />
public virtual void Configure(IHostBuilder hostBuilder)
{
AppContext.SetSwitch("System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization", true);

hostBuilder.ConfigureLogging(logging =>
{
logging.ClearProviders();
logging.AddConsole();
});

hostBuilder.ConfigureServices((context, services) =>
{
// grab the cluster id that owns this silo
var clusterId = context.Configuration["TestClusterId"];
});
}
}
Loading