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)); }
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); }
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"); }
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)); }
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"))); }
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")); }
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 }
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)); }
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)); }
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); }
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")); }
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)); }
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"); }
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; }
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); }
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); }