Exemplo n.º 1
0
        internal async Task PersistenceStorage_WriteReadWriteRead100StatesInParallel(string prefix = nameof(this.PersistenceStorage_WriteReadWriteRead100StatesInParallel))
        {
            //As data is written and read the ETags are as checked for correctness (they change).
            //Additionally the Store_WriteRead tests does its validation.
            var       grainTypeName   = GrainTypeGenerator.GetGrainType <Guid>();
            int       StartOfRange    = 33900;
            const int CountOfRange    = 100;
            string    grainIdTemplate = $"{prefix}-" + "{0}";
            var       tasks           = Enumerable.Range(StartOfRange, CountOfRange).Select(async i =>
            {
                //Since the version is NULL, storage provider tries to insert this data
                //as new state. If there is already data with this class, the writing fails
                //and the storage provider throws. Essentially it means either this range
                //is ill chosen or the test failed due another problem.
                var grainId   = string.Format(grainIdTemplate, i);
                var grainData = CommonStorageUtilities.GetTestReferenceAndState(grainId, null);

                var firstVersion = grainData.Item2.ETag;
                Assert.Equal(firstVersion, null);
                await Store_WriteRead(grainTypeName, grainData.Item1, grainData.Item2);

                var secondVersion = grainData.Item2.ETag;
                Assert.NotEqual(firstVersion, secondVersion);
                await Store_WriteRead(grainTypeName, grainData.Item1, grainData.Item2);

                var thirdVersion = grainData.Item2.ETag;
                Assert.NotEqual(firstVersion, secondVersion);
                Assert.NotEqual(secondVersion, thirdVersion);
            });
            await Task.WhenAll(tasks);
        }
Exemplo n.º 2
0
        internal async Task PersistenceStorage_WriteReadWriteReadStatesInParallel(string prefix = nameof(this.PersistenceStorage_WriteReadWriteReadStatesInParallel), int countOfGrains = 100)
        {
            //As data is written and read the Version numbers (ETags) are as checked for correctness (they change).
            //Additionally the Store_WriteRead tests does its validation.
            var    grainTypeName   = GrainTypeGenerator.GetGrainType <Guid>();
            int    StartOfRange    = 33900;
            int    CountOfRange    = countOfGrains;
            string grainIdTemplate = $"{prefix}-{{0}}";

            //Since the version is NULL, storage provider tries to insert this data
            //as new state. If there is already data with this class, the writing fails
            //and the storage provider throws. Essentially it means either this range
            //is ill chosen or the test failed due to another problem.
            var grainStates = Enumerable.Range(StartOfRange, CountOfRange).Select(i => this.GetTestReferenceAndState(string.Format(grainIdTemplate, i), null)).ToList();

            // Avoid parallelization of the first write to not stress out the system with deadlocks
            // on INSERT
            foreach (var grainData in grainStates)
            {
                //A sanity checker that the first version really has null as its state. Then it is stored
                //to the database and a new version is acquired.
                var firstVersion = grainData.Item2.ETag;
                Assert.Null(firstVersion);

                await Store_WriteRead(grainTypeName, grainData.Item1, grainData.Item2).ConfigureAwait(false);

                var secondVersion = grainData.Item2.ETag;
                Assert.NotEqual(firstVersion, secondVersion);
            }
            ;

            int MaxNumberOfThreads = Environment.ProcessorCount * 3;

            // The purpose of Parallel.ForEach is to ensure the storage provider will be tested from
            // multiple threads concurrently, as would happen in running system also. Nevertheless
            // limit the degree of parallelization (concurrent threads) to avoid unnecessarily
            // starving and growing the thread pool (which is very slow) if a few threads coupled
            // with parallelization via tasks can force most concurrency scenarios.

            Parallel.ForEach(grainStates, new ParallelOptions {
                MaxDegreeOfParallelism = MaxNumberOfThreads
            }, async grainData =>
            {
                // This loop writes the state consecutive times to the database to make sure its
                // version is updated appropriately.
                for (int k = 0; k < 10; ++k)
                {
                    var versionBefore = grainData.Item2.ETag;
                    await RetryHelper.RetryOnExceptionAsync(5, RetryOperation.Sigmoid, async() =>
                    {
                        await Store_WriteRead(grainTypeName, grainData.Item1, grainData.Item2);
                        return(Task.CompletedTask);
                    });

                    var versionAfter = grainData.Item2.ETag;
                    Assert.NotEqual(versionBefore, versionAfter);
                }
            });
        }
Exemplo n.º 3
0
        /// <summary>
        /// Writes a known inconsistent state to the storage and asserts an exception will be thrown.
        /// </summary>
        /// <returns>The <see cref="InconsistentStateException"/> thrown by the provider. This can be further inspected
        /// by the storage specific asserts.</returns>
        internal async Task <InconsistentStateException> PersistenceStorage_WriteInconsistentFailsWithInconsistentStateException()
        {
            //Some version not expected to be in the storage for this type and ID.
            var inconsistentStateVersion = RandomUtilities.GetRandom <int>().ToString(CultureInfo.InvariantCulture);

            var    inconsistentState = CommonStorageUtilities.GetTestReferenceAndState(RandomUtilities.GetRandom <long>(), inconsistentStateVersion);
            string grainTypeName     = GrainTypeGenerator.GetGrainType <Guid>();
            var    exception         = await Record.ExceptionAsync(() => Store_WriteRead(grainTypeName, inconsistentState.Item1, inconsistentState.Item2));

            Assert.NotNull(exception);
            Assert.IsType <InconsistentStateException>(exception);

            return((InconsistentStateException)exception);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Writes a known inconsistent state to the storage and asserts an exception will be thrown.
        /// </summary>
        /// <returns></returns>
        internal async Task PersistenceStorage_Relational_WriteReadIdCyrillic()
        {
            var grainTypeName  = GrainTypeGenerator.GetGrainType <Guid>();
            var grainReference = CommonStorageUtilities.GetTestReferenceAndState(0, null);
            var grainState     = grainReference.Item2;
            await Storage.WriteStateAsync(grainTypeName, grainReference.Item1, grainState);

            var storedGrainState = new GrainState <TestState1> {
                State = new TestState1()
            };
            await Storage.ReadStateAsync(grainTypeName, grainReference.Item1, storedGrainState);

            Assert.Equal(grainState.ETag, storedGrainState.ETag);
            Assert.Equal(grainState.State, storedGrainState.State);
        }
Exemplo n.º 5
0
        /// <summary>
        /// Writes a known inconsistent state to the storage and asserts an exception will be thrown.
        /// </summary>
        /// <returns></returns>
        internal async Task PersistenceStorage_Relational_WriteReadIdCyrillic()
        {
            var grainTypeName  = GrainTypeGenerator.GetGrainType <Guid>();
            var grainReference = this.GetTestReferenceAndState(0, null);
            var grainState     = grainReference.GrainState;
            await Storage.WriteStateAsync(grainTypeName, grainReference.GrainReference, grainState).ConfigureAwait(false);

            var storedGrainState = new GrainState <TestState1> {
                State = new TestState1()
            };
            await Storage.ReadStateAsync(grainTypeName, grainReference.GrainReference, storedGrainState).ConfigureAwait(false);

            Assert.Equal(grainState.ETag, storedGrainState.ETag);
            Assert.Equal(grainState.State, storedGrainState.State);
        }
Exemplo n.º 6
0
        /// <summary>
        /// Writes to storage and tries to re-write the same state with NULL as ETag, as if the grain was just created.
        /// </summary>
        /// <returns>The <see cref="InconsistentStateException"/> thrown by the provider. This can be further inspected
        /// by the storage specific asserts.</returns>
        internal async Task <InconsistentStateException> PersistenceStorage_WriteDuplicateFailsWithInconsistentStateException()
        {
            //A grain with a random ID will be arranged to the database. Then its state is set to null to simulate the fact
            //it is like a second activation after a one that has succeeded to write.
            string grainTypeName     = GrainTypeGenerator.GetGrainType <Guid>();
            var    inconsistentState = CommonStorageUtilities.GetTestReferenceAndState(RandomUtilities.GetRandom <long>(), null);
            var    grainReference    = inconsistentState.Item1;
            var    grainState        = inconsistentState.Item2;

            await Store_WriteRead(grainTypeName, inconsistentState.Item1, inconsistentState.Item2);

            grainState.ETag = null;
            var exception = await Record.ExceptionAsync(() => Store_WriteRead(grainTypeName, grainReference, grainState));

            Assert.NotNull(exception);
            Assert.IsType <InconsistentStateException>(exception);

            return((InconsistentStateException)exception);
        }
Exemplo n.º 7
0
        internal async Task PersistenceStorage_WriteReadWriteReadStatesInParallel(string prefix = nameof(this.PersistenceStorage_WriteReadWriteReadStatesInParallel), int countOfGrains = 100)
        {
            //As data is written and read the Version numbers (ETags) are as checked for correctness (they change).
            //Additionally the Store_WriteRead tests does its validation.
            var    grainTypeName   = GrainTypeGenerator.GetGrainType <Guid>();
            int    StartOfRange    = 33900;
            int    CountOfRange    = countOfGrains;
            string grainIdTemplate = $"{prefix}-" + "{0}";

            //The purpose of this Task.Run is to ensure the storage provider will be tested from
            //multiple threads concurrently, as would happen in running system also.
            var tasks = Enumerable.Range(StartOfRange, CountOfRange).Select(i => Task.Run(async() =>
            {
                //Since the version is NULL, storage provider tries to insert this data
                //as new state. If there is already data with this class, the writing fails
                //and the storage provider throws. Essentially it means either this range
                //is ill chosen or the test failed due another problem.
                var grainId   = string.Format(grainIdTemplate, i);
                var grainData = CommonStorageUtilities.GetTestReferenceAndState(i, null);

                //A sanity checker that the first version really has null as its state. Then it is stored
                //to the database and a new version is acquired.
                var firstVersion = grainData.Item2.ETag;
                Assert.Equal(firstVersion, null);

                //This loop writes the state consecutive times to the database to make sure its
                //version is updated appropriately.
                await Store_WriteRead(grainTypeName, grainData.Item1, grainData.Item2);
                for (int k = 0; k < 10; ++k)
                {
                    var secondVersion = grainData.Item2.ETag;
                    Assert.NotEqual(firstVersion, secondVersion);
                    await Store_WriteRead(grainTypeName, grainData.Item1, grainData.Item2);

                    var thirdVersion = grainData.Item2.ETag;
                    Assert.NotEqual(firstVersion, secondVersion);
                    Assert.NotEqual(secondVersion, thirdVersion);
                }
            }));
            await Task.WhenAll(tasks);
        }