コード例 #1
0
ファイル: Scenarios.cs プロジェクト: hfriedrich/SnowMaker
        public async Task ShouldUpdateBlobWhenGeneratingNextIdAfterEndOfBatch()
        {
            // Arrange
            using (var testScope = BuildTestScope())
            {
                var store = await BuildStoreAsync(testScope);

                var generator = new UniqueIdGenerator(store)
                {
                    BatchSize = 3
                };

                // Act
                await generator.NextIdAsync(testScope.IdScopeName); //1

                await generator.NextIdAsync(testScope.IdScopeName); //2

                await generator.NextIdAsync(testScope.IdScopeName); //3

                await generator.NextIdAsync(testScope.IdScopeName); //4

                // Assert
                Assert.AreEqual("7", await testScope.ReadCurrentPersistedValueAsync());
            }
        }
コード例 #2
0
ファイル: Scenarios.cs プロジェクト: hfriedrich/SnowMaker
        public async Task ShouldReturnIdsFromThirdBatchIfSecondBatchTakenByAnotherGenerator()
        {
            // Arrange
            using (var testScope = BuildTestScope())
            {
                var store1 = await BuildStoreAsync(testScope);

                var generator1 = new UniqueIdGenerator(store1)
                {
                    BatchSize = 3
                };
                var store2 = await BuildStoreAsync(testScope);

                var generator2 = new UniqueIdGenerator(store2)
                {
                    BatchSize = 3
                };

                // Act
                await generator1.NextIdAsync(testScope.IdScopeName);              //1

                await generator1.NextIdAsync(testScope.IdScopeName);              //2

                await generator1.NextIdAsync(testScope.IdScopeName);              //3

                await generator2.NextIdAsync(testScope.IdScopeName);              //4

                var lastId = await generator1.NextIdAsync(testScope.IdScopeName); //7

                // Assert
                Assert.AreEqual(7, lastId);
            }
        }
コード例 #3
0
        public async Task NextIdShouldReturnNumbersSequentially()
        {
            var store = Substitute.For <IOptimisticDataStore>();

            store.GetDataAsync("test").Returns(Task.FromResult("0"), Task.FromResult("250"));
            store.TryOptimisticWriteAsync("test", "3").Returns(Task.FromResult(true));

            var subject = new UniqueIdGenerator(store)
            {
                BatchSize = 3
            };

            Assert.AreEqual(0, await subject.NextIdAsync("test"));
            Assert.AreEqual(1, await subject.NextIdAsync("test"));
            Assert.AreEqual(2, await subject.NextIdAsync("test"));
        }
コード例 #4
0
        public async Task ShouldSupportUsingMultipleGeneratorsFromMultipleThreads()
        {
            // Arrange
            using (var testScope = BuildTestScope())
            {
                var store = await BuildStoreAsync(testScope);

                var generator = new UniqueIdGenerator(store)
                {
                    BatchSize = 1000
                };
                var store2 = await BuildStoreAsync(testScope);

                var generator2 = new UniqueIdGenerator(store2)
                {
                    BatchSize = 1000
                };
                const int testLength = 10000;

                // Act
                var generatedIds = new ConcurrentQueue <long>();
                var threadIds    = new ConcurrentQueue <int>();
                var scopeName    = testScope.IdScopeName;

                var listToExecute = new List <int>();
                for (int i = 0; i < testLength; i++)
                {
                    listToExecute.Add(i);
                }

                var tasks = listToExecute.ForEachAsync(10, async item =>
                {
                    var idToAdd = await generator.NextIdAsync(scopeName);
                    generatedIds.Enqueue(idToAdd);
                    threadIds.Enqueue(Thread.CurrentThread.ManagedThreadId);
                });
                var tasks2 = listToExecute.ForEachAsync(10, async item =>
                {
                    var idToAdd = await generator2.NextIdAsync(scopeName);
                    generatedIds.Enqueue(idToAdd);
                    threadIds.Enqueue(Thread.CurrentThread.ManagedThreadId);
                });

                await Task.WhenAll(tasks, tasks2);

                // Assert we generated the right count of ids
                Assert.AreEqual(testLength * 2, generatedIds.Count, "wrong number of ids generated");

                // Assert there were no duplicates
                Assert.IsFalse(generatedIds.GroupBy(n => n).Any(g => g.Count() != 1), "duplicated ids were generated");

                // Assert we used multiple threads
                var uniqueThreadsUsed = threadIds.Distinct().Count();
                if (uniqueThreadsUsed == 1)
                {
                    Assert.Inconclusive("The test failed to actually utilize multiple threads. {0} uniqueThreadsUsed", uniqueThreadsUsed);
                }
            }
        }
コード例 #5
0
#pragma warning disable 1998
        public async Task NextIdShouldThrowExceptionOnNullData()
#pragma warning restore 1998
        {
            var ex = Assert.ThrowsAsync <UniqueIdGenerationException>(async() =>
            {
                var store = Substitute.For <IOptimisticDataStore>();
                store.GetDataAsync("test").Returns(Task.FromResult((string)null));

                var generator = new UniqueIdGenerator(store);

                await generator.NextIdAsync("test");
            });
        }
コード例 #6
0
ファイル: Scenarios.cs プロジェクト: hfriedrich/SnowMaker
        public async Task ShouldReturnIdsAcrossMultipleGenerators()
        {
            // Arrange
            using (var testScope = BuildTestScope())
            {
                var store1 = await BuildStoreAsync(testScope);

                var generator1 = new UniqueIdGenerator(store1)
                {
                    BatchSize = 3
                };
                var store2 = await BuildStoreAsync(testScope);

                var generator2 = new UniqueIdGenerator(store2)
                {
                    BatchSize = 3
                };

                // Act
                var generatedIds = new[]
                {
                    await generator1.NextIdAsync(testScope.IdScopeName), //1
                    await generator1.NextIdAsync(testScope.IdScopeName), //2
                    await generator1.NextIdAsync(testScope.IdScopeName), //3
                    await generator2.NextIdAsync(testScope.IdScopeName), //4
                    await generator1.NextIdAsync(testScope.IdScopeName), //7
                    await generator2.NextIdAsync(testScope.IdScopeName), //5
                    await generator2.NextIdAsync(testScope.IdScopeName), //6
                    await generator2.NextIdAsync(testScope.IdScopeName), //10
                    await generator1.NextIdAsync(testScope.IdScopeName), //8
                    await generator1.NextIdAsync(testScope.IdScopeName)  //9
                };

                // Assert
                CollectionAssert.AreEqual(
                    new[] { 1, 2, 3, 4, 7, 5, 6, 10, 8, 9 },
                    generatedIds);
            }
        }
コード例 #7
0
ファイル: Scenarios.cs プロジェクト: hfriedrich/SnowMaker
        public async Task ShouldInitializeBlobForFirstIdInNewScope()
        {
            // Arrange
            using (var testScope = BuildTestScope())
            {
                var store = await BuildStoreAsync(testScope);

                var generator = new UniqueIdGenerator(store)
                {
                    BatchSize = 3
                };

                // Act
                await generator.NextIdAsync(testScope.IdScopeName); //1

                // Assert
                Assert.AreEqual("4", await testScope.ReadCurrentPersistedValueAsync());
            }
        }
コード例 #8
0
ファイル: Scenarios.cs プロジェクト: hfriedrich/SnowMaker
        public async Task ShouldReturnOneForFirstIdInNewScope()
        {
            // Arrange
            using (var testScope = BuildTestScope())
            {
                var store = await BuildStoreAsync(testScope);

                var generator = new UniqueIdGenerator(store)
                {
                    BatchSize = 3
                };

                // Act
                var generatedId = await generator.NextIdAsync(testScope.IdScopeName);

                // Assert
                Assert.AreEqual(1, generatedId);
            }
        }
コード例 #9
0
        public async Task NextIdShouldThrowExceptionWhenRetriesAreExhausted()
        {
            var store = Substitute.For <IOptimisticDataStore>();

            store.GetDataAsync("test").Returns(Task.FromResult("0"));
            store.TryOptimisticWriteAsync("test", "3").Returns(Task.FromResult(false), Task.FromResult(false), Task.FromResult(false), Task.FromResult(true));

            var generator = new UniqueIdGenerator(store)
            {
                MaxWriteAttempts = 3
            };

            try
            {
                await generator.NextIdAsync("test");
            }
            catch (Exception ex)
            {
                StringAssert.StartsWith("Failed to update the data store after 3 attempts.", ex.Message);
                return;
            }
            Assert.Fail("NextId should have thrown and been caught in the try block");
        }
コード例 #10
0
        public async Task NextIdShouldRollOverToNewBlockWhenCurrentBlockIsExhausted()
        {
            var store = Substitute.For <IOptimisticDataStore>();

            store.GetDataAsync("test").Returns(Task.FromResult("0"), Task.FromResult("250"));
            store.TryOptimisticWriteAsync("test", "3").Returns(Task.FromResult(true));
            store.TryOptimisticWriteAsync("test", "253").Returns(Task.FromResult(true));

            var subject = new UniqueIdGenerator(store)
            {
                BatchSize = 3
            };

            Assert.AreEqual(0, (await subject.NextIdAsync("test")));
            Assert.AreEqual(1, (await subject.NextIdAsync("test")));
            Assert.AreEqual(2, (await subject.NextIdAsync("test")));
            Assert.AreEqual(250, (await subject.NextIdAsync("test")));
            Assert.AreEqual(251, (await subject.NextIdAsync("test")));
            Assert.AreEqual(252, (await subject.NextIdAsync("test")));
        }