예제 #1
0
        public void NoDeadLockTest()
        {
            if (BaseTestDatabase.IsSqlite())
            {
                Assert.Ignore("This test doesn't work with Microsoft.Data.Sqlite - SELECT * FROM sys.dm_tran_locks;");
                return;
            }


            Exception      e1 = null, e2 = null;
            AutoResetEvent ev1 = new AutoResetEvent(false), ev2 = new AutoResetEvent(false);

            // testing:
            // two threads will each obtain exclusive write lock over two
            // different lock objects without blocking each other

            var thread1 = new Thread(() => NoDeadLockTestThread(1, ev1, ev2, ref e1));
            var thread2 = new Thread(() => NoDeadLockTestThread(2, ev2, ev1, ref e1));

            // ensure that current scope does not leak into starting threads
            using (ExecutionContext.SuppressFlow())
            {
                thread1.Start();
                thread2.Start();
            }

            ev2.Set();

            thread1.Join();
            thread2.Join();

            Assert.IsNull(e1);
            Assert.IsNull(e2);
        }
예제 #2
0
        public void DeadLockTest()
        {
            if (BaseTestDatabase.IsSqlite())
            {
                Assert.Ignore("This test doesn't work with Microsoft.Data.Sqlite - SELECT * FROM sys.dm_tran_locks;");
                return;
            }

            Exception      e1 = null, e2 = null;
            AutoResetEvent ev1 = new AutoResetEvent(false), ev2 = new AutoResetEvent(false);

            // testing:
            // two threads will each obtain exclusive write locks over two
            // identical lock objects deadlock each other

            var thread1 = new Thread(() => DeadLockTestThread(1, 2, ev1, ev2, ref e1));
            var thread2 = new Thread(() => DeadLockTestThread(2, 1, ev2, ev1, ref e2));

            // ensure that current scope does not leak into starting threads
            using (ExecutionContext.SuppressFlow())
            {
                thread1.Start();
                thread2.Start();
            }

            ev2.Set();

            thread1.Join();
            thread2.Join();

            //Assert.IsNotNull(e1);
            if (e1 != null)
            {
                AssertIsDistributedLockingTimeoutException(e1);
            }

            // the assertion below depends on timing conditions - on a fast enough environment,
            // thread1 dies (deadlock) and frees thread2, which succeeds - however on a slow
            // environment (CI) both threads can end up dying due to deadlock - so, cannot test
            // that e2 is null - but if it's not, can test that it's a timeout
            //
            //Assert.IsNull(e2);
            if (e2 != null)
            {
                AssertIsDistributedLockingTimeoutException(e2);
            }
        }
예제 #3
0
        public void CreateKeysAndIndexes()
        {
            if (BaseTestDatabase.IsSqlite())
            {
                // TODO: Think about this for future migrations.
                Assert.Ignore("Can't add / drop keys in SQLite.");
                return;
            }

            IMigrationBuilder builder = Mock.Of <IMigrationBuilder>();

            Mock.Get(builder)
            .Setup(x => x.Build(It.IsAny <Type>(), It.IsAny <IMigrationContext>()))
            .Returns <Type, IMigrationContext>((t, c) =>
            {
                switch (t.Name)
                {
                case "CreateTableOfTDtoMigration":
                    return(new CreateTableOfTDtoMigration(c));

                case "DeleteKeysAndIndexesMigration":
                    return(new DeleteKeysAndIndexesMigration(c));

                case "CreateKeysAndIndexesMigration":
                    return(new CreateKeysAndIndexesMigration(c));

                default:
                    throw new NotSupportedException();
                }
            });

            using (IScope scope = ScopeProvider.CreateScope())
            {
                var upgrader = new Upgrader(
                    new MigrationPlan("test")
                    .From(string.Empty)
                    .To <CreateTableOfTDtoMigration>("a")
                    .To <DeleteKeysAndIndexesMigration>("b")
                    .To <CreateKeysAndIndexesMigration>("done"));

                upgrader.Execute(MigrationPlanExecutor, ScopeProvider, Mock.Of <IKeyValueService>());
                scope.Complete();
            }
        }
예제 #4
0
        public void Throws_When_Lock_Timeout_Is_Exceeded_Read()
        {
            if (BaseTestDatabase.IsSqlite())
            {
                // Reader reads snapshot, isolated from the writer.
                Assert.Ignore("Doesn't apply to SQLite with journal_mode=wal");
            }

            using (ExecutionContext.SuppressFlow())
            {
                var t1 = Task.Run(() =>
                {
                    using (var scope = ScopeProvider.CreateScope())
                    {
                        Console.WriteLine("Write lock A");
                        // This will acquire right away
                        scope.EagerWriteLock(TimeSpan.FromMilliseconds(2000), Constants.Locks.ContentTree);
                        Thread.Sleep(6000); // Wait longer than the Read Lock B timeout
                        scope.Complete();
                        Console.WriteLine("Finished Write lock A");
                    }
                });

                Thread.Sleep(500); // 100% sure task 1 starts first

                var t2 = Task.Run(() =>
                {
                    using (var scope = ScopeProvider.CreateScope())
                    {
                        Console.WriteLine("Read lock B");

                        // This will wait for the write lock to release but it isn't going to wait long
                        // enough so an exception will be thrown.
                        Assert.Throws <DistributedReadLockTimeoutException>(() =>
                                                                            scope.EagerReadLock(TimeSpan.FromMilliseconds(3000), Constants.Locks.ContentTree));
                        scope.Complete();
                        Console.WriteLine("Finished Read lock B");
                    }
                });

                Task.WaitAll(t1, t2);
            }
        }
예제 #5
0
        public void Read_Lock_Waits_For_Write_Lock()
        {
            if (BaseTestDatabase.IsSqlite())
            {
                // Reader reads snapshot, isolated from the writer.
                Assert.Ignore("Doesn't apply to SQLite with journal_mode=wal");
            }

            var locksCompleted = 0;

            using (ExecutionContext.SuppressFlow())
            {
                var t1 = Task.Run(() =>
                {
                    using (var scope = ScopeProvider.CreateScope())
                    {
                        Console.WriteLine("Write lock A");
                        // This will acquire right away
                        scope.EagerWriteLock(TimeSpan.FromMilliseconds(2000), Constants.Locks.ContentTree);
                        Thread.Sleep(4000); // Wait less than the Read Lock B timeout
                        scope.Complete();
                        Interlocked.Increment(ref locksCompleted);
                        Console.WriteLine("Finished Write lock A");
                    }
                });

                Thread.Sleep(500); // 100% sure task 1 starts first

                var t2 = Task.Run(() =>
                {
                    using (var scope = ScopeProvider.CreateScope())
                    {
                        Console.WriteLine("Read lock B");

                        // This will wait for the write lock to release
                        Assert.DoesNotThrow(() =>
                                            scope.EagerReadLock(TimeSpan.FromMilliseconds(6000), Constants.Locks.ContentTree));

                        Assert.GreaterOrEqual(locksCompleted, 1);

                        scope.Complete();
                        Interlocked.Increment(ref locksCompleted);
                        Console.WriteLine("Finished Read lock B");
                    }
                });


                var t3 = Task.Run(() =>
                {
                    using (var scope = ScopeProvider.CreateScope())
                    {
                        Console.WriteLine("Read lock C");

                        // This will wait for the write lock to release
                        Assert.DoesNotThrow(() =>
                                            scope.EagerReadLock(TimeSpan.FromMilliseconds(6000), Constants.Locks.ContentTree));

                        Assert.GreaterOrEqual(locksCompleted, 1);

                        scope.Complete();
                        Interlocked.Increment(ref locksCompleted);
                        Console.WriteLine("Finished Read lock C");
                    }
                });

                Task.WaitAll(t1, t2, t3);
            }

            Assert.AreEqual(3, locksCompleted);
        }