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
1 change: 1 addition & 0 deletions src/Orleans.Core/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
[assembly: InternalsVisibleTo("Tester")]
[assembly: InternalsVisibleTo("Tester.AzureUtils")]
[assembly: InternalsVisibleTo("Tester.AdoNet")]
[assembly: InternalsVisibleTo("Tester.Redis")]
[assembly: InternalsVisibleTo("Tester.ZooKeeperUtils")]
[assembly: InternalsVisibleTo("TesterInternal")]
[assembly: InternalsVisibleTo("TestExtensions")]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@ namespace Tester.Redis.Clustering
// Tests for operation of Orleans Membership Table using Redis
// </summary>
[TestCategory("Redis"), TestCategory("Clustering"), TestCategory("Functional")]
[Collection(TestEnvironmentFixture.DefaultCollection)]
public class RedisMembershipTableTests : MembershipTableTestsBase
{
public RedisMembershipTableTests(ConnectionStringFixture fixture, TestEnvironmentFixture environment) : base(fixture, environment, CreateFilters())
public RedisMembershipTableTests(ConnectionStringFixture fixture, CommonFixture environment) : base(fixture, environment, CreateFilters())
{
}

Expand Down
2 changes: 1 addition & 1 deletion test/Extensions/Tester.Redis/CollectionFixtures.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ namespace Tester.Redis
// Assembly collections must be defined once in each assembly

[CollectionDefinition(TestEnvironmentFixture.DefaultCollection)]
public class TestEnvironmentFixtureCollection : ICollectionFixture<TestEnvironmentFixture> { }
public class TestEnvironmentFixtureCollection : ICollectionFixture<CommonFixture> { }
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@
using StackExchange.Redis;
using Tester.Directories;
using TestExtensions;
using Xunit;
using Xunit.Abstractions;

namespace Tester.Redis.GrainDirectory
{
[TestCategory("Redis"), TestCategory("Directory"), TestCategory("Functional")]
[Collection(TestEnvironmentFixture.DefaultCollection)]
public class RedisGrainDirectoryTests : GrainDirectoryTests<RedisGrainDirectory>
{
public RedisGrainDirectoryTests(ITestOutputHelper testOutput) : base(testOutput)
Expand All @@ -20,7 +22,6 @@ public RedisGrainDirectoryTests(ITestOutputHelper testOutput) : base(testOutput)
protected override RedisGrainDirectory GetGrainDirectory()
{
TestUtils.CheckForRedis();

var configuration = TestDefaultConfiguration.RedisConnectionString;
var directoryOptions = new RedisGrainDirectoryOptions
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@
using Tester.Directories;
using TestExtensions;
using UnitTests.Grains.Directories;
using Xunit;

namespace Tester.Redis.GrainDirectory
{
[TestCategory("Redis"), TestCategory("Directory"), TestCategory("Functional")]
[Collection(TestEnvironmentFixture.DefaultCollection)]
public class RedisMultipleGrainDirectoriesTests : MultipleGrainDirectoriesTests
{
public class SiloConfigurator : ISiloConfigurator
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
namespace Tester.Redis.Persistence
{
[TestCategory("Redis"), TestCategory("Persistence"), TestCategory("Functional")]
[Collection(TestEnvironmentFixture.DefaultCollection)]
public class RedisPersistenceGrainTests : GrainPersistenceTestsRunner, IClassFixture<RedisPersistenceGrainTests.Fixture>
{
public static readonly string ServiceId = Guid.NewGuid().ToString("N");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@
using Orleans.Configuration;
using Orleans.Runtime;
using StackExchange.Redis;
using TestExtensions;

namespace Tester.Redis.Persistence
{
[TestCategory("Redis"), TestCategory("Persistence"), TestCategory("Functional")]
[Collection(TestEnvironmentFixture.DefaultCollection)]
public class RedisPersistenceSetupTests
{
[SkippableTheory]
Expand Down
132 changes: 132 additions & 0 deletions test/Extensions/Tester.Redis/Persistence/RedisStorageTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
using TestExtensions;
using UnitTests.StorageTests.Relational;
using UnitTests.StorageTests.Relational.TestDataSets;
using Xunit;
using Xunit.Abstractions;

namespace Tester.Redis.Persistence
{
[TestCategory("Redis"), TestCategory("Persistence"), TestCategory("Functional")]
[Collection(TestEnvironmentFixture.DefaultCollection)]
public class RedisStorageTests
{
private readonly CommonFixture fixture;
private readonly CommonStorageTests commonStorageTests;

public RedisStorageTests(ITestOutputHelper output, CommonFixture commonFixture)
{
TestUtils.CheckForRedis();
this.fixture = commonFixture;
this.commonStorageTests = new CommonStorageTests(commonFixture.GetStorageProvider(false ).GetAwaiter().GetResult());
}

[SkippableFact]
[TestCategory("Functional")]
public async Task WriteInconsistentFailsWithIncosistentStateException()
{
await Relational_WriteInconsistentFailsWithIncosistentStateException();
}

[SkippableFact]
[TestCategory("Functional")]
public async Task WriteRead100StatesInParallel()
{
await Relational_WriteReadWriteRead100StatesInParallel();
}
internal Task Relational_WriteReadWriteRead100StatesInParallel()
{
return commonStorageTests.PersistenceStorage_WriteReadWriteReadStatesInParallel(nameof(Relational_WriteReadWriteRead100StatesInParallel));
}

[SkippableFact]
[TestCategory("Functional")]
public async Task WriteReadCyrillic()
{
await commonStorageTests.PersistenceStorage_Relational_WriteReadIdCyrillic();
}

[SkippableTheory, ClassData(typeof(StorageDataSet2CyrillicIdsAndGrainNames<string>))]
[TestCategory("Functional")]
internal async Task DataSet2_Cyrillic_WriteClearRead(int testNum)
{
var (grainType, getGrain, grainState) = StorageDataSet2CyrillicIdsAndGrainNames<string>.GetTestData(testNum);
await this.commonStorageTests.Store_WriteClearRead(grainType, getGrain, grainState);
}

[SkippableTheory, ClassData(typeof(StorageDataSetPlain<long>))]
[TestCategory("Functional")]
internal async Task PersistenceStorage_StorageDataSetPlain_IntegerKey_WriteClearRead(int testNum)
{
var (grainType, getGrain, grainState) = StorageDataSetPlain<long>.GetTestData(testNum);
await this.commonStorageTests.Store_WriteClearRead(grainType, getGrain, grainState);
}

[SkippableTheory, ClassData(typeof(StorageDataSetGeneric<Guid, string>))]
[TestCategory("Functional")]
internal async Task StorageDataSetGeneric_GuidKey_Generic_WriteClearRead(int testNum)
{
var (grainType, getGrain, grainState) = StorageDataSetGeneric<Guid, string>.GetTestData(testNum);
await this.commonStorageTests.Store_WriteClearRead(grainType, getGrain, grainState);
}

[SkippableTheory, ClassData(typeof(StorageDataSetGeneric<long, string>))]
[TestCategory("Functional")]
internal async Task StorageDataSetGeneric_IntegerKey_Generic_WriteClearRead(int testNum)
{
var (grainType, getGrain, grainState) = StorageDataSetGeneric<long, string>.GetTestData(testNum);
await this.commonStorageTests.Store_WriteClearRead(grainType, getGrain, grainState);
}


[SkippableTheory, ClassData(typeof(StorageDataSetGeneric<string, string>))]
[TestCategory("Functional")]
internal async Task StorageDataSetGeneric_StringKey_Generic_WriteClearRead(int testNum)
{
var (grainType, getGrain, grainState) = StorageDataSetGeneric<string, string>.GetTestData(testNum);
await this.commonStorageTests.Store_WriteClearRead(grainType, getGrain, grainState);
}

[SkippableTheory, ClassData(typeof(StorageDataSetGeneric<string, string>))]
[TestCategory("Functional")]
internal async Task StorageDataSetGeneric_WriteRead(int testNum)
{
var (grainType, getGrain, grainState) = StorageDataSetGeneric<string, string>.GetTestData(testNum);
await commonStorageTests.Store_WriteRead(grainType, getGrain, grainState);
}

[SkippableTheory, ClassData(typeof(StorageDataSetPlain<Guid>))]
[TestCategory("Functional")]
internal async Task StorageDataSetPlain_GuidKey_WriteClearRead(int testNum)
{
var (grainType, getGrain, grainState) = StorageDataSetPlain<Guid>.GetTestData(testNum);
await this.commonStorageTests.Store_WriteClearRead(grainType, getGrain, grainState);
}

[SkippableTheory, ClassData(typeof(StorageDataSetPlain<string>))]
[TestCategory("Functional")]
internal async Task StorageDataSetPlain_StringKey_WriteClearRead(int testNum)
{
var (grainType, getGrain, grainState) = StorageDataSetPlain<string>.GetTestData(testNum);
await this.commonStorageTests.Store_WriteClearRead(grainType, getGrain, grainState);
}

[SkippableFact]
[TestCategory("Functional")]
public async Task PersistenceStorage_WriteDuplicateFailsWithInconsistentStateException()
{
await Relational_WriteDuplicateFailsWithInconsistentStateException();
}

internal async Task Relational_WriteDuplicateFailsWithInconsistentStateException()
{
var exception = await commonStorageTests.PersistenceStorage_WriteDuplicateFailsWithInconsistentStateException();
CommonStorageUtilities.AssertRelationalInconsistentExceptionMessage(exception.Message);
}

internal async Task Relational_WriteInconsistentFailsWithIncosistentStateException()
{
var exception = await commonStorageTests.PersistenceStorage_WriteInconsistentFailsWithInconsistentStateException();
CommonStorageUtilities.AssertRelationalInconsistentExceptionMessage(exception.Message);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using TestExtensions;
using UnitTests.StorageTests.Relational;
using UnitTests.StorageTests.Relational.TestDataSets;
using Xunit;
using Xunit.Abstractions;

namespace Tester.Redis.Persistence
{
[TestCategory("Redis"), TestCategory("Persistence"), TestCategory("Functional")]
[Collection(TestEnvironmentFixture.DefaultCollection)]
public class RedisStorageTestsOrleansSerializer
{
private readonly CommonFixture fixture;

public RedisStorageTestsOrleansSerializer(ITestOutputHelper output, CommonFixture commonFixture)
{
TestUtils.CheckForRedis();
this.fixture = commonFixture;
}

[SkippableTheory, ClassData(typeof(StorageDataSetGeneric<string, string>))]
[TestCategory("Functional")]
internal async Task StorageDataSetGeneric_WriteRead(int testNum)
{
var storageProvider = await fixture.GetStorageProvider(true);
var commonStorageTests = new CommonStorageTests(storageProvider);
var (grainType, getGrain, grainState) = StorageDataSetGeneric<string, string>.GetTestData(testNum);
await commonStorageTests.Store_WriteRead(grainType, getGrain, grainState);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@
namespace Tester.Redis.Reminders
{
[TestCategory("Redis"), TestCategory("Reminders"), TestCategory("Functional")]
[Collection(TestEnvironmentFixture.DefaultCollection)]
public class RedisRemindersTableTests : ReminderTableTestsBase
{
public RedisRemindersTableTests(ConnectionStringFixture fixture, TestEnvironmentFixture clusterFixture) : base (fixture, clusterFixture, CreateFilters())
public RedisRemindersTableTests(ConnectionStringFixture fixture, CommonFixture clusterFixture) : base (fixture, clusterFixture, CreateFilters())
{
TestUtils.CheckForRedis();
}

private static LoggerFilterOptions CreateFilters()
Expand Down Expand Up @@ -44,6 +46,7 @@ protected override IReminderTable CreateRemindersTable()

return reminderTable;
}

protected override Task<string> GetConnectionString() => Task.FromResult(TestDefaultConfiguration.RedisConnectionString);

[SkippableFact]
Expand Down
61 changes: 61 additions & 0 deletions test/Extensions/Tester.Redis/Utility/CommonFixture.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;
using Orleans.Configuration;
using Orleans.Persistence;
using Orleans.Providers;
using Orleans.Runtime;
using Orleans.Serialization;
using Orleans.Storage;
using StackExchange.Redis;
using Tester;
using TestExtensions;

public class CommonFixture : TestEnvironmentFixture
{
/// <summary>
/// Caches DefaultProviderRuntime for multiple uses.
/// </summary>
private IProviderRuntime DefaultProviderRuntime { get; }

/// <summary>
/// Constructor.
/// </summary>
public CommonFixture()
{
_ = this.Services.GetRequiredService<IOptions<ClusterOptions>>();
DefaultProviderRuntime = new ClientProviderRuntime(
this.InternalGrainFactory,
this.Services,
this.Services.GetRequiredService<ClientGrainContext>());
}

/// <summary>
/// Returns a correct implementation of the persistence provider according to environment variables.
/// </summary>
/// <remarks>If the environment invariants have failed to hold upon creation of the storage provider,
/// a <em>null</em> value will be provided.</remarks>
public async Task<IGrainStorage> GetStorageProvider(bool useOrleansSerializer = false)
{
TestUtils.CheckForRedis();
IGrainStorageSerializer grainStorageSerializer = useOrleansSerializer ? new OrleansGrainStorageSerializer(this.DefaultProviderRuntime.ServiceProvider.GetService<Serializer>())
: new JsonGrainStorageSerializer(this.DefaultProviderRuntime.ServiceProvider.GetService<OrleansJsonSerializer>());
var options = new RedisStorageOptions()
{
ConfigurationOptions = ConfigurationOptions.Parse(TestDefaultConfiguration.RedisConnectionString),
GrainStorageSerializer = grainStorageSerializer
};

var clusterOptions = new ClusterOptions()
{
ServiceId = Guid.NewGuid().ToString()
};

var storageProvider = new RedisGrainStorage(string.Empty, options, grainStorageSerializer, Options.Create(clusterOptions), DefaultProviderRuntime.ServiceProvider.GetService<ILogger<RedisGrainStorage>>());
ISiloLifecycleSubject siloLifeCycle = new SiloLifecycleSubject(NullLoggerFactory.Instance.CreateLogger<SiloLifecycleSubject>());
storageProvider.Participate(siloLifeCycle);
await siloLifeCycle.OnStart(CancellationToken.None);
return storageProvider;
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
using System.Runtime.CompilerServices;
using System.Runtime.CompilerServices;

[assembly: InternalsVisibleTo("TesterInternal")]
[assembly: InternalsVisibleTo("NonSilo.Tests")]
[assembly: InternalsVisibleTo("Tester.AzureUtils")]
[assembly: InternalsVisibleTo("Tester.AdoNet")]
[assembly: InternalsVisibleTo("Tester.Redis")]
[assembly: InternalsVisibleTo("AWSUtils.Tests")]
[assembly: InternalsVisibleTo("GoogleUtils.Tests")]
3 changes: 2 additions & 1 deletion test/TesterInternal/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@

[assembly: InternalsVisibleTo("Tester.AzureUtils")]
[assembly: InternalsVisibleTo("Tester.AdoNet")]
[assembly: InternalsVisibleTo("Tester.Redis")]
[assembly: InternalsVisibleTo("AWSUtils.Tests")]
[assembly: InternalsVisibleTo("GoogleUtils.Tests")]
[assembly: InternalsVisibleTo("GoogleUtils.Tests")]
14 changes: 7 additions & 7 deletions test/TesterInternal/StorageTests/CommonStorageTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ namespace UnitTests.StorageTests.Relational
/// </remarks>
internal class CommonStorageTests
{
public CommonStorageTests(IGrainStorage storage) => Storage = storage;
public CommonStorageTests(IGrainStorage storage) => Storage = storage ?? throw new ArgumentNullException(nameof(storage));

/// <summary>
/// The storage provider under test.
Expand Down Expand Up @@ -187,18 +187,18 @@ await RetryHelper.RetryOnExceptionAsync(5, RetryOperation.Sigmoid, async () =>
await Storage.WriteStateAsync(grainTypeName, grainId, grainState);
var writtenStateVersion = grainState.ETag;
var recordExitsAfterWriting = grainState.RecordExists;
Assert.True(recordExitsAfterWriting);

await Storage.ClearStateAsync(grainTypeName, grainId, grainState).ConfigureAwait(false);
var clearedStateVersion = grainState.ETag;
var recordExitsAfterClearing = grainState.RecordExists;
Assert.NotEqual(writtenStateVersion, clearedStateVersion);

var storedGrainState = new GrainState<T> { State = new T() };
await Storage.ReadStateAsync(grainTypeName, grainId, storedGrainState).ConfigureAwait(false);
var recordExitsAfterClearing = grainState.RecordExists;
Assert.False(recordExitsAfterClearing);

Assert.NotEqual(writtenStateVersion, clearedStateVersion);
var storedGrainState = new GrainState<T> { State = new T(), ETag = clearedStateVersion };
await Storage.WriteStateAsync(grainTypeName, grainId, storedGrainState).ConfigureAwait(false);
Assert.Equal(storedGrainState.State, Activator.CreateInstance<T>());
Assert.True(recordExitsAfterWriting);
Assert.False(recordExitsAfterClearing);
Assert.True(storedGrainState.RecordExists);
}

Expand Down
Loading