Esempio n. 1
0
        public void AddDeleteAddSameObjectInstance_MustFail()
        {
            // Due to the way version is managed it's crutial that added objects are new instances

            var manager = new InMemoryObjectManager();

            // FIRST TRANSACTION: Add two object
            var firstTransaction = manager.CreateTransaction();

            var firstObj = new TestObjectA(Guid.NewGuid(), "first object");

            firstTransaction.Add(firstObj);

            firstTransaction.Commit();

            // SECOND TRANSACTION: Delete first object
            var secondTransaction = manager.CreateTransaction();

            secondTransaction.Delete(firstObj.Id);

            secondTransaction.Commit();

            // THIRD TRANSACTION: Add first object again - same instance - must fail
            var thirdTransaction = manager.CreateTransaction();

            Assert.Throws <OperationCanceledException>(() => thirdTransaction.Add(firstObj));
        }
Esempio n. 2
0
        public void AddedObject_ShouldGetCreationStateAssignedOnCommit()
        {
            var manager = new InMemoryObjectManager();

            var transaction = manager.CreateTransaction();

            // Internal version id should be 1
            Assert.Equal(1, transaction.Version.InternalVersionId);

            var objToAdd = new TestObjectA(Guid.NewGuid(), "hej");

            transaction.Add(objToAdd);

            // Creation version should not be assigned yet
            Assert.Null(objToAdd.CreationVersion);

            // Deletion version should be null
            Assert.Null(objToAdd.DeletionVersion);

            transaction.Commit();

            // Creation version should now be assigned
            Assert.Equal(transaction.Version, objToAdd.CreationVersion);

            // Deletion version should still be null
            Assert.Null(objToAdd.DeletionVersion);
        }
Esempio n. 3
0
        public void AddDeleteTest_GetObjectsMustReturnCorrectResult()
        {
            var manager = new InMemoryObjectManager();

            // FIRST TRANSACTION: Add two object
            var firstTransaction = manager.CreateTransaction();

            var firstObj = new TestObjectA(Guid.NewGuid(), "first object");

            firstTransaction.Add(firstObj);

            var secondObj = new TestObjectA(Guid.NewGuid(), "second object");

            firstTransaction.Add(secondObj);

            firstTransaction.Commit();

            // SECOND TRANSACTION: Delete first object
            var secondTransaction = manager.CreateTransaction();

            secondTransaction.Delete(firstObj.Id);

            secondTransaction.Commit();

            // THIRD TRANSACTION: Delete second object
            var thirdTransaction = manager.CreateTransaction();

            thirdTransaction.Delete(secondObj.Id);

            thirdTransaction.Commit();

            // FORTH TRANSACTION: Add second object again
            var forthTransaction = manager.CreateTransaction();

            forthTransaction.Add(new TestObjectA(secondObj.Id, "second object version 2"));

            forthTransaction.Commit();

            // In version 1 we should have 2 object
            Assert.Equal(2, manager.GetObjects(1).Count());
            // In version 1 name of first object should be "first object"
            Assert.Contains(manager.GetObjects(1), o => o.Id == firstObj.Id && ((TestObjectA)o).Name == "first object");
            // In version 1 name of second object should be "second object"
            Assert.Contains(manager.GetObjects(1), o => o.Id == secondObj.Id && ((TestObjectA)o).Name == "second object");

            // In version 2 we should have only 1 object
            Assert.Single(manager.GetObjects(2));
            // In version 2 we should have the second object named "second object"
            Assert.Contains(manager.GetObjects(2), o => o.Id == secondObj.Id && ((TestObjectA)o).Name == "second object");

            // In version 3 we should have no objects
            Assert.Empty(manager.GetObjects(3));

            // In version 4 we should have 1 object
            Assert.Single(manager.GetObjects(4));
            // In version 4 we should have the second object named "second object version 2"
            Assert.Contains(manager.GetObjects(4), o => o.Id == secondObj.Id && ((TestObjectA)o).Name == "second object version 2");
        }
Esempio n. 4
0
        public void AddingTheSameObjectTwiceInTheSameTransactions_MustFail()
        {
            var manager = new InMemoryObjectManager();

            var firstTransaction = manager.CreateTransaction();

            var objToAdd = new TestObjectA(Guid.NewGuid(), "hej");

            firstTransaction.Add(objToAdd);
            Assert.Throws <OperationCanceledException>(() => firstTransaction.Add(objToAdd));
        }
Esempio n. 5
0
        public void AddAfterRollback_MustFail()
        {
            var manager = new InMemoryObjectManager();

            var firstTransaction = manager.CreateTransaction();

            firstTransaction.Add(new TestObjectA(Guid.NewGuid(), "hello"));
            firstTransaction.Rollback();

            Assert.Throws <OperationCanceledException>(() => firstTransaction.Add(new TestObjectA(Guid.NewGuid(), "kitty")));
        }
Esempio n. 6
0
        public void DeleteAfterCommit_MustFail()
        {
            var manager = new InMemoryObjectManager();

            var firstTransaction = manager.CreateTransaction();

            var objToAdd = new TestObjectA(Guid.NewGuid(), "hello");

            firstTransaction.Add(objToAdd);
            firstTransaction.Commit();

            Assert.Throws <OperationCanceledException>(() => firstTransaction.Delete(objToAdd.Id));
        }
        public void CreateTwoTransactionWithSameCustomId_MustFail()
        {
            var manager = new InMemoryObjectManager();

            // First transaction
            var firstTransaction = manager.CreateTransaction("my custom version id 1");

            var objToAdd = new TestObjectA(Guid.NewGuid(), "hej");

            firstTransaction.Add(objToAdd);
            firstTransaction.Commit();

            // Create second transaction with the same version id
            Assert.Throws <ArgumentException>(() => manager.CreateTransaction("my custom version id 1"));
        }
Esempio n. 8
0
        public void AddingObjects_GetObjectsMustReturnCorrectNumberOfObjects()
        {
            var manager = new InMemoryObjectManager();

            // We should have zero object in the manager
            Assert.Empty(manager.GetObjects());

            // FIRST TRANSACTION
            var firstTransaction = manager.CreateTransaction();

            firstTransaction.Add(new TestObjectA(Guid.NewGuid(), "first object"));

            Assert.Empty(manager.GetObjects()); // We should still have zero object in the manager, because transaction is not commited yet

            firstTransaction.Commit();

            Assert.Single(manager.GetObjects()); // We should have one object in the manager after transaction commit


            // SECOND TRANSACTION
            var secondTransaction = manager.CreateTransaction();

            secondTransaction.Add(new TestObjectA(Guid.NewGuid(), "second object"));

            Assert.Single(manager.GetObjects()); // We should have one object in the manager before transaction commit

            secondTransaction.Commit();

            Assert.Equal(2, manager.GetObjects().Count()); // We should have two object in the manager before transaction commit


            // THIRD TRANSACTION
            var thirdTransaction = manager.CreateTransaction();

            thirdTransaction.Add(new TestObjectA(Guid.NewGuid(), "third object"));
            thirdTransaction.Add(new TestObjectA(Guid.NewGuid(), "forth object"));

            Assert.Equal(2, manager.GetObjects().Count()); // We should have two object in the manager before transaction commit

            thirdTransaction.Commit();

            Assert.Equal(4, manager.GetObjects().Count()); // We should have four object in the manager before transaction commit

            // Assert that GetObjects by internal version id works
            Assert.Single(manager.GetObjects(1));           // In version 1 we should have 1 object
            Assert.Equal(2, manager.GetObjects(2).Count()); // In version 2 we should have 2 object
            Assert.Equal(4, manager.GetObjects(3).Count()); // In version 3 we should have 4 object
        }
Esempio n. 9
0
        public void InvalidFromAndToVersionIds_ShouldFail(int fromVersionId, int toVersionId)
        {
            var manager = new InMemoryObjectManager();

            ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
            // FIRST TRANSACTION
            var firstTransaction = manager.CreateTransaction();

            var firstObj  = firstTransaction.Add(new TestObjectA(Guid.NewGuid(), "first object"));
            var secondObj = firstTransaction.Add(new TestObjectA(Guid.NewGuid(), "second object"));
            var thirdObj  = firstTransaction.Add(new TestObjectA(Guid.NewGuid(), "third object"));

            firstTransaction.Commit();

            Assert.Throws <ArgumentException>(() => manager.GetChanges(fromVersionId, toVersionId));
        }
Esempio n. 10
0
        public void UpdateObjectWithSameInstance_MustFail()
        {
            var manager = new InMemoryObjectManager();

            // FIRST TRANSACTION: Add two object
            var firstTransaction = manager.CreateTransaction();

            var firstObj = new TestObjectA(Guid.NewGuid(), "first object");

            firstTransaction.Add(firstObj);

            firstTransaction.Commit();

            // SECOND TRANSACTION: Update object using same instance - must fail
            var secondTransaction = manager.CreateTransaction();

            Assert.Throws <OperationCanceledException>(() => secondTransaction.Update(firstObj));
        }
Esempio n. 11
0
        public void DiffBetweenTwoAdjacentVersions_CheckResult()
        {
            var manager = new InMemoryObjectManager();

            ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
            // FIRST TRANSACTION
            var firstTransaction = manager.CreateTransaction();

            var firstObj  = firstTransaction.Add(new TestObjectA(Guid.NewGuid(), "first object"));
            var secondObj = firstTransaction.Add(new TestObjectA(Guid.NewGuid(), "second object"));
            var thirdObj  = firstTransaction.Add(new TestObjectA(Guid.NewGuid(), "third object"));

            firstTransaction.Commit();

            ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
            // SECOND TRANSACTION
            var secondTransaction = manager.CreateTransaction();

            // Insert forth object
            var forthObj = secondTransaction.Add(new TestObjectA(Guid.NewGuid(), "forth object"));

            // Delete second object
            secondTransaction.Delete(secondObj.Id);

            // Update third object
            var thirdObjUpdated = new TestObjectA(thirdObj.Id, "third object updated");

            secondTransaction.Update(thirdObjUpdated);

            secondTransaction.Commit();

            ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
            // Get the changes and assert correctness
            var changes = manager.GetChanges(1, 2);

            // We did 3 changes: add, delete and update.
            Assert.Equal(3, changes.Count());

            Assert.Contains(changes, c => c is ObjectCreation && ((ObjectCreation)c).NewState == forthObj);
            Assert.Contains(changes, c => c is ObjectDeletion && c.Id == secondObj.Id);
            Assert.Contains(changes, c => c is ObjectModification && ((ObjectModification)c).NewState == thirdObjUpdated && ((ObjectModification)c).PreviousState == thirdObj);
        }
Esempio n. 12
0
        public void AddingObject_TestGetObject()
        {
            var manager = new InMemoryObjectManager();

            var firstTransaction = manager.CreateTransaction("custom version id");

            var objToAdd = new TestObjectA(Guid.NewGuid(), "hej");

            firstTransaction.Add(objToAdd);
            firstTransaction.Commit();

            // Asset that GetObject(guid id) workd
            Assert.Equal(objToAdd, manager.GetObject(objToAdd.Id));

            // Asset that GetObject(guid id, long version id) works
            Assert.Equal(objToAdd, manager.GetObject(objToAdd.Id, 1));

            // Asset that GetObject(custom, string version id ) works
            Assert.Equal(objToAdd, manager.GetObject(objToAdd.Id, "custom version id"));
        }
Esempio n. 13
0
        public void WorkAfterRollback_ShouldNotBeCommited()
        {
            var manager = new InMemoryObjectManager();

            ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
            // FIRST TRANSACTION
            var firstTransaction = manager.CreateTransaction();

            var firstObj  = firstTransaction.Add(new TestObjectA(Guid.NewGuid(), "first object"));
            var secondObj = firstTransaction.Add(new TestObjectA(Guid.NewGuid(), "second object"));
            var thirdObj  = firstTransaction.Add(new TestObjectA(Guid.NewGuid(), "third object"));

            firstTransaction.Commit();

            ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
            // SECOND TRANSACTION
            var secondTransaction = manager.CreateTransaction();

            // Insert forth object
            var forthObj = secondTransaction.Add(new TestObjectA(Guid.NewGuid(), "forth object"));

            // Delete second object
            secondTransaction.Delete(secondObj.Id);

            // Update third object
            var thirdObjUpdated = new TestObjectA(thirdObj.Id, "third object updated");

            secondTransaction.Update(thirdObjUpdated);

            secondTransaction.Rollback();

            // In version 1 we should have 3 object
            Assert.Equal(3, manager.GetObjects(1).Count());
            // In version 1 name of first object should be "first object"
            Assert.Contains(manager.GetObjects(1), o => o.Id == firstObj.Id && ((TestObjectA)o).Name == "first object");
            // In version 1 name of second object should be "second object"
            Assert.Contains(manager.GetObjects(1), o => o.Id == secondObj.Id && ((TestObjectA)o).Name == "second object");

            // Version 2 should not exist, because we did a rollback of the second transaction
            Assert.Throws <ArgumentException>(() => manager.GetObjects(2));
        }
Esempio n. 14
0
        public void UpdateObject_GetObjectsMustReturnCorrectResult()
        {
            var manager = new InMemoryObjectManager();

            // FIRST TRANSACTION: Add two object
            var firstTransaction = manager.CreateTransaction();

            var firstObj = new TestObjectA(Guid.NewGuid(), "first object");

            firstTransaction.Add(firstObj);

            var secondObj = new TestObjectA(Guid.NewGuid(), "second object");

            firstTransaction.Add(secondObj);

            firstTransaction.Commit();

            // SECOND TRANSACTION: Update name of second object
            var secondTransaction = manager.CreateTransaction();

            var updatedObj = new TestObjectA(secondObj.Id, "second object updated");

            secondTransaction.Update(updatedObj);

            secondTransaction.Commit();

            // In version 1 we should have 2 object
            Assert.Equal(2, manager.GetObjects(1).Count());
            // In version 1 name of first object should be "first object"
            Assert.Contains(manager.GetObjects(1), o => o.Id == firstObj.Id && ((TestObjectA)o).Name == "first object");
            // In version 1 name of second object should be "second object"
            Assert.Contains(manager.GetObjects(1), o => o.Id == secondObj.Id && ((TestObjectA)o).Name == "second object");

            // In version 2 we should still have 2 object
            Assert.Equal(2, manager.GetObjects(2).Count());
            // In version 2 name of first object should still be "first object"
            Assert.Contains(manager.GetObjects(2), o => o.Id == firstObj.Id && ((TestObjectA)o).Name == "first object");
            // In version 2 name of second object should be changed to "second object updated"
            Assert.Contains(manager.GetObjects(2), o => o.Id == secondObj.Id && ((TestObjectA)o).Name == "second object updated");
        }
Esempio n. 15
0
        public void DeleteObject_GetObjectsMustReturnCorrectResult()
        {
            var manager = new InMemoryObjectManager();

            // FIRST TRANSACTION: Add two object
            var firstTransaction = manager.CreateTransaction();

            var firstObj = new TestObjectA(Guid.NewGuid(), "first object");

            firstTransaction.Add(firstObj);

            var secondObj = new TestObjectA(Guid.NewGuid(), "second object");

            firstTransaction.Add(secondObj);

            firstTransaction.Commit();

            // SECOND TRANSACTION: Delete first object
            var secondTransaction = manager.CreateTransaction();

            secondTransaction.Delete(firstObj.Id);

            secondTransaction.Commit();

            // Deletion version should not be null
            Assert.NotNull(firstObj.DeletionVersion);

            // In version 1 we should have 2 object
            Assert.Equal(2, manager.GetObjects(1).Count());
            // In version 1 name of first object should be "first object"
            Assert.Contains(manager.GetObjects(1), o => o.Id == firstObj.Id && ((TestObjectA)o).Name == "first object");
            // In version 1 name of second object should be "second object"
            Assert.Contains(manager.GetObjects(1), o => o.Id == secondObj.Id && ((TestObjectA)o).Name == "second object");

            // In version 2 we should have only 1 object
            Assert.Single(manager.GetObjects(2));
            // In version 2 we should have the second object named "second object"
            Assert.Contains(manager.GetObjects(2), o => o.Id == secondObj.Id && ((TestObjectA)o).Name == "second object");
        }
        public void CreateTransactionWithCustomId_TestGetObject()
        {
            var manager = new InMemoryObjectManager();

            var myCustomId = "my custom version id 1";

            var firstTransaction = manager.CreateTransaction(myCustomId);

            var objToAdd = new TestObjectA(Guid.NewGuid(), "hej");

            firstTransaction.Add(objToAdd);
            firstTransaction.Commit();


            // Asser that GetObjects work with custom ids
            var objects = manager.GetObjects(myCustomId);

            Assert.Single(objects);

            var obj = manager.GetObject(objToAdd.Id, myCustomId);

            Assert.Equal(objToAdd, obj);
        }
        public void CreateSimpleGraph_CheckNodeAndEdgeTraversal()
        {
            //    N1
            //    |
            // E1 |
            //    |      E2
            //    N2-------------N3

            var manager = new InMemoryObjectManager();

            var trans = manager.CreateTransaction();

            var n1 = new GraphNode(Guid.NewGuid());

            trans.Add(n1);

            var n2 = new GraphNode(Guid.NewGuid());

            trans.Add(n2);

            var n3 = new GraphNode(Guid.NewGuid());

            trans.Add(n3);

            var e1 = new GraphEdge(Guid.NewGuid(), n1, n2);

            trans.Add(e1);

            var e2 = new GraphEdge(Guid.NewGuid(), n2, n3);

            trans.Add(e2);

            trans.Commit();

            var version = trans.Version.InternalVersionId;

            // N1 should have zero ingoing edges
            Assert.Empty(n1.InE(version));

            // N1 should have one outgoing edge
            Assert.Single(n1.OutE(version));
            Assert.Contains(e1, n1.OutE(version).Where(e => e.Id == e1.Id));

            // N2 should have one ingoing edge
            Assert.Single(n2.InE(version));
            Assert.Contains(e1, n2.InE(version).Where(e => e.Id == e1.Id));

            // N2 should have one outgoing edge
            Assert.Single(n2.OutE(version));
            Assert.Contains(e2, n2.OutE(version).Where(e => e.Id == e2.Id));

            // N3 should have one ingoing edges
            Assert.Single(n3.InE(version));
            Assert.Contains(e2, n3.InE(version).Where(e => e.Id == e2.Id));

            // N3 should have zero outgoing edges
            Assert.Empty(n3.OutE(version));

            // E1 should have n1 as ingoing node
            Assert.Equal(n1, e1.InV(version));

            // E1 should have n2 as ingoing node
            Assert.Equal(n2, e1.OutV(version));

            // E2 should have n2 as ingoing node
            Assert.Equal(n2, e2.InV(version));

            // E2 should have n3 as ingoing node
            Assert.Equal(n3, e2.OutV(version));

            // Try traverse the graph from node 1
            var traceResult = n1.UndirectionalDFS <GraphNode, GraphEdge>(version);

            Assert.Equal(5, traceResult.Count());
        }
 internal InMemoryTransaction(InMemoryObjectManager objectManager, IVersion state)
 {
     _objectManager    = objectManager;
     _version          = state;
     _transactionState = TransactionState.Running;
 }
Esempio n. 19
0
        public void DiffBetweenManyVersions_CheckResult()
        {
            var manager = new InMemoryObjectManager();

            ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
            // FIRST TRANSACTION
            var firstTransaction = manager.CreateTransaction();

            var firstObj  = firstTransaction.Add(new TestObjectA(Guid.NewGuid(), "first object"));
            var secondObj = firstTransaction.Add(new TestObjectA(Guid.NewGuid(), "second object"));
            var thirdObj  = firstTransaction.Add(new TestObjectA(Guid.NewGuid(), "third object"));

            firstTransaction.Commit();

            ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
            // SECOND TRANSACTION
            var secondTransaction = manager.CreateTransaction();

            // Insert forth object
            var forthObj = secondTransaction.Add(new TestObjectA(Guid.NewGuid(), "forth object"));

            // Delete second object
            secondTransaction.Delete(secondObj.Id);

            // Update third object
            var thirdObjUpdatedFirstTime = new TestObjectA(thirdObj.Id, "third object updated first time");

            secondTransaction.Update(thirdObjUpdatedFirstTime);

            secondTransaction.Commit();


            ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
            // THIRD TRANSACTION
            var thirdTransaction = manager.CreateTransaction();

            // Insert fifth object
            var fifthObj = thirdTransaction.Add(new TestObjectA(Guid.NewGuid(), "fifth object"));

            // Delete first object
            thirdTransaction.Delete(firstObj.Id);

            // Update third object again
            var thirdObjUpdatedSecondTime = new TestObjectA(thirdObj.Id, "third object updated second time");

            thirdTransaction.Update(thirdObjUpdatedSecondTime);

            thirdTransaction.Commit();


            ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
            // Get the changes between version 1 and 2 and assert correctness
            var changes = manager.GetChanges(1, 2);

            // We did 3 changes: add, delete and update.
            Assert.Equal(3, changes.Count());

            Assert.Contains(changes, c => c is ObjectCreation && ((ObjectCreation)c).NewState == forthObj);
            Assert.Contains(changes, c => c is ObjectDeletion && c.Id == secondObj.Id);
            Assert.Contains(changes, c => c is ObjectModification && ((ObjectModification)c).NewState == thirdObjUpdatedFirstTime && ((ObjectModification)c).PreviousState == thirdObj);


            ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
            // Get the changes between version 1 and 3 and assert correctness
            changes = manager.GetChanges(1, 3);

            // We did 5 changes: two add, two delete and one update.
            Assert.Equal(5, changes.Count());

            Assert.Contains(changes, c => c is ObjectCreation && ((ObjectCreation)c).NewState == forthObj);
            Assert.Contains(changes, c => c is ObjectCreation && ((ObjectCreation)c).NewState == fifthObj);
            Assert.Contains(changes, c => c is ObjectDeletion && c.Id == firstObj.Id);
            Assert.Contains(changes, c => c is ObjectDeletion && c.Id == secondObj.Id);
            Assert.Contains(changes, c => c is ObjectModification && ((ObjectModification)c).NewState == thirdObjUpdatedSecondTime && ((ObjectModification)c).PreviousState == thirdObj);


            ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
            // Get the changes between version 2 and 3 and assert correctness
            changes = manager.GetChanges(2, 3);

            // We did 3 changes: add, delete and update.
            Assert.Equal(3, changes.Count());

            Assert.Contains(changes, c => c is ObjectCreation && ((ObjectCreation)c).NewState == fifthObj);
            Assert.Contains(changes, c => c is ObjectDeletion && c.Id == firstObj.Id);
            Assert.Contains(changes, c => c is ObjectModification && ((ObjectModification)c).NewState == thirdObjUpdatedSecondTime && ((ObjectModification)c).PreviousState == thirdObjUpdatedFirstTime);
        }
Esempio n. 20
0
        public void TestConcurrentReaderOneWriter()
        {
            var manager = new InMemoryObjectManager();

            // Add initial object
            var transaction = manager.CreateTransaction();
            var objToAdd    = new TestObjectA(Guid.NewGuid(), "initial");

            transaction.Add(objToAdd);
            transaction.Commit();

            // Update name of object to inital 2
            transaction = manager.CreateTransaction();
            var objToUpdate = new TestObjectA(objToAdd.Id, "initial 2");

            transaction.Update(objToUpdate);
            transaction.Commit();


            // Thread that create a new transaction every 10 milisecond
            new Thread(() =>
            {
                for (int i = 0; i < 100; i++)
                {
                    var transaction = manager.CreateTransaction();
                    var objToUpdate = new TestObjectA(objToAdd.Id, "trans version " + transaction.Version.InternalVersionId);

                    transaction.Update(objToUpdate);
                    //Give some time to other threads to kick in
                    Thread.Sleep(10);

                    transaction.Commit();

                    Assert.Single(manager.GetObjects(transaction.Version.InternalVersionId));
                }
            }).Start();

            // Reading thread #1
            new Thread(() =>
            {
                for (int i = 0; i < 100; i++)
                {
                    Assert.Single(manager.GetObjects(1));
                    Assert.Equal("initial", ((TestObjectA)manager.GetObjects(1).First()).Name);
                    Thread.Sleep(10);
                }
            }).Start();

            // Reading thread #2
            new Thread(() =>
            {
                for (int i = 0; i < 100; i++)
                {
                    Assert.Single(manager.GetObjects(1));
                    Assert.Equal("initial", ((TestObjectA)manager.GetObjects(1).First()).Name);
                    Thread.Sleep(10);
                }
            }).Start();

            // Reading thread #3
            new Thread(() =>
            {
                for (int i = 0; i < 100; i++)
                {
                    Assert.Single(manager.GetObjects(2));
                    Assert.Equal("initial 2", ((TestObjectA)manager.GetObjects(2).First()).Name);
                    Thread.Sleep(10);
                }
            }).Start();

            Thread.Sleep(1500);
        }