diff --git a/src/OrleansTestingHost/TestingSiloHost.cs b/src/OrleansTestingHost/TestingSiloHost.cs index c01033ad68..69dac435c0 100644 --- a/src/OrleansTestingHost/TestingSiloHost.cs +++ b/src/OrleansTestingHost/TestingSiloHost.cs @@ -35,6 +35,7 @@ namespace Orleans.TestingHost /// Also make sure that your test project references your test grains and test grain interfaces /// projects, and has CopyLocal=True set on those references [which should be the default]. /// + [Obsolete("Use TestCluster", false)] public class TestingSiloHost { /// Single instance of TestingSiloHost diff --git a/test/Tester/CollectionFixtures.cs b/test/Tester/CollectionFixtures.cs index d683568524..de7c59be55 100644 --- a/test/Tester/CollectionFixtures.cs +++ b/test/Tester/CollectionFixtures.cs @@ -9,4 +9,13 @@ public class DefaultClusterTestCollection : ICollectionFixture { } + + public abstract class BaseAzureTestClusterFixture : BaseTestClusterFixture + { + protected override void CheckPreconditionsOrThrow() + { + base.CheckPreconditionsOrThrow(); + TestUtils.CheckForAzureStorage(); + } + } } diff --git a/test/TesterAzureUtils/CollectionFixtures.cs b/test/TesterAzureUtils/CollectionFixtures.cs index 189f783db7..0b49cf5d0b 100644 --- a/test/TesterAzureUtils/CollectionFixtures.cs +++ b/test/TesterAzureUtils/CollectionFixtures.cs @@ -9,13 +9,4 @@ public class DefaultClusterTestCollection : ICollectionFixture { } - - public abstract class BaseAzureTestClusterFixture : BaseTestClusterFixture - { - protected override void CheckPreconditionsOrThrow() - { - base.CheckPreconditionsOrThrow(); - TestUtils.CheckForAzureStorage(); - } - } } diff --git a/test/TesterInternal/GeoClusterTests/BasicLogTestGrainTests.cs b/test/TesterInternal/GeoClusterTests/BasicLogTestGrainTests.cs index 72bb4be26d..e625681e36 100644 --- a/test/TesterInternal/GeoClusterTests/BasicLogTestGrainTests.cs +++ b/test/TesterInternal/GeoClusterTests/BasicLogTestGrainTests.cs @@ -8,17 +8,18 @@ using UnitTests.GrainInterfaces; using Orleans.TestingHost; using Xunit; -using Assert = Xunit.Assert; using TestExtensions; +using Tester; namespace Tests.GeoClusterTests { + [TestCategory("GeoCluster")] public class BasicLogTestGrainTests : IClassFixture { private readonly Fixture fixture; private Random random; - public class Fixture : BaseTestClusterFixture + public class Fixture : BaseAzureTestClusterFixture { protected override TestCluster CreateTestCluster() { @@ -43,35 +44,36 @@ protected override TestCluster CreateTestCluster() public BasicLogTestGrainTests(Fixture fixture) { this.fixture = fixture; + fixture.EnsurePreconditionsMet(); this.random = new Random(); } - [Fact, TestCategory("GeoCluster")] + [SkippableFact] public async Task DefaultStorage() { await DoBasicLogTestGrainTest("TestGrains.LogTestGrainDefaultStorage"); } - [Fact, TestCategory("GeoCluster")] + [SkippableFact] public async Task MemoryStorage() { await DoBasicLogTestGrainTest("TestGrains.LogTestGrainMemoryStorage"); } - [Fact, TestCategory("GeoCluster")] + [SkippableFact] public async Task SharedStorage() { await DoBasicLogTestGrainTest("TestGrains.LogTestGrainSharedStateStorage"); } - [Fact, TestCategory("GeoCluster")] + [SkippableFact] public async Task SharedLogStorage() { await DoBasicLogTestGrainTest("TestGrains.LogTestGrainSharedLogStorage"); } - [Fact, TestCategory("GeoCluster")] + [SkippableFact] public async Task CustomStorage() { await DoBasicLogTestGrainTest("TestGrains.LogTestGrainCustomStorage"); } - [Fact, TestCategory("GeoCluster")] + [SkippableFact] public async Task GsiStorage() { await DoBasicLogTestGrainTest("TestGrains.GsiLogTestGrain"); diff --git a/test/TesterInternal/GeoClusterTests/GlobalSingleInstanceClusterTests.cs b/test/TesterInternal/GeoClusterTests/GlobalSingleInstanceClusterTests.cs index dc3ba29d46..49c2151725 100644 --- a/test/TesterInternal/GeoClusterTests/GlobalSingleInstanceClusterTests.cs +++ b/test/TesterInternal/GeoClusterTests/GlobalSingleInstanceClusterTests.cs @@ -109,8 +109,8 @@ await RunWithTimeout("Setup_Clusters", largesetup ? 120000 : 60000, async () => // Create two clusters, each with a single silo. cluster0 = "cluster0"; cluster1 = "cluster1"; - NewGeoCluster(globalserviceid, cluster0, largesetup ? 3 : 1, configurationcustomizer); - NewGeoCluster(globalserviceid, cluster1, largesetup ? 4 : 1, configurationcustomizer); + NewGeoCluster(globalserviceid, cluster0, (short)(largesetup ? 3 : 1), configurationcustomizer); + NewGeoCluster(globalserviceid, cluster1, (short)(largesetup ? 4 : 1), configurationcustomizer); if (!largesetup) { @@ -508,7 +508,7 @@ public async Task ConflictResolution() private List GetGrainsInClusterWithStatus(string clusterId, GrainDirectoryEntryStatus? status = null) { List grains = new List(); - var silos = Clusters[clusterId].Silos; + var silos = Clusters[clusterId].Cluster.GetActiveSilos(); int totalSoFar = 0; foreach (var silo in silos) { diff --git a/test/TesterInternal/GeoClusterTests/LogConsistencyTestFixture.cs b/test/TesterInternal/GeoClusterTests/LogConsistencyTestFixture.cs index 0008f34a9d..056d32d35e 100644 --- a/test/TesterInternal/GeoClusterTests/LogConsistencyTestFixture.cs +++ b/test/TesterInternal/GeoClusterTests/LogConsistencyTestFixture.cs @@ -6,13 +6,12 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Text; using System.Threading.Tasks; -using UnitTests.GrainInterfaces; using Xunit; using Xunit.Abstractions; using TestExtensions; using Orleans.EventSourcing.Common; +using Tester; namespace Tests.GeoClusterTests { @@ -21,8 +20,19 @@ namespace Tests.GeoClusterTests /// (concurrent reading and updating, update propagation, conflict resolution) /// on a multicluster with the desired number of clusters /// - public class LogConsistencyTestFixture : TestingClusterHost + public class LogConsistencyTestFixture : IDisposable { + TestingClusterHost _hostedMultiCluster; + + public TestingClusterHost MultiCluster + { + get { return _hostedMultiCluster ?? (_hostedMultiCluster = new TestingClusterHost()); } + } + + public void EnsurePreconditionsMet() + { + TestUtils.CheckForAzureStorage(); + } #region client wrappers @@ -133,15 +143,13 @@ public IEnumerable GetUnresolvedConnectionIssues(string graincl public void StartClustersIfNeeded(int numclusters, ITestOutputHelper output) { - this.output = output; - - if (Clusters.Count != numclusters) + if (MultiCluster.Clusters.Count != numclusters) { - if (Clusters.Count > 0) - StopAllClientsAndClusters(); + if (MultiCluster.Clusters.Count > 0) + MultiCluster.StopAllClientsAndClusters(); - WriteLog("Creating {0} clusters and clients...", numclusters); + output.WriteLine("Creating {0} clusters and clients...", numclusters); this.numclusters = numclusters; Assert.True(numclusters >= 2); @@ -161,32 +169,31 @@ public void StartClustersIfNeeded(int numclusters, ITestOutputHelper output) for (int i = 0; i < numclusters; i++) { var clustername = Cluster[i] = ((char)('A' + i)).ToString(); - NewGeoCluster(globalserviceid, clustername, 1, + MultiCluster.NewGeoCluster(globalserviceid, clustername, 1, cfg => LogConsistencyProviderConfiguration.ConfigureLogConsistencyProvidersForTesting(TestDefaultConfiguration.DataConnectionString, cfg)); - Client[i] = this.NewClient(clustername, 0, ClientWrapper.Factory); + Client[i] = this.MultiCluster.NewClient(clustername, 0, ClientWrapper.Factory); } - WriteLog("Clusters and clients are ready (elapsed = {0})", stopwatch.Elapsed); + output.WriteLine("Clusters and clients are ready (elapsed = {0})", stopwatch.Elapsed); // wait for configuration to stabilize - WaitForLivenessToStabilizeAsync().WaitWithThrow(TimeSpan.FromMinutes(1)); + MultiCluster.WaitForLivenessToStabilizeAsync().WaitWithThrow(TimeSpan.FromMinutes(1)); Client[0].InjectClusterConfiguration(Cluster); - WaitForMultiClusterGossipToStabilizeAsync(false).WaitWithThrow(TimeSpan.FromMinutes(System.Diagnostics.Debugger.IsAttached ? 60 : 1)); + MultiCluster.WaitForMultiClusterGossipToStabilizeAsync(false).WaitWithThrow(TimeSpan.FromMinutes(System.Diagnostics.Debugger.IsAttached ? 60 : 1)); stopwatch.Stop(); - WriteLog("Multicluster is ready (elapsed = {0}).", stopwatch.Elapsed); + output.WriteLine("Multicluster is ready (elapsed = {0}).", stopwatch.Elapsed); } else { - WriteLog("Reusing existing {0} clusters and clients.", numclusters); + output.WriteLine("Reusing existing {0} clusters and clients.", numclusters); } } - public override void Dispose() + public virtual void Dispose() { - base.output = null; // cannot trace during dispose from fixtures - base.Dispose(); + _hostedMultiCluster?.Dispose(); } protected ClientWrapper[] Client; @@ -196,15 +203,10 @@ public override void Dispose() private const int Xyz = 333; - public async Task RunChecksOnGrainClass(string grainClass, bool may_update_in_all_clusters, int phases) + public async Task RunChecksOnGrainClass(string grainClass, bool may_update_in_all_clusters, int phases, ITestOutputHelper output) { - Random random = new Random(); - - Func GetRandom = () => - { - lock (random) - return random.Next(); - }; + var random = new SafeRandom(); + Func GetRandom = () => random.Next(); Func checker1 = () => Task.Run(() => { @@ -212,21 +214,21 @@ public async Task RunChecksOnGrainClass(string grainClass, bool may_update_in_al var grainidentity = string.Format("grainref={0}", Client[0].GetGrainRef(grainClass, x)); // force creation of replicas for (int i = 0; i < numclusters; i++) - AssertEqual(0, Client[i].GetALocal(grainClass, x), grainidentity); + Assert.Equal(0, Client[i].GetALocal(grainClass, x)); // write global on client 0 Client[0].SetAGlobal(grainClass, x, Xyz); // read global on other clients for (int i = 1; i < numclusters; i++) { int r = Client[i].GetAGlobal(grainClass, x); - AssertEqual(Xyz, r, grainidentity); + Assert.Equal(Xyz, r); } // check local stability for (int i = 0; i < numclusters; i++) - AssertEqual(Xyz, Client[i].GetALocal(grainClass, x), grainidentity); + Assert.Equal(Xyz, Client[i].GetALocal(grainClass, x)); // check versions for (int i = 0; i < numclusters; i++) - AssertEqual(1, Client[i].GetConfirmedVersion(grainClass, x), grainidentity); + Assert.Equal(1, Client[i].GetConfirmedVersion(grainClass, x)); }); Func checker2 = () => Task.Run(() => @@ -239,11 +241,11 @@ public async Task RunChecksOnGrainClass(string grainClass, bool may_update_in_al for (int i = 1; i < numclusters; i++) { int r = Client[i].GetAGlobal(grainClass, x); - AssertEqual(1, r, grainidentity); + Assert.Equal(1, r); } // check versions for (int i = 0; i < numclusters; i++) - AssertEqual(1, Client[i].GetConfirmedVersion(grainClass, x), grainidentity); + Assert.Equal(1, Client[i].GetConfirmedVersion(grainClass, x)); }); Func checker2b = () => Task.Run(() => @@ -251,18 +253,18 @@ public async Task RunChecksOnGrainClass(string grainClass, bool may_update_in_al int x = GetRandom(); var grainidentity = string.Format("grainref={0}", Client[0].GetGrainRef(grainClass, x)); // force first creation on replica 1 - AssertEqual(0, Client[1].GetAGlobal(grainClass, x), grainidentity); + Assert.Equal(0, Client[1].GetAGlobal(grainClass, x)); // increment on replica 0 Client[0].IncrementAGlobal(grainClass, x); // expect on other replicas for (int i = 1; i < numclusters; i++) { int r = Client[i].GetAGlobal(grainClass, x); - AssertEqual(1, r, grainidentity); + Assert.Equal(1, r); } // check versions for (int i = 0; i < numclusters; i++) - AssertEqual(1, Client[i].GetConfirmedVersion(grainClass, x), grainidentity); + Assert.Equal(1, Client[i].GetConfirmedVersion(grainClass, x)); }); Func checker3 = (int numupdates) => Task.Run(() => @@ -284,14 +286,14 @@ public async Task RunChecksOnGrainClass(string grainClass, bool may_update_in_al } // push & get all - AssertEqual(numupdates, Client[0].GetAGlobal(grainClass, x), grainidentity); + Assert.Equal(numupdates, Client[0].GetAGlobal(grainClass, x)); for (int i = 1; i < numclusters; i++) - AssertEqual(numupdates, Client[i].GetAGlobal(grainClass, x), grainidentity); // get all + Assert.Equal(numupdates, Client[i].GetAGlobal(grainClass, x)); // get all // check versions for (int i = 0; i < numclusters; i++) - AssertEqual(numupdates, Client[i].GetConfirmedVersion(grainClass, x), grainidentity); + Assert.Equal(numupdates, Client[i].GetConfirmedVersion(grainClass, x)); }); Func checker4 = () => Task.Run(() => @@ -367,7 +369,7 @@ await Task.WhenAny( Task.WhenAll(t) ); - AssertEqual(true, done.All(b => b), string.Format("checker6({0}): update did not propagate within 20 sec", preload)); + Assert.True(done.All(b => b), string.Format("checker6({0}): update did not propagate within 20 sec", preload)); }; Func checker7 = (int variation) => Task.Run(async () => @@ -384,9 +386,9 @@ await Task.WhenAny( // write conditional on client 0, should always succeed { var result = Client[0].SetAConditional(grainClass, x, Xyz); - AssertEqual(0, result.Item1, grainidentity); - AssertEqual(true, result.Item2, grainidentity); - AssertEqual(1, Client[0].GetConfirmedVersion(grainClass, x), grainidentity); + Assert.Equal(0, result.Item1); + Assert.Equal(true, result.Item2); + Assert.Equal(1, Client[0].GetConfirmedVersion(grainClass, x)); } if ((variation / 4) % 2 == 1) @@ -397,30 +399,30 @@ await Task.WhenAny( var result = Client[1].SetAConditional(grainClass, x, 444); if (result.Item1 == 0) // was stale, thus failed { - AssertEqual(false, result.Item2, grainidentity); + Assert.Equal(false, result.Item2); // must have updated as a result - AssertEqual(1, Client[1].GetConfirmedVersion(grainClass, x), grainidentity); + Assert.Equal(1, Client[1].GetConfirmedVersion(grainClass, x)); // check stability - AssertEqual(Xyz, Client[0].GetALocal(grainClass, x), grainidentity); - AssertEqual(Xyz, Client[1].GetALocal(grainClass, x), grainidentity); - AssertEqual(Xyz, Client[0].GetAGlobal(grainClass, x), grainidentity); - AssertEqual(Xyz, Client[1].GetAGlobal(grainClass, x), grainidentity); + Assert.Equal(Xyz, Client[0].GetALocal(grainClass, x)); + Assert.Equal(Xyz, Client[1].GetALocal(grainClass, x)); + Assert.Equal(Xyz, Client[0].GetAGlobal(grainClass, x)); + Assert.Equal(Xyz, Client[1].GetAGlobal(grainClass, x)); } else // was up-to-date, thus succeeded { - AssertEqual(true, result.Item2, grainidentity); - AssertEqual(1, result.Item1, grainidentity); + Assert.Equal(true, result.Item2); + Assert.Equal(1, result.Item1); // version is now 2 - AssertEqual(2, Client[1].GetConfirmedVersion(grainClass, x), grainidentity); + Assert.Equal(2, Client[1].GetConfirmedVersion(grainClass, x)); // check stability - AssertEqual(444, Client[1].GetALocal(grainClass, x), grainidentity); - AssertEqual(444, Client[0].GetAGlobal(grainClass, x), grainidentity); - AssertEqual(444, Client[1].GetAGlobal(grainClass, x), grainidentity); + Assert.Equal(444, Client[1].GetALocal(grainClass, x)); + Assert.Equal(444, Client[0].GetAGlobal(grainClass, x)); + Assert.Equal(444, Client[1].GetAGlobal(grainClass, x)); } } }); - WriteLog("Running individual short tests"); + output.WriteLine("Running individual short tests"); // first, run short ones in sequence await checker1(); @@ -445,15 +447,15 @@ await Task.WhenAny( await checker7(7); // run tests under blocked notification to force race one way - SetProtocolMessageFilterForTesting(Cluster[0], msg => ! (msg is INotificationMessage)); + MultiCluster.SetProtocolMessageFilterForTesting(Cluster[0], msg => ! (msg is INotificationMessage)); await checker7(0); await checker7(1); await checker7(2); await checker7(3); - SetProtocolMessageFilterForTesting(Cluster[0], _ => true); + MultiCluster.SetProtocolMessageFilterForTesting(Cluster[0], _ => true); } - WriteLog("Running individual longer tests"); + output.WriteLine("Running individual longer tests"); // then, run slightly longer tests if (phases != 0) @@ -462,7 +464,7 @@ await Task.WhenAny( await checker3(phases); } - WriteLog("Running many concurrent test instances"); + output.WriteLine("Running many concurrent test instances"); var tasks = new List(); for (int i = 0; i < phases; i++) diff --git a/test/TesterInternal/GeoClusterTests/LogConsistencyTestsFourClusters.cs b/test/TesterInternal/GeoClusterTests/LogConsistencyTestsFourClusters.cs index 58258cb64d..9e1f2d4532 100644 --- a/test/TesterInternal/GeoClusterTests/LogConsistencyTestsFourClusters.cs +++ b/test/TesterInternal/GeoClusterTests/LogConsistencyTestsFourClusters.cs @@ -1,70 +1,62 @@ -using System; -using System.Collections.Generic; -using System.Threading.Tasks; -using Orleans; -using Orleans.TestingHost; -using UnitTests.GrainInterfaces; -using Orleans.Runtime; -using Tests.GeoClusterTests; +using System.Threading.Tasks; using Xunit; using Xunit.Abstractions; -using Orleans.Runtime.Configuration; -using Tester; namespace Tests.GeoClusterTests { - public class LogConsistencyTestsFourClusters : - IClassFixture + [TestCategory("GeoCluster")] + public class LogConsistencyTestsFourClusters : IClassFixture { + const int phases = 100; + private ITestOutputHelper output; + private Fixture fixture; public LogConsistencyTestsFourClusters(ITestOutputHelper output, Fixture fixture) { + fixture.EnsurePreconditionsMet(); this.fixture = fixture; + this.output = output; fixture.StartClustersIfNeeded(4, output); } - Fixture fixture; public class Fixture : LogConsistencyTestFixture { } - const int phases = 100; - - [Fact, TestCategory("GeoCluster")] + [SkippableFact] public async Task TestBattery_SharedStateStorageProvider() { - await fixture.RunChecksOnGrainClass("TestGrains.LogTestGrainSharedStateStorage", true, phases); + await fixture.RunChecksOnGrainClass("TestGrains.LogTestGrainSharedStateStorage", true, phases, output); } - [Fact, TestCategory("GeoCluster")] + [SkippableFact] public async Task TestBattery_SharedLogStorageProvider() { - await fixture.RunChecksOnGrainClass("TestGrains.LogTestGrainSharedLogStorage", true, phases); + await fixture.RunChecksOnGrainClass("TestGrains.LogTestGrainSharedLogStorage", true, phases, output); } - [Fact, TestCategory("GeoCluster")] + [SkippableFact] public async Task TestBattery_GsiDefaultStorageProvider() { - await fixture.RunChecksOnGrainClass("TestGrains.GsiLogTestGrain", true, phases); + await fixture.RunChecksOnGrainClass("TestGrains.GsiLogTestGrain", true, phases, output); } - [Fact, TestCategory("GeoCluster")] + [SkippableFact] public async Task TestBattery_MemoryStorageProvider() { - await fixture.RunChecksOnGrainClass("TestGrains.LogTestGrainMemoryStorage", true, phases); + await fixture.RunChecksOnGrainClass("TestGrains.LogTestGrainMemoryStorage", true, phases, output); } - [Fact, TestCategory("GeoCluster")] + [SkippableFact] public async Task TestBattery_CustomStorageProvider() { - await fixture.RunChecksOnGrainClass("TestGrains.LogTestGrainCustomStorage", true, phases); + await fixture.RunChecksOnGrainClass("TestGrains.LogTestGrainCustomStorage", true, phases, output); } - [Fact, TestCategory("GeoCluster")] + [SkippableFact] public async Task TestBattery_CustomStorageProvider_PrimaryCluster() { - await fixture.RunChecksOnGrainClass("TestGrains.LogTestGrainCustomStoragePrimaryCluster", false, phases); + await fixture.RunChecksOnGrainClass("TestGrains.LogTestGrainCustomStoragePrimaryCluster", false, phases, output); } - } } diff --git a/test/TesterInternal/GeoClusterTests/LogConsistencyTestsTwoClusters.cs b/test/TesterInternal/GeoClusterTests/LogConsistencyTestsTwoClusters.cs index f9cae2d840..47c312cb9f 100644 --- a/test/TesterInternal/GeoClusterTests/LogConsistencyTestsTwoClusters.cs +++ b/test/TesterInternal/GeoClusterTests/LogConsistencyTestsTwoClusters.cs @@ -1,70 +1,62 @@ -using System; -using System.Collections.Generic; -using System.Threading.Tasks; -using Orleans; -using Orleans.TestingHost; -using UnitTests.GrainInterfaces; -using Orleans.Runtime; -using Tests.GeoClusterTests; +using System.Threading.Tasks; using Xunit; using Xunit.Abstractions; -using Orleans.Runtime.Configuration; namespace Tests.GeoClusterTests { - public class LogConsistencyTestsTwoClusters: - IClassFixture + [TestCategory("GeoCluster")] + public class LogConsistencyTestsTwoClusters: IClassFixture { + const int phases = 100; + private ITestOutputHelper output; + private Fixture fixture; public LogConsistencyTestsTwoClusters(ITestOutputHelper output, Fixture fixture) { + fixture.EnsurePreconditionsMet(); this.fixture = fixture; + this.output = output; fixture.StartClustersIfNeeded(2, output); } - Fixture fixture; public class Fixture : LogConsistencyTestFixture { } - const int phases = 100; - - [Fact, TestCategory("GeoCluster")] + [SkippableFact] public async Task TestBattery_SharedStateStorageProvider() { - await fixture.RunChecksOnGrainClass("TestGrains.LogTestGrainSharedStateStorage", true, phases); + await fixture.RunChecksOnGrainClass("TestGrains.LogTestGrainSharedStateStorage", true, phases, output); } - [Fact, TestCategory("GeoCluster")] + [SkippableFact] public async Task TestBattery_SharedLogStorageProvider() { - await fixture.RunChecksOnGrainClass("TestGrains.LogTestGrainSharedLogStorage", true, phases); + await fixture.RunChecksOnGrainClass("TestGrains.LogTestGrainSharedLogStorage", true, phases, output); } - [Fact, TestCategory("GeoCluster")] + [SkippableFact] public async Task TestBattery_GsiDefaultStorageProvider() { - await fixture.RunChecksOnGrainClass("TestGrains.GsiLogTestGrain", true, phases); + await fixture.RunChecksOnGrainClass("TestGrains.GsiLogTestGrain", true, phases, output); } - [Fact, TestCategory("GeoCluster")] + [SkippableFact] public async Task TestBattery_MemoryStorageProvider() { - await fixture.RunChecksOnGrainClass("TestGrains.LogTestGrainMemoryStorage", true, phases); + await fixture.RunChecksOnGrainClass("TestGrains.LogTestGrainMemoryStorage", true, phases, output); } - [Fact, TestCategory("GeoCluster")] + [SkippableFact] public async Task TestBattery_CustomStorageProvider() { - await fixture.RunChecksOnGrainClass("TestGrains.LogTestGrainCustomStorage", true, phases); + await fixture.RunChecksOnGrainClass("TestGrains.LogTestGrainCustomStorage", true, phases, output); } - [Fact, TestCategory("GeoCluster")] + [SkippableFact] public async Task TestBattery_CustomStorageProvider_PrimaryCluster() { - await fixture.RunChecksOnGrainClass("TestGrains.LogTestGrainCustomStoragePrimaryCluster", false, phases); + await fixture.RunChecksOnGrainClass("TestGrains.LogTestGrainCustomStoragePrimaryCluster", false, phases, output); } - - } } diff --git a/test/TesterInternal/GeoClusterTests/MultiClusterNetworkTests.cs b/test/TesterInternal/GeoClusterTests/MultiClusterNetworkTests.cs index 8ac5139d23..c26e6a9f31 100644 --- a/test/TesterInternal/GeoClusterTests/MultiClusterNetworkTests.cs +++ b/test/TesterInternal/GeoClusterTests/MultiClusterNetworkTests.cs @@ -64,7 +64,7 @@ public async Task TestMultiClusterConf_1_1() // create cluster A and clientA var clusterA = "A"; NewGeoCluster(globalserviceid, clusterA, 1); - var siloA = Clusters[clusterA].Silos[0].SiloAddress.Endpoint; + var siloA = Clusters[clusterA].Silos.First().SiloAddress.Endpoint; var clientA = this.NewClient(clusterA, 0, ClientWrapper.Factory); var cur = clientA.GetMultiClusterConfiguration(); @@ -84,7 +84,7 @@ public async Task TestMultiClusterConf_1_1() // create cluster B and clientB var clusterB = "B"; NewGeoCluster(globalserviceid, clusterB, 1); - var siloB = Clusters[clusterB].Silos[0].SiloAddress.Endpoint; + var siloB = Clusters[clusterB].Silos.First().SiloAddress.Endpoint; var clientB = NewClient(clusterB, 0, ClientWrapper.Factory); cur = clientB.GetMultiClusterConfiguration(); @@ -121,7 +121,7 @@ public async Task TestMultiClusterConf_1_1() } // shut down cluster B - StopSilo(Clusters[clusterB].Silos[0]); + Clusters[clusterB].Cluster.StopAllSilos(); await WaitForLivenessToStabilizeAsync(); // expect disappearance of gateway from multicluster network @@ -170,16 +170,12 @@ public async Task TestMultiClusterConf_3_3() // create cluster A and clientA NewGeoCluster(globalserviceid, clusterA, 3, configcustomizer); var clientA = this.NewClient(clusterA, 0, ClientWrapper.Factory); - var portA0 = Clusters[clusterA].Silos[0].SiloAddress.Endpoint.Port; - var portA1 = Clusters[clusterA].Silos[1].SiloAddress.Endpoint.Port; - var portA2 = Clusters[clusterA].Silos[2].SiloAddress.Endpoint.Port; + var portsA = Clusters[clusterA].Cluster.GetActiveSilos().Select(x => x.SiloAddress.Endpoint.Port).ToArray(); // create cluster B and clientB NewGeoCluster(globalserviceid, clusterB, 3, configcustomizer); var clientB = this.NewClient(clusterB, 0, ClientWrapper.Factory); - var portB0 = Clusters[clusterB].Silos[0].SiloAddress.Endpoint.Port; - var portB1 = Clusters[clusterB].Silos[1].SiloAddress.Endpoint.Port; - var portB2 = Clusters[clusterB].Silos[2].SiloAddress.Endpoint.Port; + var portsB = Clusters[clusterB].Cluster.GetActiveSilos().Select(x => x.SiloAddress.Endpoint.Port).ToArray(); // wait for membership to stabilize await WaitForLivenessToStabilizeAsync(); @@ -193,32 +189,32 @@ public async Task TestMultiClusterConf_3_3() // expect 4 active gateways, two per cluster var activegateways = clientA.GetMultiClusterGateways().Where(g => g.Status == GatewayStatus.Active).ToList(); - Assert.Equal(string.Join(",", portA0, portA1), + Assert.Equal(string.Join(",", portsA[0], portsA[1]), string.Join(",", activegateways.Where(g => g.ClusterId == clusterA).Select(g => g.SiloAddress.Endpoint.Port).OrderBy(x => x))); - Assert.Equal(string.Join(",", portB0, portB1), + Assert.Equal(string.Join(",", portsB[0], portsB[1]), string.Join(",", activegateways.Where(g => g.ClusterId == clusterB).Select(g => g.SiloAddress.Endpoint.Port).OrderBy(x => x))); var activegatewaysB = clientB.GetMultiClusterGateways().Where(g => g.Status == GatewayStatus.Active).ToList(); // shut down one of the gateways in cluster B gracefully - var target = Clusters[clusterB].Silos.Where(h => h.SiloAddress.Endpoint.Port == portB1).FirstOrDefault(); + var target = Clusters[clusterB].Cluster.GetActiveSilos().Where(h => h.SiloAddress.Endpoint.Port == portsB[1]).FirstOrDefault(); Assert.NotNull(target); - StopSilo(target); + Clusters[clusterB].Cluster.StopSilo(target); await WaitForLivenessToStabilizeAsync(); // expect disappearance and replacement of gateway from multicluster network await WaitForMultiClusterGossipToStabilizeAsync(false); AssertSameList(clientA.GetMultiClusterGateways(), clientB.GetMultiClusterGateways()); activegateways = clientA.GetMultiClusterGateways().Where(g => g.Status == GatewayStatus.Active).ToList(); - Assert.Equal(string.Join(",", portA0, portA1), + Assert.Equal(string.Join(",", portsA[0], portsA[1]), string.Join(",", activegateways.Where(g => g.ClusterId == clusterA).Select(g => g.SiloAddress.Endpoint.Port).OrderBy(x => x))); - Assert.Equal(string.Join(",", portB0, portB2), + Assert.Equal(string.Join(",", portsB[0], portsB[2]), string.Join(",", activegateways.Where(g => g.ClusterId == clusterB).Select(g => g.SiloAddress.Endpoint.Port).OrderBy(x => x))); // kill one of the gateways in cluster A - target = Clusters[clusterA].Silos.Where(h => h.SiloAddress.Endpoint.Port == portA1).FirstOrDefault(); + target = Clusters[clusterA].Cluster.GetActiveSilos().Where(h => h.SiloAddress.Endpoint.Port == portsA[1]).FirstOrDefault(); Assert.NotNull(target); - KillSilo(target); + Clusters[clusterA].Cluster.KillSilo(target); await WaitForLivenessToStabilizeAsync(); // wait for time necessary before peer removal can kick in @@ -228,7 +224,7 @@ public async Task TestMultiClusterConf_3_3() while (true) { var hosts = clientA.GetHosts(); - var killedone = hosts.Where(kvp => kvp.Key.Endpoint.Port == portA1).FirstOrDefault(); + var killedone = hosts.Where(kvp => kvp.Key.Endpoint.Port == portsA[1]).FirstOrDefault(); Assert.True(killedone.Value != SiloStatus.None); if (killedone.Value == SiloStatus.Dead) break; @@ -240,9 +236,9 @@ public async Task TestMultiClusterConf_3_3() AssertSameList(clientA.GetMultiClusterGateways(), clientB.GetMultiClusterGateways()); activegateways = clientA.GetMultiClusterGateways().Where(g => g.Status == GatewayStatus.Active).ToList(); - Assert.Equal(string.Join(",", portA0, portA2), + Assert.Equal(string.Join(",", portsA[0], portsA[2]), string.Join(",", activegateways.Where(g => g.ClusterId == clusterA).Select(g => g.SiloAddress.Endpoint.Port).OrderBy(x => x))); - Assert.Equal(string.Join(",", portB0, portB2), + Assert.Equal(string.Join(",", portsB[0], portsB[2]), string.Join(",", activegateways.Where(g => g.ClusterId == clusterB).Select(g => g.SiloAddress.Endpoint.Port).OrderBy(x => x))); } } diff --git a/test/TesterInternal/GeoClusterTests/MultiClusterRegistrationTests.cs b/test/TesterInternal/GeoClusterTests/MultiClusterRegistrationTests.cs index e624e0d9df..a86bd4acbe 100644 --- a/test/TesterInternal/GeoClusterTests/MultiClusterRegistrationTests.cs +++ b/test/TesterInternal/GeoClusterTests/MultiClusterRegistrationTests.cs @@ -6,7 +6,6 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; -using Tester; using TestExtensions; using TestGrainInterfaces; using Tests.GeoClusterTests; @@ -92,12 +91,12 @@ public async Task FourClusterBattery() await t; } - public Task StartClustersAndClients(params int[] silos) + public Task StartClustersAndClients(params short[] silos) { return StartClustersAndClients(null, null, silos); } - public Task StartClustersAndClients(Action config_customizer, Action clientconfig_customizer, params int[] silos) + public Task StartClustersAndClients(Action config_customizer, Action clientconfig_customizer, params short[] silos) { WriteLog("Creating clusters and clients..."); var stopwatch = new System.Diagnostics.Stopwatch(); @@ -493,7 +492,7 @@ await RunWithTimeout("BlockedDeact", 10 * 1000, async () => AssertEqual(1, val, gref); var newid = Clients[1][0].GetRuntimeId(x); WriteLog("{2} sees Grain {0} at {1}", gref, newid, ClusterNames[1]); - Assert.True(Clusters[ClusterNames[1]].Silos[0].SiloAddress.ToString() == newid); + Assert.True(Clusters[ClusterNames[1]].Silos.First().SiloAddress.ToString() == newid); }); } } diff --git a/test/TesterInternal/GeoClusterTests/TestingClusterHost.cs b/test/TesterInternal/GeoClusterTests/TestingClusterHost.cs index 1fdb7ba8a5..ab712cec92 100644 --- a/test/TesterInternal/GeoClusterTests/TestingClusterHost.cs +++ b/test/TesterInternal/GeoClusterTests/TestingClusterHost.cs @@ -1,12 +1,9 @@ using System; using System.Collections.Generic; -using System.Globalization; using System.Linq; using System.Net; -using System.Reflection; using System.Threading.Tasks; using Orleans; -using Orleans.Runtime; using Orleans.Runtime.Configuration; using Orleans.TestingHost; using Tester; @@ -22,28 +19,23 @@ namespace Tests.GeoClusterTests /// public class TestingClusterHost : IDisposable { + public readonly Dictionary Clusters = new Dictionary(); - protected readonly Dictionary Clusters; - private TestingSiloHost siloHost; - - - public TestingSiloOptions siloOptions { get; set; } protected ITestOutputHelper output; - private TimeSpan gossipStabilizationTime; + private TimeSpan gossipStabilizationTime = TimeSpan.FromSeconds(10); public TestingClusterHost(ITestOutputHelper output = null) { this.output = output; - Clusters = new Dictionary(); TestUtils.CheckForAzureStorage(); } - - protected struct ClusterInfo + public struct ClusterInfo { - public List Silos; // currently active silos + public TestCluster Cluster; public int SequenceNumber; // we number created clusters in order of creation + public IEnumerable Silos => Cluster.GetActiveSilos(); } public void WriteLog(string format, params object[] args) @@ -127,7 +119,9 @@ public async Task WaitForMultiClusterGossipToStabilizeAsync(bool account_for_los public Task WaitForLivenessToStabilizeAsync() { - return this.siloHost.WaitForLivenessToStabilizeAsync(); + return this.Clusters.Any() + ? this.Clusters.First().Value.Cluster.WaitForLivenessToStabilizeAsync() + : Task.Delay(gossipStabilizationTime); } private static TimeSpan GetGossipStabilizationTime(GlobalConfiguration global) @@ -139,18 +133,12 @@ private static TimeSpan GetGossipStabilizationTime(GlobalConfiguration global) return stabilizationTime; } - public void StopSilo(SiloHandle instance) - { - siloHost.StopSilo(instance); - } - public void KillSilo(SiloHandle instance) - { - siloHost.KillSilo(instance); - } - public void StopAllSilos() { - siloHost.StopAllSilos(); + foreach (var cluster in Clusters.Values) + { + cluster.Cluster.StopAllSilos(); + } } public ParallelOptions paralleloptions = new ParallelOptions() { MaxDegreeOfParallelism = 4 }; @@ -170,7 +158,7 @@ private static int GetProxyBase(int clusternumber) #region Cluster Creation - public void NewGeoCluster(Guid globalServiceId, string clusterId, int numSilos, Action customizer = null) + public void NewGeoCluster(Guid globalServiceId, string clusterId, short numSilos, Action customizer = null) { Action extendedcustomizer = config => { @@ -194,61 +182,40 @@ public void NewGeoCluster(Guid globalServiceId, string clusterId, int numSilos, } - public void NewCluster(string clusterId, int numSilos, Action customizer = null) + public void NewCluster(string clusterId, short numSilos, Action customizer = null) { + TestCluster testCluster; lock (Clusters) { var myCount = Clusters.Count; WriteLog("Starting Cluster {0} ({1})...", myCount, clusterId); - if (myCount == 0) + var options = new TestClusterOptions(initialSilosCount: numSilos) { - TestingSiloHost.StopAllSilosIfRunning(); - this.siloHost = TestingSiloHost.CreateUninitialized(); - } - - var silohandles = new SiloHandle[numSilos]; - - var options = new TestingSiloOptions - { - StartClient = false, - AdjustConfig = customizer, - BasePort = GetPortBase(myCount), - ProxyBasePort = GetProxyBase(myCount) + BaseSiloPort = GetPortBase(myCount), + BaseGatewayPort = GetProxyBase(myCount) }; - silohandles[0] = TestingSiloHost.StartOrleansSilo(this.siloHost, Silo.SiloType.Primary, options, 0); + options.ClusterConfiguration.AddMemoryStorageProvider("Default"); + options.ClusterConfiguration.AddMemoryStorageProvider("MemoryStore"); - Parallel.For(1, numSilos, paralleloptions, i => - { - silohandles[i] = TestingSiloHost.StartOrleansSilo(this.siloHost, Silo.SiloType.Secondary, options, i); - }); + customizer?.Invoke(options.ClusterConfiguration); + testCluster = new TestCluster(options.ClusterConfiguration, null); + testCluster.Deploy(); Clusters[clusterId] = new ClusterInfo { - Silos = silohandles.ToList(), + Cluster = testCluster, SequenceNumber = myCount }; if (myCount == 0) - gossipStabilizationTime = GetGossipStabilizationTime(this.siloHost.Globals); + gossipStabilizationTime = GetGossipStabilizationTime(options.ClusterConfiguration.Globals); - WriteLog("Cluster {0} started. [{1}]", clusterId, string.Join(" ", silohandles.Select(s => s.ToString()))); + WriteLog("Cluster {0} started. [{1}]", clusterId, string.Join(" ", testCluster.GetActiveSilos().Select(s => s.ToString()))); } } - public void AddSiloToCluster(string clusterId, string siloName, Action customizer = null) - { - var clusterinfo = Clusters[clusterId]; - - var options = new TestingSiloOptions - { - StartClient = false, - AdjustConfig = customizer - }; - - var silo = TestingSiloHost.StartOrleansSilo(this.siloHost, Silo.SiloType.Secondary, options, clusterinfo.Silos.Count); - } public virtual void Dispose() { StopAllClientsAndClusters(); @@ -289,8 +256,7 @@ public void StopAllClusters() Parallel.ForEach(Clusters.Keys, paralleloptions, key => { var info = Clusters[key]; - Parallel.For(1, info.Silos.Count, i => siloHost.StopSilo(info.Silos[i])); - siloHost.StopSilo(info.Silos[0]); + info.Cluster.StopAllSilos(); }); Clusters.Clear(); } @@ -362,7 +328,7 @@ public T NewClient( var name = string.Format("Client-{0}-{1}", clusterId, clientNumber); // clients are assigned to silos round-robin - var gatewayport = ci.Silos[clientNumber % ci.Silos.Count].NodeConfiguration.ProxyGatewayEndpoint.Port; + var gatewayport = ci.Silos.ElementAt(clientNumber).ProxyAddress.Endpoint.Port; WriteLog("Starting {0} connected to {1}", name, gatewayport); @@ -438,7 +404,7 @@ public void SetProtocolMessageFilterForTesting(string origincluster, Func s.Name == siloName); + return Clusters[clusterId].Cluster.GetActiveSilos().FirstOrDefault(s => s.Name == siloName); } } } \ No newline at end of file diff --git a/vNext/test/TesterInternal/TesterInternal.csproj b/vNext/test/TesterInternal/TesterInternal.csproj index baeb1bdc35..f6a3aeabfd 100644 --- a/vNext/test/TesterInternal/TesterInternal.csproj +++ b/vNext/test/TesterInternal/TesterInternal.csproj @@ -51,7 +51,7 @@ - +